diff --git a/.github/workflows/CI_compile_examples.yml b/.github/workflows/CI_compile_examples.yml index 6383c113..c0738fb2 100644 --- a/.github/workflows/CI_compile_examples.yml +++ b/.github/workflows/CI_compile_examples.yml @@ -119,6 +119,7 @@ jobs: - source-url: https://github.com/ambiot/ambd_arduino/raw/dev/Arduino_zip_libraries/AmebaMotors.zip - source-url: https://github.com/ambiot/ambd_arduino/raw/dev/Arduino_zip_libraries/AmebaEink.zip - name: "SparkFun ADXL313 Arduino Library" + - name: "SdFat - Adafruit Fork" verbose: false enable-deltas-report: false if: ${{ github.ref == 'refs/heads/dev' || github.event.pull_request.base.ref == 'dev'}} @@ -141,6 +142,7 @@ jobs: - source-url: https://github.com/ambiot/ambd_arduino/raw/master/Arduino_zip_libraries/AmebaMotors.zip - source-url: https://github.com/ambiot/ambd_arduino/raw/master/Arduino_zip_libraries/AmebaEink.zip - name: "SparkFun ADXL313 Arduino Library" + - name: "SdFat - Adafruit Fork" verbose: false enable-deltas-report: false if: ${{ github.ref == 'refs/heads/master' || github.event.pull_request.base.ref == 'master' }} diff --git a/Arduino_package/hardware/libraries/SPI/examples/BW16_SD_Card_SPI/BW16_SD_Card_SPI.ino b/Arduino_package/hardware/libraries/SPI/examples/BW16_SD_Card_SPI/BW16_SD_Card_SPI.ino new file mode 100644 index 00000000..10105d72 --- /dev/null +++ b/Arduino_package/hardware/libraries/SPI/examples/BW16_SD_Card_SPI/BW16_SD_Card_SPI.ino @@ -0,0 +1,231 @@ +/* + BW16 SPI Bus SD Card example: + This program attempts to initialize an SD card and analyze its structure. + + It needs the Adafruit fork of the SdFat Library: https://github.com/adafruit/SdFat/ + + This example code is in the public domain. + + This modified example credits to https://github.com/designer2k2 + */ + +#ifdef BOARD_AITHINKER_BW16 + +#include "SdFat.h" +#include "sdios.h" + +#define SD_CONFIG SdSpiConfig(SS, DEDICATED_SPI, SD_SCK_MHZ(16)) + +//------------------------------------------------------------------------------ +SdFs sd; +cid_t cid; +csd_t csd; +scr_t scr; +uint8_t cmd6Data[64]; +uint32_t eraseSize; +uint32_t ocr; +static ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void cidDmp() { + cout << F("\nManufacturer ID: "); + cout << uppercase << showbase << hex << int(cid.mid) << dec << endl; + cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl; + cout << F("Product: "); + for (uint8_t i = 0; i < 5; i++) { + cout << cid.pnm[i]; + } + cout << F("\nRevision: ") << cid.prvN() << '.' << cid.prvM() << endl; + cout << F("Serial number: ") << hex << cid.psn() << dec << endl; + cout << F("Manufacturing date: "); + cout << cid.mdtMonth() << '/' << cid.mdtYear() << endl; + cout << endl; +} +//------------------------------------------------------------------------------ +void clearSerialInput() { + uint32_t m = micros(); + do { + if (Serial.read() >= 0) { + m = micros(); + } + } while (micros() - m < 10000); +} +//------------------------------------------------------------------------------ +void csdDmp() { + eraseSize = csd.eraseSize(); + cout << F("cardSize: ") << 0.000512 * csd.capacity(); + cout << F(" MB (MB = 1,000,000 bytes)\n"); + + cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n"); + cout << F("eraseSingleBlock: "); + if (csd.eraseSingleBlock()) { + cout << F("true\n"); + } else { + cout << F("false\n"); + } + cout << F("dataAfterErase: "); + if (scr.dataAfterErase()) { + cout << F("ones\n"); + } else { + cout << F("zeros\n"); + } +} +//------------------------------------------------------------------------------ +void errorPrint() { + if (sd.sdErrorCode()) { + cout << F("SD errorCode: ") << hex << showbase; + printSdErrorSymbol(&Serial, sd.sdErrorCode()); + cout << F(" = ") << int(sd.sdErrorCode()) << endl; + cout << F("SD errorData = ") << int(sd.sdErrorData()) << dec << endl; + } +} +//------------------------------------------------------------------------------ +bool mbrDmp() { + MbrSector_t mbr; + bool valid = true; + if (!sd.card()->readSector(0, (uint8_t *)&mbr)) { + cout << F("\nread MBR failed.\n"); + errorPrint(); + return false; + } + cout << F("\nSD Partition Table\n"); + cout << F("part,boot,bgnCHS[3],type,endCHS[3],start,length\n"); + for (uint8_t ip = 1; ip < 5; ip++) { + MbrPart_t *pt = &mbr.part[ip - 1]; + if ((pt->boot != 0 && pt->boot != 0X80) || getLe32(pt->relativeSectors) > csd.capacity()) { + valid = false; + } + cout << int(ip) << ',' << uppercase << showbase << hex; + cout << int(pt->boot) << ','; + for (int i = 0; i < 3; i++) { + cout << int(pt->beginCHS[i]) << ','; + } + cout << int(pt->type) << ','; + for (int i = 0; i < 3; i++) { + cout << int(pt->endCHS[i]) << ','; + } + cout << dec << getLe32(pt->relativeSectors) << ','; + cout << getLe32(pt->totalSectors) << endl; + } + if (!valid) { + cout << F("\nMBR not valid, assuming Super Floppy format.\n"); + } + return true; +} +//------------------------------------------------------------------------------ +void dmpVol() { + cout << F("\nScanning FAT, please wait.\n"); + int32_t freeClusterCount = sd.freeClusterCount(); + if (sd.fatType() <= 32) { + cout << F("\nVolume is FAT") << int(sd.fatType()) << endl; + } else { + cout << F("\nVolume is exFAT\n"); + } + cout << F("sectorsPerCluster: ") << sd.sectorsPerCluster() << endl; + cout << F("fatStartSector: ") << sd.fatStartSector() << endl; + cout << F("dataStartSector: ") << sd.dataStartSector() << endl; + cout << F("clusterCount: ") << sd.clusterCount() << endl; + cout << F("freeClusterCount: "); + if (freeClusterCount >= 0) { + cout << freeClusterCount << endl; + } else { + cout << F("failed\n"); + errorPrint(); + } +} +//------------------------------------------------------------------------------ +void printCardType() { + + cout << F("\nCard type: "); + + switch (sd.card()->type()) { + case SD_CARD_TYPE_SD1: + cout << F("SD1\n"); + break; + + case SD_CARD_TYPE_SD2: + cout << F("SD2\n"); + break; + + case SD_CARD_TYPE_SDHC: + if (csd.capacity() < 70000000) { + cout << F("SDHC\n"); + } else { + cout << F("SDXC\n"); + } + break; + + default: + cout << F("Unknown\n"); + } +} +//----------------------------------------------------------------------------- +void setup() { + Serial.begin(9600); + // Wait for USB Serial + while (!Serial) { + yield(); + } + cout << F("SdFat version: ") << SD_FAT_VERSION_STR << endl; +} +//------------------------------------------------------------------------------ +void loop() { + // Read any existing Serial data. + clearSerialInput(); + + // F stores strings in flash to save RAM + cout << F("\ntype any character to start\n"); + while (!Serial.available()) { + yield(); + } + uint32_t t = millis(); + if (!sd.cardBegin(SD_CONFIG)) { + cout << F( + "\nSD initialization failed.\n" + "Do not reformat the card!\n" + "Is the card correctly inserted?\n" + "Is there a wiring/soldering problem?\n"); + if (isSpi(SD_CONFIG)) { + cout << F( + "Does another SPI device need to be disabled?\n"); + } + errorPrint(); + return; + } + t = millis() - t; + cout << F("init time: ") << dec << t << " ms" << endl; + + if (!sd.card()->readCID(&cid) || !sd.card()->readCSD(&csd) || !sd.card()->readOCR(&ocr) || !sd.card()->readSCR(&scr)) { + cout << F("readInfo failed\n"); + errorPrint(); + return; + } + printCardType(); + cout << F("sdSpecVer: ") << 0.01 * scr.sdSpecVer() << endl; + cout << F("HighSpeedMode: "); + if (scr.sdSpecVer() && sd.card()->cardCMD6(0X00FFFFFF, cmd6Data) && (2 & cmd6Data[13])) { + cout << F("true\n"); + } else { + cout << F("false\n"); + } + cidDmp(); + csdDmp(); + cout << F("\nOCR: ") << uppercase << showbase; + cout << hex << ocr << dec << endl; + if (!mbrDmp()) { + return; + } + if (!sd.volumeBegin()) { + cout << F("\nvolumeBegin failed. Is the card formatted?\n"); + errorPrint(); + return; + } + dmpVol(); +} + +#else + +void setup() {} + +void loop() {} + +#endif diff --git a/Arduino_package/hardware/variants/rtl8720dn_bw16/variant.h b/Arduino_package/hardware/variants/rtl8720dn_bw16/variant.h index d768309d..1e9be420 100644 --- a/Arduino_package/hardware/variants/rtl8720dn_bw16/variant.h +++ b/Arduino_package/hardware/variants/rtl8720dn_bw16/variant.h @@ -101,6 +101,12 @@ extern void wait_for_debug(void); #define SPI_SCLK AMB_D10 // AMB_D10 #define SPI_SS AMB_D9 // AMB_D9 +/* Arduino style SPI pin mapping */ +static const uint8_t SS = SPI_SS; +static const uint8_t MOSI = SPI_MOSI; +static const uint8_t MISO = SPI_MISO; +static const uint8_t SCK = SPI_SCLK; + /* TwoWire/I2C pin mapping */ #define I2C_SDA AMB_D8 // AMB_D8 #define I2C_SCL AMB_D7 // AMB_D7