Boron SOM SDfat

Am I missing something here, I am having a really hard time getting the boron s o m SD card to work.
Does anybody have any sample code of this working?

Please :frowning:

I found that the SS pin was d5, And I’ve put all the jumpers in but I still get the various errors of the library such as unable to initialize or SD card not found.

I’ve been working on this most of the day and I’m about to pass out I’ll post sample code and what I’ve tried tomorrow but was really hoping I’m just missing some wonderful read me or example code for this.

Thanks

I’ve done this:

#include <SPI.h>

#include "Particle.h"
//#include <SD.h>
#include "SdFat.h"
SdFat SD;

#define SD_CS_PIN D8
File myFile;

void setup() {
    Cellular.off();
    // Open serial communications and wait for port to open:
    Serial.begin(9600);
    waitFor(Serial.isConnected, 15000);

    Serial.print("Initializing SD card...");

    if (!SD.begin(SD_CS_PIN)) {
        Serial.println("initialization failed!");
        return;
    }
    Serial.println("initialization done.");

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    myFile = SD.open("test.txt", FILE_WRITE);

    // if the file opened okay, write to it:
    if (myFile) {
        Serial.print("Writing to test.txt...");
        myFile.println("testing 1, 2, 3.");
        // close the file:
        myFile.close();
        Serial.println("done.");
    } else {
        // if the file didn't open, print an error:
        Serial.println("error opening test.txt");
    }

    // re-open the file for reading:
    myFile = SD.open("test.txt");
    if (myFile) {
        Serial.println("test.txt:");

        // read from the file until there's nothing else in it:
        while (myFile.available()) {
            Serial.write(myFile.read());
        }
        // close the file:
        myFile.close();
    } else {
        // if the file didn't open, print an error:
        Serial.println("error opening test.txt");
    }
}

void loop() {
    // nothing happens after setup
}

with the output of Initializing SD card...initialization failed!

UPDATE
I got it working using SdFat 1.0 :sleepy:

#define IMPLEMENT_SPI_PORT_SELECTION 1
// Quick hardware test for SPI card access.
//
// clang-format off
#include <SPI.h>


#include "Particle.h"
#include "SdFat.h"
#include "sdios.h"

// clang-format on
//
// Set DISABLE_CHIP_SELECT to disable a second SPI device.
// For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
// to 10 to disable the Ethernet controller.
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
const int8_t DISABLE_CHIP_SELECT = -1;
//
// Test with reduced SPI speed for breadboards.  SD_SCK_MHZ(4) will select
// the highest speed supported by the board that is not over 4 MHz.
// Change SPI_SPEED to SD_SCK_MHZ(50) for best performance.
#define SPI_SPEED SD_SCK_MHZ(4)
//------------------------------------------------------------------------------
// File system object.

SdFat sd((SPIClass*)&SPI1);

// Serial streams
ArduinoOutStream cout(Serial);

// input buffer for line
char cinBuf[40];
ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));

// SD card chip select
int chipSelect;

void cardOrSpeed() {
    cout << F("Try another SD card or reduce the SPI bus speed.\n");
    cout << F("Edit SPI_SPEED in this program to change it.\n");
}

void reformatMsg() {
    cout << F("Try reformatting the card.  For best results use\n");
    cout << F("the SdFormatter program in SdFat/examples or download\n");
    cout << F("and use SDFormatter from www.sdcard.org/downloads.\n");
}

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

    // Wait for USB Serial
    waitFor(Serial.isConnected, 15000);
    delay(1000);
    cout << F("\nSPI pins:\n");
    cout << F("MISO: ") << int(MISO) << endl;
    cout << F("MOSI: ") << int(MOSI) << endl;
    cout << F("SCK:  ") << int(SCK) << endl;
    cout << F("SS:   ") << int(SS) << endl;
    delay(1000);
    if (DISABLE_CHIP_SELECT < 0) {
        cout << F(
            "\nBe sure to edit DISABLE_CHIP_SELECT if you have\n"
            "a second SPI device.  For example, with the Ethernet\n"
            "shield, DISABLE_CHIP_SELECT should be set to 10\n"
            "to disable the Ethernet controller.\n");
    }
    cout << F(
        "\nSD chip select is the key hardware option.\n"
        "Common values are:\n"
        "Arduino Ethernet shield, pin 4\n"
        "Sparkfun SD shield, pin 8\n"
        "Adafruit SD shields and modules, pin 10\n");
}

bool firstTry = true;
void loop() {
    // Read any existing Serial data.
    do {
        delay(10);
    } while (Serial.available() && Serial.read() >= 0);

    if (!firstTry) {
        cout << F("\nRestarting\n");
        delay(10000);
    }
    firstTry = false;
    chipSelect = 5;
    // cout << F("\nEnter the chip select pin number: ");
    // while (!Serial.available()) {
    //     SysCall::yield();
    // }
    // cin.readline();
    // if (cin >> chipSelect) {
    //     cout << chipSelect << endl;
    // } else {
    //     cout << F("\nInvalid pin number\n");
    //     return;
    // }
    if (DISABLE_CHIP_SELECT < 0) {
        cout << F(
            "\nAssuming the SD is the only SPI device.\n"
            "Edit DISABLE_CHIP_SELECT to disable another device.\n");
    } else {
        cout << F("\nDisabling SPI device on pin ");
        cout << int(DISABLE_CHIP_SELECT) << endl;
        pinMode(DISABLE_CHIP_SELECT, OUTPUT);
        digitalWrite(DISABLE_CHIP_SELECT, HIGH);
    }
    if (!sd.begin(chipSelect, SPI_SPEED)) {
        if (sd.card()->errorCode()) {
            cout << F(
                "\nSD initialization failed.\n"
                "Do not reformat the card!\n"
                "Is the card correctly inserted?\n"
                "Is chipSelect set to the correct value?\n"
                "Does another SPI device need to be disabled?\n"
                "Is there a wiring/soldering problem?\n");
            cout << F("\nerrorCode: ") << hex << showbase;
            cout << int(sd.card()->errorCode());
            cout << F(", errorData: ") << int(sd.card()->errorData());
            cout << dec << noshowbase << endl;
            return;
        }
        if (sd.vol()->fatType() == 0) {
            cout << F("Can't find a valid FAT16/FAT32 partition.\n");
            reformatMsg();
            return;
        }
        cout << F("begin failed, can't determine error type\n");
        return;
    }
    cout << F("\nCard successfully initialized.\n");
    cout << endl;

    uint32_t size = sd.card()->cardSize();
    if (size == 0) {
        cout << F("Can't determine the card size.\n");
        cardOrSpeed();
        return;
    }
    uint32_t sizeMB = 0.000512 * size + 0.5;
    cout << F("Card size: ") << sizeMB;
    cout << F(" MB (MB = 1,000,000 bytes)\n");
    cout << endl;
    cout << F("Volume is FAT") << int(sd.vol()->fatType());
    cout << F(", Cluster size (bytes): ") << 512L * sd.vol()->blocksPerCluster();
    cout << endl
         << endl;

    cout << F("Files found (date time size name):\n");
    sd.ls(LS_R | LS_DATE | LS_SIZE);

    if ((sizeMB > 1100 && sd.vol()->blocksPerCluster() < 64) || (sizeMB < 2200 && sd.vol()->fatType() == 32)) {
        cout << F("\nThis card should be reformatted for best performance.\n");
        cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n");
        cout << F("Only cards larger than 2 GB should be formatted FAT32.\n");
        reformatMsg();
        return;
    }
    // Read any extra Serial data.
    do {
        delay(10);
    } while (Serial.available() && Serial.read() >= 0);
    cout << F("\nSuccess!  Type any character to restart.\n");
    while (!Serial.available()) {
        SysCall::yield();
    }
}

As it was able to let me select SPI1 to init the SD class, how are you supposed to use SPI1 for v2 of the library. I’ve torn through the source and everything :frowning:

Nevermind - follow the instructions here

for example:

//
// clang-format off

#include <SPI.h>
#include "Particle.h"

#include "SdFat.h"
#include "sdios.h"


// clang-format on
//
// Set DISABLE_CHIP_SELECT to disable a second SPI device.
// For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
// to 10 to disable the Ethernet controller.
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
const int8_t DISABLE_CHIP_SELECT = -1;

#define SD2_CONFIG SdSpiConfig(5, DEDICATED_SPI, SD_SCK_MHZ(18), &SPI1)

//
// Test with reduced SPI speed for breadboards.  SD_SCK_MHZ(4) will select
// the highest speed supported by the board that is not over 4 MHz.
// Change SPI_SPEED to SD_SCK_MHZ(50) for best performance.
#define SPI_SPEED SD_SCK_MHZ(4)
//------------------------------------------------------------------------------
// File system object.
SdFat sd;

// Serial streams
ArduinoOutStream cout(Serial);

// input buffer for line
char cinBuf[40];
ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));

// SD card chip select
int chipSelect;

void cardOrSpeed() {
    cout << F("Try another SD card or reduce the SPI bus speed.\n");
    cout << F("Edit SPI_SPEED in this program to change it.\n");
}

void reformatMsg() {
    cout << F("Try reformatting the card.  For best results use\n");
    cout << F("the SdFormatter program in SdFat/examples or download\n");
    cout << F("and use SDFormatter from www.sdcard.org/downloads.\n");
}

void read() {
    File myFile = sd.open("test.txt", FILE_READ);
    // if the file opened okay, write to it:
    if (myFile) {
        // read from the file until there's nothing else in it:
        while (myFile.available()) {
            Serial.write(myFile.read());
        }
        // close the file:
        myFile.close();
    } else {
        cout << F("Error opening test.txt");
    }
}

void write() {
    File myFile = sd.open("test.txt", FILE_WRITE);
    // if the file opened okay, write to it:
    if (myFile) {
        Serial.print("Writing to test.txt...");
        myFile.println("testing 1, 2, 3.");
        // close the file:
        myFile.close();
        Serial.println("done.");
    } else {
        cout << F("Error opening test.txt");
    }
}

void readWriteTest() {
    write();
    read();
}

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

    // Wait for USB Serial
    waitFor(Serial.isConnected, 15000);
    delay(1000);
    cout << F("\nSPI pins:\n");
    cout << F("MISO: ") << int(MISO) << endl;
    cout << F("MOSI: ") << int(MOSI) << endl;
    cout << F("SCK:  ") << int(SCK) << endl;
    cout << F("SS:   ") << int(SS) << endl;

    if (DISABLE_CHIP_SELECT < 0) {
        cout << F(
            "\nBe sure to edit DISABLE_CHIP_SELECT if you have\n"
            "a second SPI device.  For example, with the Ethernet\n"
            "shield, DISABLE_CHIP_SELECT should be set to 10\n"
            "to disable the Ethernet controller.\n");
    }
    cout << F(
        "\nSD chip select is the key hardware option.\n"
        "Common values are:\n"
        "Arduino Ethernet shield, pin 4\n"
        "Sparkfun SD shield, pin 8\n"
        "Adafruit SD shields and modules, pin 10\n");
}

bool firstTry = true;
void loop() {
    // Read any existing Serial data.
    do {
        delay(10);
    } while (Serial.available() && Serial.read() >= 0);

    if (!firstTry) {
        cout << F("\nRestarting\n");
        delay(10000);
    }
    firstTry = false;
    chipSelect = 5;

    if (DISABLE_CHIP_SELECT < 0) {
        cout << F(
            "\nAssuming the SD is the only SPI device.\n"
            "Edit DISABLE_CHIP_SELECT to disable another device.\n");
    } else {
        cout << F("\nDisabling SPI device on pin ");
        cout << int(DISABLE_CHIP_SELECT) << endl;
        pinMode(DISABLE_CHIP_SELECT, OUTPUT);
        digitalWrite(DISABLE_CHIP_SELECT, HIGH);
    }
    if (!sd.begin(SD2_CONFIG)) {
        if (sd.card()->errorCode()) {
            cout << F(
                "\nSD initialization failed.\n"
                "Do not reformat the card!\n"
                "Is the card correctly inserted?\n"
                "Is chipSelect set to the correct value?\n"
                "Does another SPI device need to be disabled?\n"
                "Is there a wiring/soldering problem?\n");
            cout << F("\nerrorCode: ") << hex << showbase;
            cout << int(sd.card()->errorCode());
            cout << F(", errorData: ") << int(sd.card()->errorData());
            cout << dec << noshowbase << endl;
            return;
        }
        if (sd.vol()->fatType() == 0) {
            cout << F("Can't find a valid FAT16/FAT32 partition.\n");
            reformatMsg();
            return;
        }
        cout << F("begin failed, can't determine error type\n");
        return;
    }
    cout << F("\nCard successfully initialized.\n");
    cout << endl;
    readWriteTest();

    uint32_t size = sd.card()->cardSize();
    if (size == 0) {
        cout << F("Can't determine the card size.\n");
        cardOrSpeed();
        return;
    }
    uint32_t sizeMB = 0.000512 * size + 0.5;
    cout << F("Card size: ") << sizeMB;
    cout << F(" MB (MB = 1,000,000 bytes)\n");
    cout << endl;
    cout << F("Volume is FAT") << int(sd.vol()->fatType());
    cout << F(", Cluster size (bytes): ") << 512L * sd.vol()->blocksPerCluster();
    cout << endl
         << endl;

    cout << F("Files found (date time size name):\n");
    sd.ls(LS_R | LS_DATE | LS_SIZE);

    if ((sizeMB > 1100 && sd.vol()->blocksPerCluster() < 64) || (sizeMB < 2200 && sd.vol()->fatType() == 32)) {
        cout << F("\nThis card should be reformatted for best performance.\n");
        cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n");
        cout << F("Only cards larger than 2 GB should be formatted FAT32.\n");
        reformatMsg();
        return;
    }
    // Read any extra Serial data.
    do {
        delay(10);
    } while (Serial.available() && Serial.read() >= 0);
    cout << F("\nSuccess!  Type any character to restart.\n");
    while (!Serial.available()) {
        SysCall::yield();
    }
}