Login
1 branch 0 tags
Ben (Desktop/Arch) We're USB MSC now! 93094f8 1 month ago 43 Commits
moon / firmware / esp32 / main / usb_msc.c
#include "usb_msc.h"
#include "tusb_msc_storage.h"
#include "tinyusb.h"
#include "tinyusb_types.h"
#include <string.h>
#include "esp_mac.h"

static bool prev_in_use = false;

// USB Device Descriptor
static const tusb_desc_device_t desc_device = {
    .bLength = sizeof(tusb_desc_device_t),
    .bDescriptorType = TUSB_DESC_DEVICE,
    .bcdUSB = 0x0200,
    .bDeviceClass = 0x00,
    .bDeviceSubClass = 0x00,
    .bDeviceProtocol = 0x00,
    .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
    .idVendor = 0x303A,  // Espressif VID
    .idProduct = 0x4002,
    .bcdDevice = 0x0100,
    .iManufacturer = 0x01,
    .iProduct = 0x02,
    .iSerialNumber = 0x03,
    .bNumConfigurations = 0x01,
};

// MSC endpoint addresses
#define EPNUM_MSC_OUT 0x01
#define EPNUM_MSC_IN  0x81

// Configuration descriptor
static const uint8_t desc_configuration[] = {
    TUD_CONFIG_DESCRIPTOR(1, 1, 0, TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN, 0, 100),
    TUD_MSC_DESCRIPTOR(0, 0, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
};

// Serial number string built from chip MAC
static char serial_str[13];

static const char *string_descriptors[] = {
    "\x09\x04",     // 0: Language (English)
    "Moon",          // 1: Manufacturer
    "Moon Player",   // 2: Product
    serial_str,      // 3: Serial
};

static void build_serial_string(void) {
    uint8_t mac[6];
    esp_read_mac(mac, ESP_MAC_WIFI_STA);
    snprintf(serial_str, sizeof(serial_str),
             "%02X%02X%02X%02X%02X%02X",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

void usb_msc_init(void) {
    build_serial_string();

    const tinyusb_config_t tusb_cfg = {
        .device_descriptor = &desc_device,
        .string_descriptor = string_descriptors,
        .string_descriptor_count = sizeof(string_descriptors) / sizeof(string_descriptors[0]),
        .external_phy = false,
        .configuration_descriptor = desc_configuration,
    };

    ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
}

bool usb_msc_host_connected(void) {
    bool in_use = tinyusb_msc_storage_in_use_by_usb_host();
    if (in_use && !prev_in_use) {
        prev_in_use = true;
        return true;
    }
    prev_in_use = in_use;
    return false;
}

bool usb_msc_host_disconnected(void) {
    bool in_use = tinyusb_msc_storage_in_use_by_usb_host();
    if (!in_use && prev_in_use) {
        prev_in_use = false;
        return true;
    }
    prev_in_use = in_use;
    return false;
}

bool usb_msc_is_connected(void) {
    return tinyusb_msc_storage_in_use_by_usb_host();
}