Access to the "/data" partition via USB Mass Storage (#405)

This commit is contained in:
NellowTCS
2025-11-02 08:26:35 -07:00
committed by GitHub
parent e2ec39304c
commit ab2aa2c4d4
9 changed files with 166 additions and 29 deletions
+45 -6
View File
@@ -9,14 +9,15 @@
namespace tt::hal::usb {
constexpr auto* TAG = "usb";
constexpr auto BOOT_FLAG = 42;
constexpr auto BOOT_FLAG_SDMMC = 42; // Existing
constexpr auto BOOT_FLAG_FLASH = 43; // For flash mode
struct BootMode {
struct BootModeData {
uint32_t flag = 0;
};
static Mode currentMode = Mode::Default;
static RTC_NOINIT_ATTR BootMode bootMode;
static RTC_NOINIT_ATTR BootModeData bootModeData;
sdmmc_card_t* _Nullable getCard() {
auto sdcards = findDevices<sdcard::SpiSdCardDevice>(Device::Type::SdCard);
@@ -87,17 +88,55 @@ bool canRebootIntoMassStorageSdmmc() {
void rebootIntoMassStorageSdmmc() {
if (tusbIsSupported()) {
bootMode.flag = BOOT_FLAG;
bootModeData.flag = BOOT_FLAG_SDMMC;
esp_restart();
}
}
// NEW: Flash mass storage functions
bool startMassStorageWithFlash() {
if (!canStartNewMode()) {
TT_LOG_E(TAG, "Can't start flash mass storage");
return false;
}
if (tusbStartMassStorageWithFlash()) {
currentMode = Mode::MassStorageFlash;
return true;
} else {
TT_LOG_E(TAG, "Failed to init flash mass storage");
return false;
}
}
bool canRebootIntoMassStorageFlash() {
return tusbCanStartMassStorageWithFlash();
}
void rebootIntoMassStorageFlash() {
if (tusbCanStartMassStorageWithFlash()) {
bootModeData.flag = BOOT_FLAG_FLASH;
esp_restart();
}
}
bool isUsbBootMode() {
return bootMode.flag == BOOT_FLAG;
return bootModeData.flag == BOOT_FLAG_SDMMC || bootModeData.flag == BOOT_FLAG_FLASH; // Support both
}
BootMode getUsbBootMode() {
switch (bootModeData.flag) {
case BOOT_FLAG_SDMMC:
return BootMode::Sdmmc;
case BOOT_FLAG_FLASH:
return BootMode::Flash;
default:
return BootMode::None;
}
}
void resetUsbBootMode() {
bootMode.flag = 0;
bootModeData.flag = 0;
}
}
+4
View File
@@ -9,10 +9,14 @@ namespace tt::hal::usb {
bool startMassStorageWithSdmmc() { return false; }
void stop() {}
Mode getMode() { return Mode::Default; }
BootMode getUsbBootMode() { return BootMode::None; }
bool isSupported() { return false; }
bool canRebootIntoMassStorageSdmmc() { return false; }
void rebootIntoMassStorageSdmmc() {}
bool startMassStorageWithFlash() { return false; }
bool canRebootIntoMassStorageFlash() { return false; }
void rebootIntoMassStorageFlash() {}
bool isUsbBootMode() { return false; }
void resetUsbBootMode() {}
+47 -4
View File
@@ -1,6 +1,7 @@
#ifdef ESP_PLATFORM
#include "Tactility/hal/usb/UsbTusb.h"
#include <Tactility/PartitionsEsp.h>
#include <sdkconfig.h>
@@ -9,10 +10,12 @@
#include <Tactility/Log.h>
#include <tinyusb.h>
#include <tusb_msc_storage.h>
#include <wear_levelling.h>
#define TAG "usb"
#define EPNUM_MSC 1
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN)
#define SECTOR_SIZE 512
namespace tt::hal::usb {
extern sdmmc_card_t* _Nullable getCard();
@@ -90,9 +93,9 @@ static uint8_t const msc_hs_configuration_desc[] = {
static void storage_mount_changed_cb(tinyusb_msc_event_t* event) {
if (event->mount_changed_data.is_mounted) {
TT_LOG_I(TAG, "Mounted");
TT_LOG_I(TAG, "MSC Mounted");
} else {
TT_LOG_I(TAG, "Unmounted");
TT_LOG_I(TAG, "MSC Unmounted");
}
}
@@ -152,22 +155,62 @@ bool tusbStartMassStorageWithSdmmc() {
auto result = tinyusb_msc_storage_init_sdmmc(&config_sdmmc);
if (result != ESP_OK) {
TT_LOG_E(TAG, "TinyUSB init failed: %s", esp_err_to_name(result));
TT_LOG_E(TAG, "TinyUSB SDMMC init failed: %s", esp_err_to_name(result));
} else {
TT_LOG_I(TAG, "TinyUSB SDMMC init success");
}
return result == ESP_OK;
}
bool tusbStartMassStorageWithFlash() {
TT_LOG_I(TAG, "Starting flash MSC");
ensureDriverInstalled();
wl_handle_t handle = tt::getDataPartitionWlHandle();
if (handle == WL_INVALID_HANDLE) {
TT_LOG_E(TAG, "WL not mounted for /data");
return false;
}
const tinyusb_msc_spiflash_config_t config_flash = {
.wl_handle = handle,
.callback_mount_changed = storage_mount_changed_cb,
.callback_premount_changed = nullptr,
.mount_config = {
.format_if_mount_failed = false,
.max_files = 5,
.allocation_unit_size = 0,
.disk_status_check_enable = false,
.use_one_fat = false
}
};
esp_err_t result = tinyusb_msc_storage_init_spiflash(&config_flash);
if (result != ESP_OK) {
TT_LOG_E(TAG, "TinyUSB flash init failed: %s", esp_err_to_name(result));
} else {
TT_LOG_I(TAG, "TinyUSB flash init success");
}
return result == ESP_OK;
}
void tusbStop() {
tinyusb_msc_storage_deinit();
}
bool tusbCanStartMassStorageWithFlash() {
return tusbIsSupported() && (tt::getDataPartitionWlHandle() != WL_INVALID_HANDLE);
}
#else
bool tusbIsSupported() { return false; }
bool tusbStartMassStorageWithSdmmc() { return false; }
bool tusbStartMassStorageWithFlash() { return false; }
void tusbStop() {}
bool tusbCanStartMassStorageWithFlash() { return false; }
#endif // TinyUSB enabled
#endif // CONFIG_TINYUSB_MSC_ENABLED
#endif // ESP_PLATFORM