Skip to content

Commit

Permalink
esp_tinyusb: add MSC pre mount/unmount changed event and callback (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
esp-saurabhbansal authored Jul 19, 2023
1 parent b383228 commit 10a1fdd
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 14 deletions.
2 changes: 1 addition & 1 deletion usb/esp_tinyusb/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
description: Espressif's additions to TinyUSB
documentation: "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_device.html"
version: 1.3.0
version: 1.3.1
url: https://github.com/espressif/idf-extra-components/tree/master/usb/esp_tinyusb
dependencies:
idf: '>=5.0' # IDF 4.x contains TinyUSB as submodule
Expand Down
27 changes: 18 additions & 9 deletions usb/esp_tinyusb/include/tusb_msc_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ extern "C" {
#endif

/**
* @brief Data provided to the input of the `callback_mount_changed` callback
* @brief Data provided to the input of the `callback_mount_changed` and `callback_premount_changed` callback
*/
typedef struct {
bool is_mounted;
bool is_mounted; /*!< Flag if storage is mounted or not */
} tinyusb_msc_event_mount_changed_data_t;

/**
* @brief Types of MSC events
*/
typedef enum {
TINYUSB_MSC_EVENT_MOUNT_CHANGED
TINYUSB_MSC_EVENT_MOUNT_CHANGED, /*!< Event type AFTER mount/unmount operation is successfully finished */
TINYUSB_MSC_EVENT_PREMOUNT_CHANGED /*!< Event type BEFORE mount/unmount operation is started */
} tinyusb_msc_event_type_t;

/**
Expand All @@ -37,12 +38,12 @@ typedef enum {
typedef struct {
tinyusb_msc_event_type_t type; /*!< Event type */
union {
tinyusb_msc_event_mount_changed_data_t mount_changed_data; /*!< Data input of the `callback_mount_changed` callback */
tinyusb_msc_event_mount_changed_data_t mount_changed_data; /*!< Data input of the callback */
};
} tinyusb_msc_event_t;

/**
* @brief MSC callback type
* @brief MSC callback that is delivered whenever a specific event occurs.
*/
typedef void(*tusb_msc_callback_t)(tinyusb_msc_event_t *event);

Expand All @@ -54,8 +55,9 @@ typedef void(*tusb_msc_callback_t)(tinyusb_msc_event_t *event);
* initializing the sdmmc media.
*/
typedef struct {
sdmmc_card_t *card;
tusb_msc_callback_t callback_mount_changed; /*!< Pointer to the function with the `tusb_msc_callback_t` type that will be handled as a callback */
sdmmc_card_t *card; /*!< Pointer to sdmmc card configuration structure */
tusb_msc_callback_t callback_mount_changed; /*!< Pointer to the function callback that will be delivered AFTER mount/unmount operation is successfully finished */
tusb_msc_callback_t callback_premount_changed; /*!< Pointer to the function callback that will be delivered BEFORE mount/unmount operation is started */
} tinyusb_msc_sdmmc_config_t;
#endif

Expand All @@ -66,8 +68,9 @@ typedef struct {
* initializing the SPI Flash media.
*/
typedef struct {
wl_handle_t wl_handle;
tusb_msc_callback_t callback_mount_changed; /*!< Pointer to the function with the `tusb_msc_callback_t` type that will be handled as a callback */
wl_handle_t wl_handle; /*!< Pointer to spiflash wera-levelling handle */
tusb_msc_callback_t callback_mount_changed; /*!< Pointer to the function callback that will be delivered AFTER mount/unmount operation is successfully finished */
tusb_msc_callback_t callback_premount_changed; /*!< Pointer to the function callback that will be delivered BEFORE mount/unmount operation is started */
} tinyusb_msc_spiflash_config_t;

/**
Expand Down Expand Up @@ -125,6 +128,9 @@ esp_err_t tinyusb_msc_unregister_callback(tinyusb_msc_event_type_t event_type);
* Mounts the partition.
* This API is used by the firmware application. If the storage partition is
* mounted by this API, host (PC) can't access the storage via MSC.
* When this function is called from the tinyusb callback functions, care must be taken
* so as to make sure that user callbacks must be completed within a
* specific time. Otherwise, MSC device may re-appear again on Host.
*
* @param base_path path prefix where FATFS should be registered
* @return esp_err_t
Expand All @@ -141,6 +147,9 @@ esp_err_t tinyusb_msc_storage_mount(const char *base_path);
* Unregister the SPI flash partition.
* Finally, Un-register FATFS from VFS.
* After this function is called, storage device can be seen (recognized) by host (PC).
* When this function is called from the tinyusb callback functions, care must be taken
* so as to make sure that user callbacks must be completed within a specific time.
* Otherwise, MSC device may not appear on Host.
*
* @return esp_err_t
* - ESP_OK on success
Expand Down
49 changes: 45 additions & 4 deletions usb/esp_tinyusb/tusb_msc_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef struct {
esp_err_t (*read)(size_t sector_size, uint32_t lba, uint32_t offset, size_t size, void *dest);
esp_err_t (*write)(size_t sector_size, size_t addr, uint32_t lba, uint32_t offset, size_t size, const void *src);
tusb_msc_callback_t callback_mount_changed;
tusb_msc_callback_t callback_premount_changed;
} tinyusb_msc_storage_handle_s; /*!< MSC object */

/* handle of tinyusb driver connected to application */
Expand Down Expand Up @@ -248,13 +249,24 @@ static esp_err_t _mount(char *drv, FATFS *fs)

esp_err_t tinyusb_msc_storage_mount(const char *base_path)
{
esp_err_t ret;
esp_err_t ret = ESP_OK;
assert(s_storage_handle);

if (s_storage_handle->is_fat_mounted) {
return ESP_OK;
}

tusb_msc_callback_t cb = s_storage_handle->callback_premount_changed;
if (cb) {
tinyusb_msc_event_t event = {
.type = TINYUSB_MSC_EVENT_PREMOUNT_CHANGED,
.mount_changed_data = {
.is_mounted = s_storage_handle->is_fat_mounted
}
};
cb(&event);
}

if (!base_path) {
base_path = CONFIG_TINYUSB_MSC_MOUNT_PATH;
}
Expand All @@ -281,7 +293,7 @@ esp_err_t tinyusb_msc_storage_mount(const char *base_path)
s_storage_handle->is_fat_mounted = true;
s_storage_handle->base_path = base_path;

tusb_msc_callback_t cb = s_storage_handle->callback_mount_changed;
cb = s_storage_handle->callback_mount_changed;
if (cb) {
tinyusb_msc_event_t event = {
.type = TINYUSB_MSC_EVENT_MOUNT_CHANGED,
Expand All @@ -292,7 +304,7 @@ esp_err_t tinyusb_msc_storage_mount(const char *base_path)
cb(&event);
}

return ESP_OK;
return ret;

fail:
if (fs) {
Expand All @@ -309,9 +321,22 @@ esp_err_t tinyusb_msc_storage_unmount(void)
if (!s_storage_handle) {
return ESP_FAIL;
}

if (!s_storage_handle->is_fat_mounted) {
return ESP_OK;
}

tusb_msc_callback_t cb = s_storage_handle->callback_premount_changed;
if (cb) {
tinyusb_msc_event_t event = {
.type = TINYUSB_MSC_EVENT_PREMOUNT_CHANGED,
.mount_changed_data = {
.is_mounted = s_storage_handle->is_fat_mounted
}
};
cb(&event);
}

esp_err_t err = (s_storage_handle->unmount)();
if (err) {
return err;
Expand All @@ -320,7 +345,7 @@ esp_err_t tinyusb_msc_storage_unmount(void)
s_storage_handle->base_path = NULL;
s_storage_handle->is_fat_mounted = false;

tusb_msc_callback_t cb = s_storage_handle->callback_mount_changed;
cb = s_storage_handle->callback_mount_changed;
if (cb) {
tinyusb_msc_event_t event = {
.type = TINYUSB_MSC_EVENT_MOUNT_CHANGED,
Expand Down Expand Up @@ -367,6 +392,11 @@ esp_err_t tinyusb_msc_storage_init_spiflash(const tinyusb_msc_spiflash_config_t
} else {
tinyusb_msc_unregister_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED);
}
if (config->callback_premount_changed) {
tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_PREMOUNT_CHANGED, config->callback_premount_changed);
} else {
tinyusb_msc_unregister_callback(TINYUSB_MSC_EVENT_PREMOUNT_CHANGED);
}

return ESP_OK;
}
Expand All @@ -393,6 +423,11 @@ esp_err_t tinyusb_msc_storage_init_sdmmc(const tinyusb_msc_sdmmc_config_t *confi
} else {
tinyusb_msc_unregister_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED);
}
if (config->callback_premount_changed) {
tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_PREMOUNT_CHANGED, config->callback_premount_changed);
} else {
tinyusb_msc_unregister_callback(TINYUSB_MSC_EVENT_PREMOUNT_CHANGED);
}

return ESP_OK;
}
Expand All @@ -413,6 +448,9 @@ esp_err_t tinyusb_msc_register_callback(tinyusb_msc_event_type_t event_type,
case TINYUSB_MSC_EVENT_MOUNT_CHANGED:
s_storage_handle->callback_mount_changed = callback;
return ESP_OK;
case TINYUSB_MSC_EVENT_PREMOUNT_CHANGED:
s_storage_handle->callback_premount_changed = callback;
return ESP_OK;
default:
ESP_LOGE(TAG, "Wrong event type");
return ESP_ERR_INVALID_ARG;
Expand All @@ -426,6 +464,9 @@ esp_err_t tinyusb_msc_unregister_callback(tinyusb_msc_event_type_t event_type)
case TINYUSB_MSC_EVENT_MOUNT_CHANGED:
s_storage_handle->callback_mount_changed = NULL;
return ESP_OK;
case TINYUSB_MSC_EVENT_PREMOUNT_CHANGED:
s_storage_handle->callback_premount_changed = NULL;
return ESP_OK;
default:
ESP_LOGE(TAG, "Wrong event type");
return ESP_ERR_INVALID_ARG;
Expand Down

0 comments on commit 10a1fdd

Please sign in to comment.