Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions src/core/massStorage.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@


#include "massStorage.h"
#include "core/display.h"
#include <USB.h>
#include <tusb.h>
#if defined(SOC_USB_OTG_SUPPORTED)
bool MassStorage::shouldStop = false;
int32_t MassStorage::status = -1;
Expand Down Expand Up @@ -40,10 +39,10 @@ void MassStorage::loop() {
if (prev_status != status) {
vTaskDelay(100 / portTICK_PERIOD_MS);
switch (status) {
case ARDUINO_USB_STARTED_EVENT: drawUSBStickIcon(true); break;
case ARDUINO_USB_STARTED_EVENT: drawUSBStickIcon(true); break;
case ARDUINO_USB_RESUME_EVENT: drawUSBStickIcon(true); break;
case ARDUINO_USB_STOPPED_EVENT: drawUSBStickIcon(false); break;
case ARDUINO_USB_SUSPEND_EVENT: MassStorage::displayMessage("USB suspend"); break;
case ARDUINO_USB_RESUME_EVENT: MassStorage::displayMessage("USB resume"); break;
case ARDUINO_USB_SUSPEND_EVENT: drawUSBStickIcon(false); break;
default: break;
}
prev_status = status;
Expand All @@ -56,6 +55,13 @@ void MassStorage::beginUsb() {
setupUsbEvent();
drawUSBStickIcon(false);
USB.begin();
// If USB was already connected before opening mass storage,
// STARTED event already fired before our listener was registered.
// Check and force status so loop() picks it up immediately.
vTaskDelay(300 / portTICK_PERIOD_MS);
if (tud_connected()) {
status = ARDUINO_USB_STARTED_EVENT;
}
}

void MassStorage::setupUsbCallback() {
Expand Down Expand Up @@ -132,8 +138,6 @@ bool usbStartStopCallback(uint8_t power_condition, bool start, bool load_eject)
}

void drawUSBStickIcon(bool plugged) {
static bool first = true;

float scale;
if (bruceConfigPins.rotation & 0b01) scale = float((float)tftHeight / (float)135);
else scale = float((float)tftWidth / (float)240);
Expand Down Expand Up @@ -167,17 +171,14 @@ void drawUSBStickIcon(bool plugged) {
int ledX = bodyX + 2 * ledW;
int ledY = bodyY + (iconH - ledH) / 2;

if (first) {
MassStorage::displayMessage("");
// Body
tft.fillRoundRect(bodyX, bodyY, bodyW, bodyH, radius, TFT_DARKCYAN);
// Port USB
tft.fillRoundRect(portX, portY, portW, portH, radius, TFT_LIGHTGREY);
// Small square on port
tft.fillRoundRect(portDetailX, portDetailY1, portDetailW, portDetailH, radius, TFT_DARKGREY);
tft.fillRoundRect(portDetailX, portDetailY2, portDetailW, portDetailH, radius, TFT_DARKGREY);
first = false;
}
MassStorage::displayMessage("");
// Body
tft.fillRoundRect(bodyX, bodyY, bodyW, bodyH, radius, TFT_DARKCYAN);
// Port USB
tft.fillRoundRect(portX, portY, portW, portH, radius, TFT_LIGHTGREY);
// Small square on port
tft.fillRoundRect(portDetailX, portDetailY1, portDetailW, portDetailH, radius, TFT_DARKGREY);
tft.fillRoundRect(portDetailX, portDetailY2, portDetailW, portDetailH, radius, TFT_DARKGREY);
// Led
tft.fillRoundRect(ledX, ledY, ledW, ledH, radius, plugged ? TFT_GREEN : TFT_RED);
}
Expand Down
188 changes: 188 additions & 0 deletions src/core/massStorage_m5_Launcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#ifdef ARDUINO_USB_MODE

#include "massStorage.h"
#include "display.h"
#include "sd_functions.h"
#include <USB.h>

bool MassStorage::shouldStop = false;

MassStorage::MassStorage() { setup(); }

MassStorage::~MassStorage() {
msc.end();
USB.~ESPUSB();

// Hack to make USB back to flash mode
USB.enableDFU();
}

void MassStorage::setup() {
displayMessage("Mounting...");

setShouldStop(false);

if (!setupSdCard()) {
displayRedStripe("SD card not found.");
delay(1000);
return;
}

beginUsb();

vTaskDelay(pdTICKS_TO_MS(500));
return loop();
}

void MassStorage::loop() {
while (!check(EscPress) && !shouldStop) yield();
}

void MassStorage::beginUsb() {
setupUsbCallback();
setupUsbEvent();
drawUSBStickIcon(false);
USB.begin();
}

void MassStorage::setupUsbCallback() {
uint32_t secSize = SDM.sectorSize();
uint32_t numSectors = SDM.numSectors();

msc.vendorID("ESP32");
msc.productID("Launcher");
msc.productRevision("1.0");

msc.onRead(usbReadCallback);
msc.onWrite(usbWriteCallback);
msc.onStartStop(usbStartStopCallback);

msc.mediaPresent(true);
msc.begin(numSectors, secSize);
}

void MassStorage::setupUsbEvent() {
USB.onEvent([](void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
if (event_base == ARDUINO_USB_EVENTS) {
auto *data = reinterpret_cast<arduino_usb_event_data_t *>(event_data);
switch (event_id) {
case ARDUINO_USB_STARTED_EVENT: drawUSBStickIcon(true); break;
case ARDUINO_USB_STOPPED_EVENT: drawUSBStickIcon(false); break;
case ARDUINO_USB_SUSPEND_EVENT: MassStorage::displayMessage("USB suspend"); break;
case ARDUINO_USB_RESUME_EVENT: MassStorage::displayMessage("USB resume"); break;
default: break;
}
}
});
}

void MassStorage::displayMessage(String message) {
tft->drawRoundRect(5, 5, tftWidth - 10, tftHeight - 10, 5, ALCOLOR);
tft->fillRoundRect(6, 6, tftWidth - 12, tftHeight - 12, 5, BGCOLOR);
setTftDisplay(7, 7, ALCOLOR, FP, BGCOLOR);
tft->drawCentreString("-= USB MSC =-", tftWidth / 2, 0, 8);
tft->setCursor(10, 20);
tftprint(message, 10, 5);
}

int32_t usbWriteCallback(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) {
// Verify freespace
uint64_t freeSpace = SDM.totalBytes() - SDM.usedBytes();
if (bufsize > freeSpace) {
return -1; // no space available
}

// Verify sector size
const uint32_t secSize = SDM.sectorSize();
if (secSize == 0) return -1; // disk error

// Write blocs
for (uint32_t x = 0; x < bufsize / secSize; ++x) {
uint8_t blkBuffer[secSize];
memcpy(blkBuffer, buffer + secSize * x, secSize);
if (!SDM.writeRAW(blkBuffer, lba + x)) {
return -1; // write error
}
}
return bufsize;
}

int32_t usbReadCallback(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
// Verify sector size
const uint32_t secSize = SDM.sectorSize();
if (secSize == 0) return -1; // disk error

// Read blocs
for (uint32_t x = 0; x < bufsize / secSize; ++x) {
if (!SDM.readRAW(reinterpret_cast<uint8_t *>(buffer) + (x * secSize), lba + x)) {
return -1; // read error
}
}
return bufsize;
}

bool usbStartStopCallback(uint8_t power_condition, bool start, bool load_eject) {
if (!start && load_eject) {
MassStorage::setShouldStop(true);
return false;
}

return true;
}

void drawUSBStickIcon(bool plugged) {
#ifdef E_PAPER_DISPLAY
tft->stopCallback();
#endif
MassStorage::displayMessage("");

float scale;
if (rotation & 0b01) scale = float((float)tftHeight / (float)135);
else scale = float((float)tftWidth / (float)240);

int iconW = scale * 120;
int iconH = scale * 40;

if (iconW % 2 != 0) iconW++;
if (iconH % 2 != 0) iconH++;

int radius = 5;

int bodyW = 2 * iconW / 3;
int bodyH = iconH;
int bodyX = tftWidth / 2 - iconW / 2;
int bodyY = tftHeight / 2;

int portW = iconW - bodyW;
int portH = 0.8 * bodyH;
int portX = bodyX + bodyW;
int portY = bodyY + (bodyH - portH) / 2;

int portDetailW = portW / 2;
int portDetailH = portH / 4;
int portDetailX = portX + (portW - portDetailW) / 2;
int portDetailY1 = portY + 0.8 * portDetailH;
int portDetailY2 = portY + portH - 1.8 * portDetailH;

int ledW = 0.1 * bodyH;
int ledH = 0.6 * bodyH;
int ledX = bodyX + 2 * ledW;
int ledY = bodyY + (iconH - ledH) / 2;

// Body
tft->fillRoundRect(bodyX, bodyY, bodyW, bodyH, radius, DARKCYAN);
// Port USB
tft->fillRoundRect(portX, portY, portW, portH, radius, LIGHTGREY);
// Small square on port
tft->fillRoundRect(portDetailX, portDetailY1, portDetailW, portDetailH, radius, DARKGREY);
tft->fillRoundRect(portDetailX, portDetailY2, portDetailW, portDetailH, radius, DARKGREY);
// Led
tft->fillRoundRect(ledX, ledY, ledW, ledH, radius, plugged ? GREEN : RED);

tft->display(false);
#ifdef E_PAPER_DISPLAY
tft->startCallback();
#endif
}

#endif // ARDUINO_USB_MODE