2

I want both, a Config file on the MSC and also FW Update via USB.

Right now I can choose on a Hold Button which should be done.

But it shows always two Drives instead of one. One Drive is empty and the other one is with a file.

What do I need to change, that only one Drive is shown?

#if ARDUINO_USB_MODE
#warning This sketch should be used when USB is in OTG mode
void setup() {}
void loop() {}
#else
#include "USB.h"
#include "FirmwareMSC.h"
#include "USBMSC.h"
#include "FFat.h"
#include "FS.h"
#if !ARDUINO_USB_MSC_ON_BOOT
FirmwareMSC MSC_Update;
// USB Mass Storage Class (MSC) object
USBMSC msc;
#endif
#if ARDUINO_USB_CDC_ON_BOOT
#define HWSerial Serial0
#define USBSerial Serial
#else
#define HWSerial Serial
USBCDC USBSerial;
#endif
#endif

// Block size of flash memory (in bytes) (4KB)
#define BLOCK_SIZE 4096




// Flash memory object
EspClass _flash;

// Partition information object
const esp_partition_t* Partition;


void listDir(fs::FS& fs, const char* dirname, int numTabs = 0);


const esp_partition_t* partition() {
  // Return the first FAT partition found (should be the only one)
  return esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL);
}


static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
  //Serial.println("Write lba: " + String(lba) + " offset: " + String(offset) + " bufsize: " + String(bufsize));

  // Erase block before writing as to not leave any garbage
  _flash.partitionEraseRange(Partition, offset + (lba * BLOCK_SIZE), bufsize);

  // Write data to flash memory in blocks from buffer
  _flash.partitionWrite(Partition, offset + (lba * BLOCK_SIZE), (uint32_t*)buffer, bufsize);

  return bufsize;
}

static int32_t onRead(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
  //Serial.println("Read lba: " + String(lba) + " offset: " + String(offset) + " bufsize: " + String(bufsize));

  // Read data from flash memory in blocks and store in buffer
  _flash.partitionRead(Partition, offset + (lba * BLOCK_SIZE), (uint32_t*)buffer, bufsize);

  return bufsize;
}

static bool onStartStop(uint8_t power_condition, bool start, bool load_eject) {
  return true;
}

static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
  if (event_base == ARDUINO_USB_EVENTS) {
    arduino_usb_event_data_t * data = (arduino_usb_event_data_t*)event_data;
    switch (event_id) {
      case ARDUINO_USB_STARTED_EVENT:
        HWSerial.println("USB PLUGGED");
        break;
      case ARDUINO_USB_STOPPED_EVENT:
        HWSerial.println("USB UNPLUGGED");
        break;
      case ARDUINO_USB_SUSPEND_EVENT:
        HWSerial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en);
        break;
      case ARDUINO_USB_RESUME_EVENT:
        HWSerial.println("USB RESUMED");
        break;

      default:
        break;
    }
  } else if (event_base == ARDUINO_FIRMWARE_MSC_EVENTS) {
    arduino_firmware_msc_event_data_t * data = (arduino_firmware_msc_event_data_t*)event_data;
    switch (event_id) {
      case ARDUINO_FIRMWARE_MSC_START_EVENT:
        HWSerial.println("MSC Update Start");
        break;
      case ARDUINO_FIRMWARE_MSC_WRITE_EVENT:
        //HWSerial.printf("MSC Update Write %u bytes at offset %u\n", data->write.size, data->write.offset);
        HWSerial.print(".");
        break;
      case ARDUINO_FIRMWARE_MSC_END_EVENT:
        HWSerial.printf("\nMSC Update End: %u bytes\n", data->end.size);
        break;
      case ARDUINO_FIRMWARE_MSC_ERROR_EVENT:
        HWSerial.printf("MSC Update ERROR! Progress: %u bytes\n", data->error.size);
        break;
      case ARDUINO_FIRMWARE_MSC_POWER_EVENT:
        HWSerial.printf("MSC Update Power: power: %u, start: %u, eject: %u", data->power.power_condition, data->power.start, data->power.load_eject);
        break;

      default:
        break;
    }
  }
}


void setup() {
  HWSerial.begin(115200);
  HWSerial.setDebugOutput(true);

  Serial.begin(115200);

  Serial.println("Starting Serial");

  Serial.println("Initializing FFat");

  pinMode(0, INPUT);
  pinMode(17, OUTPUT);
  digitalWrite(17, LOW);
  delay(3000);

  // False for the msc mode and True for internal filesystem mode
  // Since both cannot write to the same table at the same time
  if (digitalRead(0)) {

    // begin(true) will format on fail
    if (!FFat.begin()) {
      Serial.println("Mount Failed, formatting...");

      // If mount fails, format the partition (Feels cleaner than FFat.begin(true))
      if (FFat.format(FFAT_WIPE_FULL)) {
        Serial.println("Format Success");
      } else {
        Serial.println("Format Failed");
      }
    } else {
      Serial.println("fat success");
    }

    Serial.println("Listing before");

    listDir(FFat, "/");

    if (!FFat.exists("/config.json")) {
      Serial.println("Creating file");
      // Create a file | use F("...") on file paths or it creates weird problems (idk why)
      File f = FFat.open(F("/config.json"), FILE_WRITE, true);

      // Write to file (using F("...") here just to be safe)
      f.println(F("{\n  \"r\": 255,\n  \"g\": 0,\n  \"b\": 0,\n  \"w\": 0,\n  \"offset\": 0\n}"));

      // Close and flush file (Not sure if flush is needed, but there to be safe)
      f.flush();
      f.close();

      Serial.println("Listing After");

      // Print directory contents
      listDir(FFat, "/");
    }
  } else {
    digitalWrite(17, HIGH);
    delay(3000);
    Serial.println("Initializing MSC");
    // Initialize USB metadata and callbacks for MSC (Mass Storage Class)
    if (digitalRead(0)) {
      Serial.println("Getting partition info");
      // Get partition information
      Partition = partition();
      msc.vendorID("ESP32");
      msc.productID("USB_MSC");
      msc.productRevision("1.0");
      msc.onRead(onRead);
      msc.onWrite(onWrite);
      msc.onStartStop(onStartStop);
      msc.mediaPresent(true);
      msc.begin(Partition->size / BLOCK_SIZE, BLOCK_SIZE);
      digitalWrite(17, HIGH);
    } else {
      MSC_Update.onEvent(usbEventCallback);
      MSC_Update.begin();
      digitalWrite(17, LOW);
    }

    USBSerial.begin();
    Serial.println("Initializing USB");

    USB.begin();

    Serial.println("Printing flash size");

    //Print flash size
    char buff[50];
    sprintf(buff, "Flash Size: %d", Partition->size);
    Serial.println(buff);
  }
}

void loop() {
  delay(5000);
}


void listDir(fs::FS& fs, const char* dirname, int numTabs) {
  File dir = fs.open(F(dirname));

  if (!dir) {
    Serial.print("Failed to open directory: ");
    Serial.println(dirname);
    return;
  }
  if (!dir.isDirectory()) {
    Serial.println("Not a directory");
    return;
  }

  while (true) {
    File file =  dir.openNextFile();
    if (!file) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(file.name());
    if (file.isDirectory()) {
      Serial.println("/");
      // Ugly string concatenation to get the full path
      listDir(fs, ((std::string)"/" + (std::string)file.name()).c_str(), numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t\tSize: ");
      Serial.println(file.size(), DEC);
    }
    file.close();
  }
}

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.