#include "SDInterface.h" #include "lang_var.h" bool SDInterface::initSD() { #ifdef HAS_SD String display_string = ""; #ifdef KIT pinMode(SD_DET, INPUT); if (digitalRead(SD_DET) == LOW) { Serial.println(F("SD Card Detect Pin Detected")); } else { Serial.println(F("SD Card Detect Pin Not Detected")); this->supported = false; return false; } #endif pinMode(SD_CS, OUTPUT); delay(10); #if (defined(MARAUDER_M5STICKC)) || (defined(HAS_CYD_TOUCH)) /* Set up SPI SD Card using external pin header StickCPlus Header - SPI SD Card Reader 3v3 - 3v3 GND - GND G0 - CLK G36/G25 - MISO G26 - MOSI - CS (jumper to SD Card GND Pin) */ #if defined(MARAUDER_M5STICKC) enum { SPI_SCK = 0, SPI_MISO = 36, SPI_MOSI = 26 }; #elif defined(MARAUDER_CYD_MICRO) enum { SPI_SCK = SD_SCK, SPI_MISO = SD_MISO, SPI_MOSI = SD_MOSI }; #else enum { SPI_SCK = 0, SPI_MISO = 36, SPI_MOSI = 26 }; #endif this->spiExt = new SPIClass(); this->spiExt->begin(SPI_SCK, SPI_MISO, SPI_MOSI, SD_CS); if (!SD.begin(SD_CS, *(this->spiExt))) { #else if (!SD.begin(SD_CS)) { #endif Serial.println(F("Failed to mount SD Card")); this->supported = false; return false; } else { this->supported = true; this->cardType = SD.cardType(); //if (cardType == CARD_MMC) // Serial.println(F("SD: MMC Mounted")); //else if(cardType == CARD_SD) // Serial.println(F("SD: SDSC Mounted")); //else if(cardType == CARD_SDHC) // Serial.println(F("SD: SDHC Mounted")); //else // Serial.println(F("SD: UNKNOWN Card Mounted")); this->cardSizeMB = SD.cardSize() / (1024 * 1024); //Serial.printf("SD Card Size: %lluMB\n", this->cardSizeMB); if (this->supported) { const int NUM_DIGITS = log10(this->cardSizeMB) + 1; char sz[NUM_DIGITS + 1]; sz[NUM_DIGITS] = 0; for ( size_t i = NUM_DIGITS; i--; this->cardSizeMB /= 10) { sz[i] = '0' + (this->cardSizeMB % 10); display_string.concat((String)sz[i]); } this->card_sz = sz; } if (!SD.exists("/SCRIPTS")) { Serial.println("/SCRIPTS does not exist. Creating..."); SD.mkdir("/SCRIPTS"); Serial.println("/SCRIPTS created"); } this->sd_files = new LinkedList(); this->sd_files->add("Back"); return true; } #else Serial.println("SD support disabled, skipping init"); return false; #endif } File SDInterface::getFile(String path) { if (this->supported) { File file = SD.open(path, FILE_READ); //if (file) return file; } } bool SDInterface::removeFile(String file_path) { if (SD.remove(file_path)) return true; else return false; } void SDInterface::listDirToLinkedList(LinkedList* file_names, String str_dir, String ext) { if (this->supported) { File dir = SD.open(str_dir); while (true) { File entry = dir.openNextFile(); if (!entry) { break; } if (entry.isDirectory()) continue; String file_name = entry.name(); if (ext != "") { if (file_name.endsWith(ext)) { file_names->add(file_name); } } else file_names->add(file_name); } } } void SDInterface::listDir(String str_dir){ if (this->supported) { File dir = SD.open(str_dir); while (true) { File entry = dir.openNextFile(); if (! entry) { break; } //for (uint8_t i = 0; i < numTabs; i++) //{ // Serial.print('\t'); //} Serial.print(entry.name()); Serial.print("\t"); Serial.println(entry.size()); entry.close(); } } } void SDInterface::runUpdate() { #ifdef HAS_SCREEN display_obj.tft.setTextWrap(false); display_obj.tft.setFreeFont(NULL); display_obj.tft.setCursor(0, TFT_HEIGHT / 3); display_obj.tft.setTextSize(1); display_obj.tft.setTextColor(TFT_WHITE); display_obj.tft.println(F(text15)); #endif File updateBin = SD.open("/update.bin"); if (updateBin) { if(updateBin.isDirectory()){ #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_RED); display_obj.tft.println(F(text_table2[0])); #endif Serial.println(F("Error, could not find \"update.bin\"")); #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_WHITE); #endif updateBin.close(); return; } size_t updateSize = updateBin.size(); if (updateSize > 0) { #ifdef HAS_SCREEN display_obj.tft.println(F(text_table2[1])); #endif Serial.println(F("Starting update over SD. Please wait...")); this->performUpdate(updateBin, updateSize); } else { #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_RED); display_obj.tft.println(F(text_table2[2])); #endif Serial.println(F("Error, file is empty")); #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_WHITE); #endif return; } updateBin.close(); // whe finished remove the binary from sd card to indicate end of the process #ifdef HAS_SCREEN display_obj.tft.println(F(text_table2[3])); #endif Serial.println(F("rebooting...")); //SD.remove("/update.bin"); delay(1000); ESP.restart(); } else { #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_RED); display_obj.tft.println(F(text_table2[4])); #endif Serial.println(F("Could not load update.bin from sd root")); #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_WHITE); #endif } } void SDInterface::performUpdate(Stream &updateSource, size_t updateSize) { if (Update.begin(updateSize)) { #ifdef HAS_SCREEN display_obj.tft.println(text_table2[5] + String(updateSize)); display_obj.tft.println(F(text_table2[6])); #endif size_t written = Update.writeStream(updateSource); if (written == updateSize) { #ifdef HAS_SCREEN display_obj.tft.println(text_table2[7] + String(written) + text_table2[10]); #endif Serial.println("Written : " + String(written) + " successfully"); } else { #ifdef HAS_SCREEN display_obj.tft.println(text_table2[8] + String(written) + "/" + String(updateSize) + text_table2[9]); #endif Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?"); } if (Update.end()) { Serial.println("OTA done!"); if (Update.isFinished()) { #ifdef HAS_SCREEN display_obj.tft.println(F(text_table2[11])); #endif Serial.println(F("Update successfully completed. Rebooting.")); } else { #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_RED); display_obj.tft.println(text_table2[12]); #endif Serial.println("Update not finished? Something went wrong!"); #ifdef HAS_SCREEN display_obj.tft.setTextColor(TFT_WHITE); #endif } } else { #ifdef HAS_SCREEN display_obj.tft.println(text_table2[13] + String(Update.getError())); #endif Serial.println("Error Occurred. Error #: " + String(Update.getError())); } } else { #ifdef HAS_SCREEN display_obj.tft.println(text_table2[14]); #endif Serial.println("Not enough space to begin OTA"); } } bool SDInterface::checkDetectPin() { #ifdef KIT if (digitalRead(SD_DET) == LOW) return true; else return false; #endif return false; } void SDInterface::main() { if (!this->supported) { if (checkDetectPin()) { delay(100); this->initSD(); } } }