- Implemented [unPhone](https://unphone.net/) v9 board - Updated `.clang-format` to better reflect the intended code style - Fix SD card compatibility issues for all boards (frequency wasn't set well) - Moved `I2cDevice` class from CoreS3 board project to TactilityHeadless project - Tactility configuration now has default empty lists for apps and services fields - Fix for Launcher app: we don't need padding when showing it vertically - Fix for I2cDevice read/write calls that checked for `esp_err_t` instead of `bool` - Fix for TinyUSB init that checked for `esp_err_t` instead of `bool`
173 lines
4.8 KiB
C++
173 lines
4.8 KiB
C++
#ifdef ESP_PLATFORM
|
|
|
|
#include "UsbTusb.h"
|
|
#include "sdkconfig.h"
|
|
|
|
#if CONFIG_TINYUSB_MSC_ENABLED == 1
|
|
|
|
#include "Log.h"
|
|
#include "tinyusb.h"
|
|
#include "tusb_msc_storage.h"
|
|
|
|
#define TAG "usb"
|
|
#define EPNUM_MSC 1
|
|
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN)
|
|
|
|
namespace tt::hal::usb {
|
|
extern sdmmc_card_t* _Nullable getCard();
|
|
}
|
|
|
|
enum {
|
|
ITF_NUM_MSC = 0,
|
|
ITF_NUM_TOTAL
|
|
};
|
|
|
|
enum {
|
|
EDPT_CTRL_OUT = 0x00,
|
|
EDPT_CTRL_IN = 0x80,
|
|
|
|
EDPT_MSC_OUT = 0x01,
|
|
EDPT_MSC_IN = 0x81,
|
|
};
|
|
|
|
static bool driverInstalled = false;
|
|
|
|
static tusb_desc_device_t descriptor_config = {
|
|
.bLength = sizeof(descriptor_config),
|
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
|
.bcdUSB = 0x0200,
|
|
.bDeviceClass = TUSB_CLASS_MISC,
|
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
|
.idVendor = 0x303A, // TODO: Espressif VID. Do we need to change this?
|
|
.idProduct = 0x4002,
|
|
.bcdDevice = 0x100,
|
|
.iManufacturer = 0x01,
|
|
.iProduct = 0x02,
|
|
.iSerialNumber = 0x03,
|
|
.bNumConfigurations = 0x01
|
|
};
|
|
|
|
static char const* string_desc_arr[] = {
|
|
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
|
"Espressif", // 1: Manufacturer
|
|
"Tactility Device", // 2: Product
|
|
"42", // 3: Serials
|
|
"Tactility Mass Storage", // 4. MSC
|
|
};
|
|
|
|
static uint8_t const msc_fs_configuration_desc[] = {
|
|
// Config number, interface count, string index, total length, attribute, power in mA
|
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
|
|
|
// Interface number, string index, EP Out & EP In address, EP size
|
|
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, 64),
|
|
};
|
|
|
|
#if (TUD_OPT_HIGH_SPEED)
|
|
static const tusb_desc_device_qualifier_t device_qualifier = {
|
|
.bLength = sizeof(tusb_desc_device_qualifier_t),
|
|
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
|
.bcdUSB = 0x0200,
|
|
.bDeviceClass = TUSB_CLASS_MISC,
|
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
|
.bNumConfigurations = 0x01,
|
|
.bReserved = 0
|
|
};
|
|
|
|
static uint8_t const msc_hs_configuration_desc[] = {
|
|
// Config number, interface count, string index, total length, attribute, power in mA
|
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
|
|
|
// Interface number, string index, EP Out & EP In address, EP size
|
|
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, 512),
|
|
};
|
|
#endif // TUD_OPT_HIGH_SPEED
|
|
|
|
static void storage_mount_changed_cb(tinyusb_msc_event_t* event) {
|
|
if (event->mount_changed_data.is_mounted) {
|
|
TT_LOG_I(TAG, "Mounted");
|
|
} else {
|
|
TT_LOG_I(TAG, "Unmounted");
|
|
}
|
|
}
|
|
|
|
static bool ensureDriverInstalled() {
|
|
if (driverInstalled) {
|
|
return true;
|
|
}
|
|
|
|
const tinyusb_config_t tusb_cfg = {
|
|
.device_descriptor = &descriptor_config,
|
|
.string_descriptor = string_desc_arr,
|
|
.string_descriptor_count = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]),
|
|
.external_phy = false,
|
|
#if (TUD_OPT_HIGH_SPEED)
|
|
.fs_configuration_descriptor = msc_fs_configuration_desc,
|
|
.hs_configuration_descriptor = msc_hs_configuration_desc,
|
|
.qualifier_descriptor = &device_qualifier,
|
|
#else
|
|
.configuration_descriptor = msc_fs_configuration_desc,
|
|
#endif // TUD_OPT_HIGH_SPEED
|
|
.self_powered = false,
|
|
.vbus_monitor_io = 0
|
|
};
|
|
|
|
if (tinyusb_driver_install(&tusb_cfg) != ESP_OK) {
|
|
TT_LOG_E(TAG, "Failed to install TinyUSB driver");
|
|
return false;
|
|
}
|
|
|
|
driverInstalled = true;
|
|
return true;
|
|
}
|
|
|
|
bool tusbIsSupported() { return true; }
|
|
|
|
bool tusbStartMassStorageWithSdmmc() {
|
|
ensureDriverInstalled();
|
|
|
|
auto* card = tt::hal::usb::getCard();
|
|
if (card == nullptr) {
|
|
TT_LOG_E(TAG, "SD card not mounted");
|
|
return false;
|
|
}
|
|
|
|
const tinyusb_msc_sdmmc_config_t config_sdmmc = {
|
|
.card = card,
|
|
.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
|
|
}
|
|
};
|
|
|
|
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));
|
|
}
|
|
|
|
return result == ESP_OK;
|
|
}
|
|
|
|
void tusbStop() {
|
|
tinyusb_msc_storage_deinit();
|
|
}
|
|
|
|
#else
|
|
|
|
bool tusbIsSupported() { return false; }
|
|
bool tusbStartMassStorageWithSdmmc() { return false; }
|
|
void tusbStop() {}
|
|
|
|
#endif // TinyUSB enabled
|
|
|
|
#endif // ESP_PLATFORM
|