SdFat with Teensy 3.6: error: write MBR - SD error: 23,200002

Status
Not open for further replies.

mcc

Well-known member
Hi,

Currently I am trying to get the internal SDcard slot working on my Teensy 3.6.
From MickMake reviews of the Teensy 3.5/3.6 on YouTube I got the information
that SdFat by Bill Greiman is the one I should use.

I did that and it completly failed (card not recognized). In the forum I found
a post, that I have to enable SDIO and tried to format my 8GB card ... which
at least accepted the existence of a sdcard in the slot (HURRAY! :) ) ... but
the formatting process ended with

Code:
17:43:33.361 -> ..........................
17:43:34.390 -> All data set to 0x88
17:43:34.390 -> Erase done
17:43:34.390 -> 
17:43:34.390 -> Formatting
17:43:34.390 -> Blocks/Cluster: 64
17:43:34.390 -> FAT32
17:43:34.390 -> error: write MBR
17:43:34.390 -> SD error: 23,200002

The according code, which creates this error:
Code:
/*
 * This program will format an SD or SDHC card.
 * Warning all data will be deleted!
 *
 * For SD/SDHC cards larger than 64 MB this
 * program attempts to match the format
 * generated by SDFormatter available here:
 *
 * http://www.sdcard.org/consumers/formatter/
 *
 * For smaller cards this program uses FAT16
 * and SDFormatter uses FAT12.
 */

// Set USE_SDIO to zero for SPI card access. 
#define USE_SDIO 1
//
// Change the value of chipSelect if your hardware does
// not use the default value, SS.  Common values are:
// Arduino Ethernet shield: pin 4
// Sparkfun SD shield: pin 8
// Adafruit SD shields and modules: pin 10
const uint8_t chipSelect = SS;

// Initialize at highest supported speed not over 50 MHz.
// Reduce max speed if errors occur.
#define SPI_SPEED SD_SCK_MHZ(50)

// Print extra info for debug if DEBUG_PRINT is nonzero
#define DEBUG_PRINT 0
#include <SPI.h>
#include "SdFat.h"
#include "sdios.h"
#if DEBUG_PRINT
#include "FreeStack.h"
#endif  // DEBUG_PRINT

// Serial output stream
ArduinoOutStream cout(Serial);

#if USE_SDIO
// Use faster SdioCardEX
SdioCardEX card;
// SdioCard card;
#else  // USE_SDIO
Sd2Card card;
#endif  // USE_SDIO
 
uint32_t cardSizeBlocks;
uint32_t cardCapacityMB;

// cache for SD block
cache_t cache;

// MBR information
uint8_t partType;
uint32_t relSector;
uint32_t partSize;

// Fake disk geometry
uint8_t numberOfHeads;
uint8_t sectorsPerTrack;

// FAT parameters
uint16_t reservedSectors;
uint8_t sectorsPerCluster;
uint32_t fatStart;
uint32_t fatSize;
uint32_t dataStart;

// constants for file system structure
uint16_t const BU16 = 128;
uint16_t const BU32 = 8192;

//  strings needed in file system structures
char noName[] = "NO NAME    ";
char fat16str[] = "FAT16   ";
char fat32str[] = "FAT32   ";
//------------------------------------------------------------------------------
#define sdError(msg) {cout << F("error: ") << F(msg) << endl; sdErrorHalt();}
//------------------------------------------------------------------------------
void sdErrorHalt() {
  if (card.errorCode()) {
    cout << F("SD error: ") << hex << int(card.errorCode());
    cout << ',' << int(card.errorData()) << dec << endl;
  }
  SysCall::halt();
}
//------------------------------------------------------------------------------
#if DEBUG_PRINT
void debugPrint() {
  cout << F("FreeStack: ") << FreeStack() << endl;
  cout << F("partStart: ") << relSector << endl;
  cout << F("partSize: ") << partSize << endl;
  cout << F("reserved: ") << reservedSectors << endl;
  cout << F("fatStart: ") << fatStart << endl;
  cout << F("fatSize: ") << fatSize << endl;
  cout << F("dataStart: ") << dataStart << endl;
  cout << F("clusterCount: ");
  cout << ((relSector + partSize - dataStart)/sectorsPerCluster) << endl;
  cout << endl;
  cout << F("Heads: ") << int(numberOfHeads) << endl;
  cout << F("Sectors: ") << int(sectorsPerTrack) << endl;
  cout << F("Cylinders: ");
  cout << cardSizeBlocks/(numberOfHeads*sectorsPerTrack) << endl;
}
#endif  // DEBUG_PRINT
//------------------------------------------------------------------------------
// write cached block to the card
uint8_t writeCache(uint32_t lbn) {
  return card.writeBlock(lbn, cache.data);
}
//------------------------------------------------------------------------------
// initialize appropriate sizes for SD capacity
void initSizes() {
  if (cardCapacityMB <= 6) {
    sdError("Card is too small.");
  } else if (cardCapacityMB <= 16) {
    sectorsPerCluster = 2;
  } else if (cardCapacityMB <= 32) {
    sectorsPerCluster = 4;
  } else if (cardCapacityMB <= 64) {
    sectorsPerCluster = 8;
  } else if (cardCapacityMB <= 128) {
    sectorsPerCluster = 16;
  } else if (cardCapacityMB <= 1024) {
    sectorsPerCluster = 32;
  } else if (cardCapacityMB <= 32768) {
    sectorsPerCluster = 64;
  } else {
    // SDXC cards
    sectorsPerCluster = 128;
  }

  cout << F("Blocks/Cluster: ") << int(sectorsPerCluster) << endl;
  // set fake disk geometry
  sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63;

  if (cardCapacityMB <= 16) {
    numberOfHeads = 2;
  } else if (cardCapacityMB <= 32) {
    numberOfHeads = 4;
  } else if (cardCapacityMB <= 128) {
    numberOfHeads = 8;
  } else if (cardCapacityMB <= 504) {
    numberOfHeads = 16;
  } else if (cardCapacityMB <= 1008) {
    numberOfHeads = 32;
  } else if (cardCapacityMB <= 2016) {
    numberOfHeads = 64;
  } else if (cardCapacityMB <= 4032) {
    numberOfHeads = 128;
  } else {
    numberOfHeads = 255;
  }
}
//------------------------------------------------------------------------------
// zero cache and optionally set the sector signature
void clearCache(uint8_t addSig) {
  memset(&cache, 0, sizeof(cache));
  if (addSig) {
    cache.mbr.mbrSig0 = BOOTSIG0;
    cache.mbr.mbrSig1 = BOOTSIG1;
  }
}
//------------------------------------------------------------------------------
// zero FAT and root dir area on SD
void clearFatDir(uint32_t bgn, uint32_t count) {
  clearCache(false);
#if USE_SDIO
  for (uint32_t i = 0; i < count; i++) {
    if (!card.writeBlock(bgn + i, cache.data)) {
       sdError("Clear FAT/DIR writeBlock failed");
    }     
    if ((i & 0XFF) == 0) {
      cout << '.';
    }    
  }
#else  // USE_SDIO
  if (!card.writeStart(bgn, count)) {
    sdError("Clear FAT/DIR writeStart failed");
  }
  for (uint32_t i = 0; i < count; i++) {
    if ((i & 0XFF) == 0) {
      cout << '.';
    }
    if (!card.writeData(cache.data)) {
      sdError("Clear FAT/DIR writeData failed");
    }
  }
  if (!card.writeStop()) {
    sdError("Clear FAT/DIR writeStop failed");
  }
#endif  // USE_SDIO
  cout << endl;
}
//------------------------------------------------------------------------------
// return cylinder number for a logical block number
uint16_t lbnToCylinder(uint32_t lbn) {
  return lbn / (numberOfHeads * sectorsPerTrack);
}
//------------------------------------------------------------------------------
// return head number for a logical block number
uint8_t lbnToHead(uint32_t lbn) {
  return (lbn % (numberOfHeads * sectorsPerTrack)) / sectorsPerTrack;
}
//------------------------------------------------------------------------------
// return sector number for a logical block number
uint8_t lbnToSector(uint32_t lbn) {
  return (lbn % sectorsPerTrack) + 1;
}
//------------------------------------------------------------------------------
// format and write the Master Boot Record
void writeMbr() {
  clearCache(true);
  part_t* p = cache.mbr.part;
  p->boot = 0;
  uint16_t c = lbnToCylinder(relSector);
  if (c > 1023) {
    sdError("MBR CHS");
  }
  p->beginCylinderHigh = c >> 8;
  p->beginCylinderLow = c & 0XFF;
  p->beginHead = lbnToHead(relSector);
  p->beginSector = lbnToSector(relSector);
  p->type = partType;
  uint32_t endLbn = relSector + partSize - 1;
  c = lbnToCylinder(endLbn);
  if (c <= 1023) {
    p->endCylinderHigh = c >> 8;
    p->endCylinderLow = c & 0XFF;
    p->endHead = lbnToHead(endLbn);
    p->endSector = lbnToSector(endLbn);
  } else {
    // Too big flag, c = 1023, h = 254, s = 63
    p->endCylinderHigh = 3;
    p->endCylinderLow = 255;
    p->endHead = 254;
    p->endSector = 63;
  }
  p->firstSector = relSector;
  p->totalSectors = partSize;
  if (!writeCache(0)) {
    sdError("write MBR");
  }
}
//------------------------------------------------------------------------------
// generate serial number from card size and micros since boot
uint32_t volSerialNumber() {
  return (cardSizeBlocks << 8) + micros();
}
//------------------------------------------------------------------------------
// format the SD as FAT16
void makeFat16() {
  uint32_t nc;
  for (dataStart = 2 * BU16;; dataStart += BU16) {
    nc = (cardSizeBlocks - dataStart)/sectorsPerCluster;
    fatSize = (nc + 2 + 255)/256;
    uint32_t r = BU16 + 1 + 2 * fatSize + 32;
    if (dataStart < r) {
      continue;
    }
    relSector = dataStart - r + BU16;
    break;
  }
  // check valid cluster count for FAT16 volume
  if (nc < 4085 || nc >= 65525) {
    sdError("Bad cluster count");
  }
  reservedSectors = 1;
  fatStart = relSector + reservedSectors;
  partSize = nc * sectorsPerCluster + 2 * fatSize + reservedSectors + 32;
  if (partSize < 32680) {
    partType = 0X01;
  } else if (partSize < 65536) {
    partType = 0X04;
  } else {
    partType = 0X06;
  }
  // write MBR
  writeMbr();
  clearCache(true);
  fat_boot_t* pb = &cache.fbs;
  pb->jump[0] = 0XEB;
  pb->jump[1] = 0X00;
  pb->jump[2] = 0X90;
  for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
    pb->oemId[i] = ' ';
  }
  pb->bytesPerSector = 512;
  pb->sectorsPerCluster = sectorsPerCluster;
  pb->reservedSectorCount = reservedSectors;
  pb->fatCount = 2;
  pb->rootDirEntryCount = 512;
  pb->mediaType = 0XF8;
  pb->sectorsPerFat16 = fatSize;
  pb->sectorsPerTrack = sectorsPerTrack;
  pb->headCount = numberOfHeads;
  pb->hidddenSectors = relSector;
  pb->totalSectors32 = partSize;
  pb->driveNumber = 0X80;
  pb->bootSignature = EXTENDED_BOOT_SIG;
  pb->volumeSerialNumber = volSerialNumber();
  memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
  memcpy(pb->fileSystemType, fat16str, sizeof(pb->fileSystemType));
  // write partition boot sector
  if (!writeCache(relSector)) {
    sdError("FAT16 write PBS failed");
  }
  // clear FAT and root directory
  clearFatDir(fatStart, dataStart - fatStart);
  clearCache(false);
  cache.fat16[0] = 0XFFF8;
  cache.fat16[1] = 0XFFFF;
  // write first block of FAT and backup for reserved clusters
  if (!writeCache(fatStart)
      || !writeCache(fatStart + fatSize)) {
    sdError("FAT16 reserve failed");
  }
}
//------------------------------------------------------------------------------
// format the SD as FAT32
void makeFat32() {
  uint32_t nc;
  relSector = BU32;
  for (dataStart = 2 * BU32;; dataStart += BU32) {
    nc = (cardSizeBlocks - dataStart)/sectorsPerCluster;
    fatSize = (nc + 2 + 127)/128;
    uint32_t r = relSector + 9 + 2 * fatSize;
    if (dataStart >= r) {
      break;
    }
  }
  // error if too few clusters in FAT32 volume
  if (nc < 65525) {
    sdError("Bad cluster count");
  }
  reservedSectors = dataStart - relSector - 2 * fatSize;
  fatStart = relSector + reservedSectors;
  partSize = nc * sectorsPerCluster + dataStart - relSector;
  // type depends on address of end sector
  // max CHS has lbn = 16450560 = 1024*255*63
  if ((relSector + partSize) <= 16450560) {
    // FAT32
    partType = 0X0B;
  } else {
    // FAT32 with INT 13
    partType = 0X0C;
  }
  writeMbr();
  clearCache(true);

  fat32_boot_t* pb = &cache.fbs32;
  pb->jump[0] = 0XEB;
  pb->jump[1] = 0X00;
  pb->jump[2] = 0X90;
  for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
    pb->oemId[i] = ' ';
  }
  pb->bytesPerSector = 512;
  pb->sectorsPerCluster = sectorsPerCluster;
  pb->reservedSectorCount = reservedSectors;
  pb->fatCount = 2;
  pb->mediaType = 0XF8;
  pb->sectorsPerTrack = sectorsPerTrack;
  pb->headCount = numberOfHeads;
  pb->hidddenSectors = relSector;
  pb->totalSectors32 = partSize;
  pb->sectorsPerFat32 = fatSize;
  pb->fat32RootCluster = 2;
  pb->fat32FSInfo = 1;
  pb->fat32BackBootBlock = 6;
  pb->driveNumber = 0X80;
  pb->bootSignature = EXTENDED_BOOT_SIG;
  pb->volumeSerialNumber = volSerialNumber();
  memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
  memcpy(pb->fileSystemType, fat32str, sizeof(pb->fileSystemType));
  // write partition boot sector and backup
  if (!writeCache(relSector)
      || !writeCache(relSector + 6)) {
    sdError("FAT32 write PBS failed");
  }
  clearCache(true);
  // write extra boot area and backup
  if (!writeCache(relSector + 2)
      || !writeCache(relSector + 8)) {
    sdError("FAT32 PBS ext failed");
  }
  fat32_fsinfo_t* pf = &cache.fsinfo;
  pf->leadSignature = FSINFO_LEAD_SIG;
  pf->structSignature = FSINFO_STRUCT_SIG;
  pf->freeCount = 0XFFFFFFFF;
  pf->nextFree = 0XFFFFFFFF;
  // write FSINFO sector and backup
  if (!writeCache(relSector + 1)
      || !writeCache(relSector + 7)) {
    sdError("FAT32 FSINFO failed");
  }
  clearFatDir(fatStart, 2 * fatSize + sectorsPerCluster);
  clearCache(false);
  cache.fat32[0] = 0x0FFFFFF8;
  cache.fat32[1] = 0x0FFFFFFF;
  cache.fat32[2] = 0x0FFFFFFF;
  // write first block of FAT and backup for reserved clusters
  if (!writeCache(fatStart)
      || !writeCache(fatStart + fatSize)) {
    sdError("FAT32 reserve failed");
  }
}
//------------------------------------------------------------------------------
// flash erase all data
uint32_t const ERASE_SIZE = 262144L;
void eraseCard() {
  cout << endl << F("Erasing\n");
  uint32_t firstBlock = 0;
  uint32_t lastBlock;
  uint16_t n = 0;

  do {
    lastBlock = firstBlock + ERASE_SIZE - 1;
    if (lastBlock >= cardSizeBlocks) {
      lastBlock = cardSizeBlocks - 1;
    }
    if (!card.erase(firstBlock, lastBlock)) {
      sdError("erase failed");
    }
    cout << '.';
    if ((n++)%32 == 31) {
      cout << endl;
    }
    firstBlock += ERASE_SIZE;
  } while (firstBlock < cardSizeBlocks);
  cout << endl;

  if (!card.readBlock(0, cache.data)) {
    sdError("readBlock");
  }
  cout << hex << showbase << setfill('0') << internal;
  cout << F("All data set to ") << setw(4) << int(cache.data[0]) << endl;
  cout << dec << noshowbase << setfill(' ') << right;
  cout << F("Erase done\n");
}
//------------------------------------------------------------------------------
void formatCard() {
  cout << endl;
  cout << F("Formatting\n");
  initSizes();
  if (card.type() != SD_CARD_TYPE_SDHC) {
    cout << F("FAT16\n");
    makeFat16();
  } else {
    cout << F("FAT32\n");
    makeFat32();
  }
#if DEBUG_PRINT
  debugPrint();
#endif  // DEBUG_PRINT
  cout << F("Format done\n");
}
//------------------------------------------------------------------------------
void setup() {
  char c;
  Serial.begin(9600);
  // Wait for USB Serial 
  while (!Serial) {
    SysCall::yield();
  }
  cout << F("Type any character to start\n");
  while (!Serial.available()) {
    SysCall::yield();
  }
  // Discard any extra characters.
  do {
    delay(10);
  } while (Serial.available() && Serial.read() >= 0);
  cout << F(
         "\n"
         "This program can erase and/or format SD/SDHC cards.\n"
         "\n"
         "Erase uses the card's fast flash erase command.\n"
         "Flash erase sets all data to 0X00 for most cards\n"
         "and 0XFF for a few vendor's cards.\n"
         "\n"
         "Cards larger than 2 GB will be formatted FAT32 and\n"
         "smaller cards will be formatted FAT16.\n"
         "\n"
         "Warning, all data on the card will be erased.\n"
         "Enter 'Y' to continue: ");
  while (!Serial.available()) {
    SysCall::yield();
  }

  c = Serial.read();
  cout << c << endl;
  if (c != 'Y') {
    cout << F("Quiting, you did not enter 'Y'.\n");
    return;
  }
  // Read any existing Serial data.
  do {
    delay(10);
  } while (Serial.available() && Serial.read() >= 0);

  cout << F(
         "\n"
         "Options are:\n"
         "E - erase the card and skip formatting.\n"
         "F - erase and then format the card. (recommended)\n"
         "Q - quick format the card without erase.\n"
         "\n"
         "Enter option: ");

  while (!Serial.available()) {
    SysCall::yield();
  }
  c = Serial.read();
  cout << c << endl;
  if (!strchr("EFQ", c)) {
    cout << F("Quiting, invalid option entered.") << endl;
    return;
  }
#if USE_SDIO
  if (!card.begin()) {
    sdError("card.begin failed");  
  }
#else  // USE_SDIO
  if (!card.begin(chipSelect, SPI_SPEED)) {
    cout << F(
           "\nSD initialization failure!\n"
           "Is the SD card inserted correctly?\n"
           "Is chip select correct at the top of this program?\n");
    sdError("card.begin failed");
  }
#endif  
  cardSizeBlocks = card.cardSize();
  if (cardSizeBlocks == 0) {
    sdError("cardSize");
  }
  cardCapacityMB = (cardSizeBlocks + 2047)/2048;

  cout << F("Card Size: ") << setprecision(0) << 1.048576*cardCapacityMB;
  cout << F(" MB, (MB = 1,000,000 bytes)") << endl;

  if (c == 'E' || c == 'F') {
    eraseCard();
  }
  if (c == 'F' || c == 'Q') {
    formatCard();
  }
}
//------------------------------------------------------------------------------
void loop() {}

From the thread, which mentioned that SDIO needs to be enabled, I read that there
was another library currently in beta (or being patched or so...) . Since the post
some time has gone...:

What is the library of choice for reading, formatting and writing sdcards with the Teensy 3.6,
which work together with the audio lib?

Thanks a lot for any help in advance!
Cheers!
Meino
 
Hi,

I tried another way to access the sdcard:
I used a SDcard, which I freshly formatted on my Linux like so:
Disk /dev/sdc: 7.5 GiB, 7994343424 bytes, 15613952 sectors
Disk model: STORAGE DEVICE
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device Boot Start End Sectors Size Id Type
/dev/sdc1 8192 15613951 15605760 7.5G b W95 FAT32

To put a filesystem on it I used
mkfs.fat -F32 /dev/sdc1
and copied all four files of the provided sound examples onto the sdcard,
synced, unmounted and remount the sdcard. The file listing:
total 62512
-rwxr-xr-x 1 root root 16787550 2019-05-12 19:48 SDTEST1.WAV
-rwxr-xr-x 1 root root 16425698 2019-05-12 19:48 SDTEST2.WAV
-rwxr-xr-x 1 root root 13617358 2019-05-12 19:48 SDTEST3.WAV
-rwxr-xr-x 1 root root 17173152 2019-05-12 19:48 SDTEST4.WAV

From File->Examples->Audio I compiled the "WavPlayerUSB".
I activated
// Use these with the Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN BUILTIN_SDCARD
#define SDCARD_MOSI_PIN 11 // not actually used
#define SDCARD_SCK_PIN 13 // not actually used

Unfortunately "BUILTIN_SDCARD" was not defined and I changed the code this way:
// Use these with the Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN SS
#define SDCARD_MOSI_PIN 11 // not actually used
#define SDCARD_SCK_PIN 13 // not actually used

After that I compiled the code, set USB to audio, flashed the code and on the
serial monitor I got
20:20:46.016 -> Unable to access the SD card
20:20:46.514 -> Unable to access the SD card
20:20:47.011 -> Unable to access the SD card
20:20:47.509 -> Unable to access the SD card
20:20:48.007 -> Unable to access the SD card
20:20:48.505 -> Unable to access the SD card
20:20:49.002 -> Unable to access the SD card
20:20:49.500 -> Unable to access the SD card
20:20:49.998 -> Unable to access the SD card
20:20:50.496 -> Unable to access the SD card
20:20:50.993 -> Unable to access the SD card
20:20:51.491 -> Unable to access the SD card
20:20:51.989 -> Unable to access the SD card
20:20:52.487 -> Unable to access the SD card
20:20:52.984 -> Unable to access the SD card
20:20:53.515 -> Unable to access the SD card
20:20:54.013 -> Unable to access the SD card
20:20:54.510 -> Unable to access the SD card
20:20:55.008 -> Unable to access the SD card
20:20:55.506 -> Unable to access the SD card
20:20:56.003 -> Unable to access the SD card
20:20:56.502 -> Unable to access the SD card
20:20:56.999 -> Unable to access the SD card
20:20:57.496 -> Unable to access the SD card
20:20:57.994 -> Unable to access the SD card
20:20:58.492 -> Unable to access the SD card
20:20:58.990 -> Unable to access the SD card
20:20:59.487 -> Unable to access the SD card
20:20:59.985 -> Unable to access the SD card
20:21:00.516 -> Unable to access the SD card
20:21:01.013 -> Unable to access the SD card
20:21:01.511 -> Unable to access the SD card
20:21:02.008 -> Unable to access the SD card
20:21:02.506 -> Unable to access the SD card
20:21:03.004 -> Unable to access the SD card

The sdcard is a different one as I used in my first experiment.

The complete code I used is:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav           playWav1;
AudioOutputUSB           audioOutput; // must set Tools > USB Type to Audio
AudioOutputAnalog        dac;
AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);
AudioConnection          patchCord3(playWav1, 0, dac, 0);

// Use these with the Teensy Audio Shield
//#define SDCARD_CS_PIN    10
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14

// Use these with the Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN    SS
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13

void setup() {
  Serial.begin(9600);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(20);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}

void playFile(const char *filename)
{
  playWav1.play(filename);
  // A brief delay for the library read WAV info
  delay(5);
  // Simply wait for the file to finish playing.
  while (playWav1.isPlaying()) {
  }
}

void loop() {
  Serial.println( "Now playing SDTEST1.WAV" );
  playFile("SDTEST1.WAV");  // filenames are always uppercase 8.3 format
  delay(500);
  Serial.println( "Now playing SDTEST2.WAV" );
  playFile("SDTEST2.WAV");
  delay(500);
  Serial.println( "Now playing SDTEST3.WAV" );
  playFile("SDTEST3.WAV");
  delay(500);
  Serial.println( "Now playing SDTEST4.WAV" );
  playFile("SDTEST4.WAV");
  delay(1500);
}

// A known problem occurs on Macintosh computers, where the Mac's driver
// does not seem to be able to adapt and transmit horribly distorted
// audio to Teensy after a matter of minutes.  An imperfect workaround
// can be enabled by editing usb_audio.cpp.  Find and uncomment
// "#define MACOSX_ADAPTIVE_LIMIT".  More detailed info is available here:
// https://forum.pjrc.com/threads/34855-Distorted-audio-when-using-USB-input-on-Teensy-3-1?p=110392&viewfull=1#post110392

Thanks in advance for any help in solving this sdcard-issue!
Cheers!
Meino
 
The use the build-in card you either use "BUILTIN_SDCARD" which IS defined if you use the correct SD library
If you insist to use the SPI interface then you must do a little bit more:
switch SPI to SPI1 and configure proper MISO,MOSI,CLK,CS
(IIRC in the huge "K66 Beta Test" thread (3 Years ago) there is info on how to do that)
 
Hi,

what is the correct library to use?

This is a example program, which came with teensyduino.

Cheers!
Meino
 
Status
Not open for further replies.
Back
Top