|
|
@@ -11,182 +11,20 @@
|
|
|
* For different scenarios and behaviour, Refer to README of this example.
|
|
|
*/
|
|
|
|
|
|
-#include <unistd.h>
|
|
|
#include <errno.h>
|
|
|
#include <dirent.h>
|
|
|
-#include "esp_log.h"
|
|
|
#include "esp_console.h"
|
|
|
+#include "esp_check.h"
|
|
|
+#include "driver/gpio.h"
|
|
|
#include "tinyusb.h"
|
|
|
-#include "class/msc/msc_device.h"
|
|
|
#include "tusb_msc_storage.h"
|
|
|
-#include "driver/gpio.h"
|
|
|
+#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SDMMCCARD
|
|
|
+#include "diskio_impl.h"
|
|
|
+#include "diskio_sdmmc.h"
|
|
|
+#endif
|
|
|
|
|
|
static const char *TAG = "example_main";
|
|
|
|
|
|
-/* TinyUSB MSC callbacks
|
|
|
- ********************************************************************* */
|
|
|
-
|
|
|
-/** SCSI ASC/ASCQ codes. **/
|
|
|
-/** User can add and use more codes as per the need of the application **/
|
|
|
-#define SCSI_CODE_ASC_MEDIUM_NOT_PRESENT 0x3A /** SCSI ASC code for 'MEDIUM NOT PRESENT' **/
|
|
|
-#define SCSI_CODE_ASC_INVALID_COMMAND_OPERATION_CODE 0x20 /** SCSI ASC code for 'INVALID COMMAND OPERATION CODE' **/
|
|
|
-#define SCSI_CODE_ASCQ 0x00
|
|
|
-
|
|
|
-static void _mount(void);
|
|
|
-static void _unmount(void);
|
|
|
-static bool is_eject = false;
|
|
|
-
|
|
|
-// Invoked when received SCSI_CMD_INQUIRY
|
|
|
-// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
|
|
-void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
|
|
-{
|
|
|
- (void) lun;
|
|
|
- ESP_LOGD(TAG, "tud_msc_inquiry_cb() invoked");
|
|
|
-
|
|
|
- const char vid[] = "TinyUSB";
|
|
|
- const char pid[] = "Flash Storage";
|
|
|
- const char rev[] = "0.1";
|
|
|
-
|
|
|
- memcpy(vendor_id, vid, strlen(vid));
|
|
|
- memcpy(product_id, pid, strlen(pid));
|
|
|
- memcpy(product_rev, rev, strlen(rev));
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when received Test Unit Ready command.
|
|
|
-// return true allowing host to read/write this LUN e.g SD card inserted
|
|
|
-bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
|
|
-{
|
|
|
- (void) lun;
|
|
|
- ESP_LOGD(TAG, "tud_msc_test_unit_ready_cb() invoked");
|
|
|
-
|
|
|
- if (is_eject) {
|
|
|
- tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, SCSI_CODE_ASC_MEDIUM_NOT_PRESENT, SCSI_CODE_ASCQ);
|
|
|
- return false;
|
|
|
- } else {
|
|
|
- ESP_LOGD(TAG, "tud_msc_test_unit_ready_cb: MSC START: Expose Over USB");
|
|
|
- _unmount();
|
|
|
- return true;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
|
|
-// Application update block count and block size
|
|
|
-void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size)
|
|
|
-{
|
|
|
- (void) lun;
|
|
|
-
|
|
|
- uint32_t sec_count = storage_get_sector_count();
|
|
|
- uint32_t sec_size = storage_get_sector_size();
|
|
|
- ESP_LOGD(TAG, "tud_msc_capacity_cb() sec_count(%lu), sec_size(%lu)", sec_count, sec_size);
|
|
|
- *block_count = sec_count;
|
|
|
- *block_size = (uint16_t)sec_size;
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when received Start Stop Unit command
|
|
|
-// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
|
|
-// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
|
|
-bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
|
|
|
-{
|
|
|
- (void) lun;
|
|
|
- (void) power_condition;
|
|
|
- ESP_LOGI(TAG, "tud_msc_start_stop_cb() invoked, power_condition=%d, start=%d, load_eject=%d", power_condition, start, load_eject);
|
|
|
-
|
|
|
- if (load_eject && !start) {
|
|
|
- is_eject = true;
|
|
|
- ESP_LOGI(TAG, "tud_msc_start_stop_cb: MSC EJECT: Mount on Example");
|
|
|
- _mount();
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when received SCSI READ10 command
|
|
|
-// - Address = lba * BLOCK_SIZE + offset
|
|
|
-// - Application fill the buffer (up to bufsize) with address contents and return number of read byte.
|
|
|
-int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
|
|
|
-{
|
|
|
- ESP_LOGD(TAG, "tud_msc_read10_cb() invoked, lun=%d, lba=%lu, offset=%lu, bufsize=%lu", lun, lba, offset, bufsize);
|
|
|
-
|
|
|
- esp_err_t err = storage_read_sector(lba, offset, bufsize, buffer);
|
|
|
- if (err != ESP_OK) {
|
|
|
- ESP_LOGE(TAG, "storage_read_sector failed: 0x%x", err);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return bufsize;
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when received SCSI WRITE10 command
|
|
|
-// - Address = lba * BLOCK_SIZE + offset
|
|
|
-// - Application write data from buffer to address contents (up to bufsize) and return number of written byte.
|
|
|
-int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
|
|
|
-{
|
|
|
- ESP_LOGD(TAG, "tud_msc_write10_cb() invoked, lun=%d, lba=%lu, offset=%lu, bufsize=%lu", lun, lba, offset, bufsize);
|
|
|
-
|
|
|
- esp_err_t err = storage_write_sector(lba, offset, bufsize, buffer);
|
|
|
- if (err != ESP_OK) {
|
|
|
- ESP_LOGE(TAG, "storage_write_sector failed: 0x%x", err);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return bufsize;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Invoked when received an SCSI command not in built-in list below.
|
|
|
- * - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
|
|
|
- * - READ10 and WRITE10 has their own callbacks
|
|
|
- *
|
|
|
- * \param[in] lun Logical unit number
|
|
|
- * \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
|
|
|
- * \param[out] buffer Buffer for SCSI Data Stage.
|
|
|
- * - For INPUT: application must fill this with response.
|
|
|
- * - For OUTPUT it holds the Data from host
|
|
|
- * \param[in] bufsize Buffer's length.
|
|
|
- *
|
|
|
- * \return Actual bytes processed, can be zero for no-data command.
|
|
|
- * \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
|
|
|
- * endpoint and return failed status in command status wrapper phase.
|
|
|
- */
|
|
|
-int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize)
|
|
|
-{
|
|
|
- int32_t ret;
|
|
|
-
|
|
|
- ESP_LOGD(TAG, "tud_msc_scsi_cb() invoked. bufsize=%d", bufsize);
|
|
|
-
|
|
|
- switch (scsi_cmd[0]) {
|
|
|
- case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
|
|
- /* SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL is the Prevent/Allow Medium Removal
|
|
|
- command (1Eh) that requests the library to enable or disable user access to
|
|
|
- the storage media/partition. */
|
|
|
- ESP_LOGI(TAG, "tud_msc_scsi_cb() invoked: SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL");
|
|
|
- ret = 0;
|
|
|
- break;
|
|
|
- default:
|
|
|
- ESP_LOGW(TAG, "tud_msc_scsi_cb() invoked: %d", scsi_cmd[0]);
|
|
|
- tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_CODE_ASC_INVALID_COMMAND_OPERATION_CODE, SCSI_CODE_ASCQ);
|
|
|
- ret = -1;
|
|
|
- break;
|
|
|
- }
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when device is unmounted
|
|
|
-void tud_umount_cb(void)
|
|
|
-{
|
|
|
- is_eject = true;
|
|
|
- ESP_LOGI(TAG, "tud_umount_cb: Mount on Example");
|
|
|
- _mount();
|
|
|
-}
|
|
|
-
|
|
|
-// Invoked when device is mounted (configured)
|
|
|
-void tud_mount_cb(void)
|
|
|
-{
|
|
|
- ESP_LOGI(TAG, "tud_mount_cb MSC START: Expose Over USB");
|
|
|
- _unmount();
|
|
|
-}
|
|
|
-/*********************************************************************** TinyUSB MSC callbacks*/
|
|
|
-
|
|
|
-/* Application Code
|
|
|
- ********************************************************************* */
|
|
|
-
|
|
|
/* TinyUSB descriptors
|
|
|
********************************************************************* */
|
|
|
#define EPNUM_MSC 1
|
|
|
@@ -239,53 +77,51 @@ static char const *string_desc_arr[] = {
|
|
|
};
|
|
|
/*********************************************************************** TinyUSB descriptors*/
|
|
|
|
|
|
-#define VBUS_MONITORING_GPIO_NUM GPIO_NUM_4
|
|
|
#define BASE_PATH "/data" // base path to mount the partition
|
|
|
-static bool is_mount = false;
|
|
|
|
|
|
#define PROMPT_STR CONFIG_IDF_TARGET
|
|
|
-static int f_unmount(int argc, char **argv);
|
|
|
-static int f_read(int argc, char **argv);
|
|
|
-static int f_write(int argc, char **argv);
|
|
|
-static int f_size(int argc, char **argv);
|
|
|
-static int f_status(int argc, char **argv);
|
|
|
-static int f_exit(int argc, char **argv);
|
|
|
+static int console_unmount(int argc, char **argv);
|
|
|
+static int console_read(int argc, char **argv);
|
|
|
+static int console_write(int argc, char **argv);
|
|
|
+static int console_size(int argc, char **argv);
|
|
|
+static int console_status(int argc, char **argv);
|
|
|
+static int console_exit(int argc, char **argv);
|
|
|
const esp_console_cmd_t cmds[] = {
|
|
|
{
|
|
|
.command = "read",
|
|
|
.help = "read BASE_PATH/README.MD and print its contents",
|
|
|
.hint = NULL,
|
|
|
- .func = &f_read,
|
|
|
+ .func = &console_read,
|
|
|
},
|
|
|
{
|
|
|
.command = "write",
|
|
|
.help = "create file BASE_PATH/README.MD if it does not exist",
|
|
|
.hint = NULL,
|
|
|
- .func = &f_write,
|
|
|
+ .func = &console_write,
|
|
|
},
|
|
|
{
|
|
|
.command = "size",
|
|
|
.help = "show storage size and sector size",
|
|
|
.hint = NULL,
|
|
|
- .func = &f_size,
|
|
|
+ .func = &console_size,
|
|
|
},
|
|
|
{
|
|
|
.command = "expose",
|
|
|
.help = "Expose Storage to Host",
|
|
|
.hint = NULL,
|
|
|
- .func = &f_unmount,
|
|
|
+ .func = &console_unmount,
|
|
|
},
|
|
|
{
|
|
|
.command = "status",
|
|
|
.help = "Status of storage exposure over USB",
|
|
|
.hint = NULL,
|
|
|
- .func = &f_status,
|
|
|
+ .func = &console_status,
|
|
|
},
|
|
|
{
|
|
|
.command = "exit",
|
|
|
.help = "exit from application",
|
|
|
.hint = NULL,
|
|
|
- .func = &f_exit,
|
|
|
+ .func = &console_exit,
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -293,10 +129,8 @@ const esp_console_cmd_t cmds[] = {
|
|
|
static void _mount(void)
|
|
|
{
|
|
|
ESP_LOGI(TAG, "Mount storage...");
|
|
|
- if (!is_mount) {
|
|
|
- ESP_ERROR_CHECK(storage_mount(BASE_PATH));
|
|
|
- is_mount = true;
|
|
|
- }
|
|
|
+ ESP_ERROR_CHECK(tinyusb_msc_storage_mount(BASE_PATH));
|
|
|
+
|
|
|
|
|
|
// List all the files in this directory
|
|
|
ESP_LOGI(TAG, "\nls command output:");
|
|
|
@@ -319,29 +153,22 @@ static void _mount(void)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-// unmount the partition
|
|
|
-static void _unmount(void)
|
|
|
+// unmount storage
|
|
|
+static int console_unmount(int argc, char **argv)
|
|
|
{
|
|
|
- if (!is_mount) {
|
|
|
- ESP_LOGD(TAG, "storage exposed over USB...");
|
|
|
- return;
|
|
|
+ if (tinyusb_msc_storage_in_use_by_usb_host()) {
|
|
|
+ ESP_LOGE(TAG, "storage is already exposed");
|
|
|
+ return -1;
|
|
|
}
|
|
|
ESP_LOGI(TAG, "Unmount storage...");
|
|
|
- ESP_ERROR_CHECK(storage_unmount());
|
|
|
- is_mount = false;
|
|
|
- is_eject = false;
|
|
|
-}
|
|
|
-
|
|
|
-static int f_unmount(int argc, char **argv)
|
|
|
-{
|
|
|
- _unmount();
|
|
|
+ ESP_ERROR_CHECK(tinyusb_msc_storage_unmount());
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// read BASE_PATH/README.MD and print its contents
|
|
|
-static int f_read(int argc, char **argv)
|
|
|
+static int console_read(int argc, char **argv)
|
|
|
{
|
|
|
- if (!is_mount) {
|
|
|
+ if (tinyusb_msc_storage_in_use_by_usb_host()) {
|
|
|
ESP_LOGE(TAG, "storage exposed over USB. Application can't read from storage.");
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -361,9 +188,9 @@ static int f_read(int argc, char **argv)
|
|
|
}
|
|
|
|
|
|
// create file BASE_PATH/README.MD if it does not exist
|
|
|
-static int f_write(int argc, char **argv)
|
|
|
+static int console_write(int argc, char **argv)
|
|
|
{
|
|
|
- if (!is_mount) {
|
|
|
+ if (tinyusb_msc_storage_in_use_by_usb_host()) {
|
|
|
ESP_LOGE(TAG, "storage exposed over USB. Application can't write to storage.");
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -382,56 +209,55 @@ static int f_write(int argc, char **argv)
|
|
|
}
|
|
|
|
|
|
// Show storage size and sector size
|
|
|
-static int f_size(int argc, char **argv)
|
|
|
+static int console_size(int argc, char **argv)
|
|
|
{
|
|
|
- if (!is_mount) {
|
|
|
+ if (tinyusb_msc_storage_in_use_by_usb_host()) {
|
|
|
ESP_LOGE(TAG, "storage exposed over USB. Application can't access storage");
|
|
|
return -1;
|
|
|
}
|
|
|
- uint32_t sec_count = storage_get_sector_count();
|
|
|
- uint32_t sec_size = storage_get_sector_size();
|
|
|
+ uint32_t sec_count = tinyusb_msc_storage_get_sector_count();
|
|
|
+ uint32_t sec_size = tinyusb_msc_storage_get_sector_size();
|
|
|
printf("Storage Capacity %lluMB\n", ((uint64_t) sec_count) * sec_size / (1024 * 1024));
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// exit from application
|
|
|
-static int f_status(int argc, char **argv)
|
|
|
+static int console_status(int argc, char **argv)
|
|
|
{
|
|
|
- printf("storage exposed over USB: %s\n", is_mount ? "No" : "Yes");
|
|
|
+ printf("storage exposed over USB: %s\n", tinyusb_msc_storage_in_use_by_usb_host() ? "Yes" : "No");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// exit from application
|
|
|
-static int f_exit(int argc, char **argv)
|
|
|
+static int console_exit(int argc, char **argv)
|
|
|
{
|
|
|
+ tinyusb_msc_storage_deinit();
|
|
|
printf("Application Exiting\n");
|
|
|
exit(0);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-void app_main(void)
|
|
|
+#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
+static esp_err_t storage_init_spiflash(wl_handle_t *wl_handle)
|
|
|
{
|
|
|
- // Configure GPIO Pin for vbus monitoring
|
|
|
- const gpio_config_t vbus_gpio_config = {
|
|
|
- .pin_bit_mask = BIT64(VBUS_MONITORING_GPIO_NUM),
|
|
|
- .mode = GPIO_MODE_INPUT,
|
|
|
- .intr_type = GPIO_INTR_DISABLE,
|
|
|
- .pull_up_en = true,
|
|
|
- .pull_down_en = false,
|
|
|
- };
|
|
|
- ESP_ERROR_CHECK(gpio_config(&vbus_gpio_config));
|
|
|
+ ESP_LOGI(TAG, "Initializing wear levelling");
|
|
|
|
|
|
- ESP_LOGI(TAG, "Initializing storage...");
|
|
|
- tinyusb_config_storage_t storage_config;
|
|
|
+ const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL);
|
|
|
+ if (data_partition == NULL) {
|
|
|
+ ESP_LOGE(TAG, "Failed to find FATFS partition. Check the partition table.");
|
|
|
+ return ESP_ERR_NOT_FOUND;
|
|
|
+ }
|
|
|
|
|
|
-#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
- // configuration is to defined in case of SPI Flash
|
|
|
- storage_config.storage_type = TINYUSB_STORAGE_SPI;
|
|
|
- tinyusb_config_spiffs_t config_spi;
|
|
|
- storage_config.spiffs_config = &config_spi;
|
|
|
-#else // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
- storage_config.storage_type = TINYUSB_STORAGE_SDMMC;
|
|
|
- tinyusb_config_sdmmc_t config_sdmmc;
|
|
|
+ return wl_mount(data_partition, wl_handle);
|
|
|
+}
|
|
|
+#else // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
+static esp_err_t storage_init_sdmmc(sdmmc_card_t **card)
|
|
|
+{
|
|
|
+ esp_err_t ret = ESP_OK;
|
|
|
+ bool host_init = false;
|
|
|
+ sdmmc_card_t *sd_card;
|
|
|
+
|
|
|
+ ESP_LOGI(TAG, "Initializing SDCard");
|
|
|
|
|
|
// By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz)
|
|
|
// For setting a specific frequency, use host.max_freq_khz (range 400kHz - 40MHz for SDMMC)
|
|
|
@@ -467,13 +293,64 @@ void app_main(void)
|
|
|
// connected on the bus. This is for debug / example purpose only.
|
|
|
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
|
|
|
|
|
- config_sdmmc.host = host;
|
|
|
- config_sdmmc.slot_config = slot_config;
|
|
|
- storage_config.sdmmc_config = &config_sdmmc;
|
|
|
+ // not using ff_memalloc here, as allocation in internal RAM is preferred
|
|
|
+ sd_card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t));
|
|
|
+ ESP_GOTO_ON_FALSE(sd_card, ESP_ERR_NO_MEM, clean, TAG, "could not allocate new sdmmc_card_t");
|
|
|
+
|
|
|
+ ESP_GOTO_ON_ERROR((*host.init)(), clean, TAG, "Host Config Init fail");
|
|
|
+ host_init = true;
|
|
|
|
|
|
+ ESP_GOTO_ON_ERROR(sdmmc_host_init_slot(host.slot, (const sdmmc_slot_config_t *) &slot_config),
|
|
|
+ clean, TAG, "Host init slot fail");
|
|
|
+
|
|
|
+ while (sdmmc_card_init(&host, sd_card)) {
|
|
|
+ ESP_LOGE(TAG, "The detection pin of the slot is disconnected(Insert uSD card). Retrying...");
|
|
|
+ vTaskDelay(pdMS_TO_TICKS(3000));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Card has been initialized, print its properties
|
|
|
+ sdmmc_card_print_info(stdout, sd_card);
|
|
|
+ *card = sd_card;
|
|
|
+
|
|
|
+ return ESP_OK;
|
|
|
+
|
|
|
+clean:
|
|
|
+ if (host_init) {
|
|
|
+ if (host.flags & SDMMC_HOST_FLAG_DEINIT_ARG) {
|
|
|
+ host.deinit_p(host.slot);
|
|
|
+ } else {
|
|
|
+ (*host.deinit)();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (sd_card) {
|
|
|
+ free(sd_card);
|
|
|
+ sd_card = NULL;
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
#endif // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
|
|
|
- ESP_ERROR_CHECK(storage_init(&storage_config));
|
|
|
+void app_main(void)
|
|
|
+{
|
|
|
+ ESP_LOGI(TAG, "Initializing storage...");
|
|
|
+
|
|
|
+#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
+ static wl_handle_t wl_handle = WL_INVALID_HANDLE;
|
|
|
+ ESP_ERROR_CHECK(storage_init_spiflash(&wl_handle));
|
|
|
+
|
|
|
+ const tinyusb_msc_spiflash_config_t config_spi = {
|
|
|
+ .wl_handle = wl_handle
|
|
|
+ };
|
|
|
+ ESP_ERROR_CHECK(tinyusb_msc_storage_init_spiflash(&config_spi));
|
|
|
+#else // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
+ static sdmmc_card_t *card = NULL;
|
|
|
+ ESP_ERROR_CHECK(storage_init_sdmmc(&card));
|
|
|
+
|
|
|
+ const tinyusb_msc_sdmmc_config_t config_sdmmc = {
|
|
|
+ .card = card
|
|
|
+ };
|
|
|
+ ESP_ERROR_CHECK(tinyusb_msc_storage_init_sdmmc(&config_sdmmc));
|
|
|
+#endif // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH
|
|
|
|
|
|
//mounted in the app by default
|
|
|
_mount();
|
|
|
@@ -485,8 +362,6 @@ void app_main(void)
|
|
|
.string_descriptor_count = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]),
|
|
|
.external_phy = false,
|
|
|
.configuration_descriptor = desc_configuration,
|
|
|
- .self_powered = true,
|
|
|
- .vbus_monitor_io = VBUS_MONITORING_GPIO_NUM,
|
|
|
};
|
|
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
|
|
ESP_LOGI(TAG, "USB MSC initialization DONE");
|
|
|
@@ -506,4 +381,3 @@ void app_main(void)
|
|
|
}
|
|
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
|
|
}
|
|
|
-/*********************************************************************** Application Code*/
|