1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <wchar.h>
10 #include <stdint.h>
11 #include "esp_err.h"
12 #include <freertos/FreeRTOS.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 #define ESP_ERR_MSC_HOST_BASE        0x1700                      /*!< MSC host error code base */
19 #define ESP_ERR_MSC_MOUNT_FAILED    (ESP_ERR_MSC_HOST_BASE + 1)  /*!< Failed to mount storage */
20 #define ESP_ERR_MSC_FORMAT_FAILED   (ESP_ERR_MSC_HOST_BASE + 2)  /*!< Failed to format storage */
21 #define ESP_ERR_MSC_INTERNAL        (ESP_ERR_MSC_HOST_BASE + 3)  /*!< MSC host internal error */
22 
23 #define MSC_STR_DESC_SIZE 32
24 
25 typedef struct msc_host_device *msc_host_device_handle_t;     /**< Handle to a Mass Storage Device */
26 
27 /**
28  * @brief USB Mass Storage event containing event type and associated device handle.
29 */
30 typedef struct {
31     enum {
32         MSC_DEVICE_CONNECTED,       /**< MSC device has been connected to the system.*/
33         MSC_DEVICE_DISCONNECTED,    /**< MSC device has been disconnected from the system.*/
34     } event;
35     union {
36         uint8_t address;                /**< Address of connected MSC device.*/
37         msc_host_device_handle_t handle; /**< MSC device handle to disconnected device.*/
38     } device;
39 } msc_host_event_t;
40 
41 /**
42  * @brief USB Mass Storage event callback.
43  *
44  * @param[in] event mass storage event
45 */
46 typedef void (*msc_host_event_cb_t)(const msc_host_event_t *event, void *arg);
47 
48 /**
49  * @brief MSC configuration structure.
50 */
51 typedef struct {
52     bool create_backround_task;     /**< When set to true, background task handling usb events is created.
53                                          Otherwise user has to periodically call msc_host_handle_events function */
54     size_t task_priority;           /**< Task priority of crated background task */
55     size_t stack_size;              /**< Stack size of crated background task */
56     BaseType_t core_id;             /**< Select core on which background task will run or tskNO_AFFINITY  */
57     msc_host_event_cb_t callback;   /**< Callback invoked when MSC event occurs. Must not be NULL. */
58     void *callback_arg;             /**< User provided argument passed to callback */
59 } msc_host_driver_config_t;
60 
61 /**
62  * @brief MSC device info.
63 */
64 typedef struct {
65     uint32_t sector_count;
66     uint32_t sector_size;
67     uint16_t idProduct;
68     uint16_t idVendor;
69     wchar_t iManufacturer[MSC_STR_DESC_SIZE];
70     wchar_t iProduct[MSC_STR_DESC_SIZE];
71     wchar_t iSerialNumber[MSC_STR_DESC_SIZE];
72 } msc_host_device_info_t;
73 
74 /**
75  * @brief Install USB Host Mass Storage Class driver
76  *
77  * @param[in] config configuration structure MSC to create
78  * @return esp_err_r
79  */
80 esp_err_t msc_host_install(const msc_host_driver_config_t *config);
81 
82 /**
83  * @brief Uninstall Mass Storage Class driver
84  * @return esp_err_t
85  */
86 esp_err_t msc_host_uninstall(void);
87 
88 /**
89  * @brief Initialization of MSC device.
90  *
91  * @param[in]  device_address  Device address obtained from MSC callback provided upon connection and enumeration
92  * @param[out] device          Mass storage device handle to be used for subsequent calls.
93  * @return esp_err_t
94  */
95 esp_err_t msc_host_install_device(uint8_t device_address, msc_host_device_handle_t *device);
96 
97 /**
98  * @brief Deinitialization of MSC device.
99  *
100  * @param[in]  device  Device handle obtained from msc_host_install_device function
101  * @return esp_err_t
102  */
103 esp_err_t msc_host_uninstall_device(msc_host_device_handle_t device);
104 
105 /**
106  * @brief Helper function for reading sector from mass storage device.
107  *
108  * @warning This call is not thread safe and should not be combined
109  *          with accesses to storage through file system.
110  *
111  * @note  Provided sector and size cannot exceed
112  *        sector_count and sector_size obtained from msc_host_device_info_t
113  *
114  * @param[in]  device Device handle
115  * @param[in]  sector Number of sector to be read
116  * @param[out] data   Buffer into which data will be written
117  * @param[in]  size   Number of bytes to be read
118  * @return esp_err_t
119  */
120 esp_err_t msc_host_read_sector(msc_host_device_handle_t device, size_t sector, void *data, size_t size);
121 
122 /**
123  * @brief Helper function for writing sector to mass storage device.
124  *
125  * @warning This call is not thread safe and should not be combined
126  *          with accesses to storare through file system.
127  *
128  * @note  Provided sector and size cannot exceed
129  *        sector_count and sector_size obtained from msc_host_device_info_t
130  *
131  * @param[in]  device Device handle
132  * @param[in]  sector Number of sector to be read
133  * @param[in]  data   Data to be written to the sector
134  * @param[in]  size   Number of bytes to be written
135  * @return esp_err_t
136  */
137 esp_err_t msc_host_write_sector(msc_host_device_handle_t device, size_t sector, const void *data, size_t size);
138 
139 /**
140  * @brief Handle MSC HOST events.
141  *
142  * @param[in]  timeout_ms  Timeout in miliseconds
143  * @return esp_err_t
144  */
145 esp_err_t msc_host_handle_events(uint32_t timeout_ms);
146 
147 /**
148  * @brief Gets devices information.
149  *
150  * @warning This call is not thread safe and should not be combined
151  *          with accesses to storare through file system.
152  *
153  * @param[in]  device  Handle to device
154  * @param[out] info  Structure to be populated with device info
155  * @return esp_err_t
156  */
157 esp_err_t msc_host_get_device_info(msc_host_device_handle_t device, msc_host_device_info_t *info);
158 
159 /**
160  * @brief Print configuration descriptor.
161  *
162  * @param[in]  device  Handle of MSC device
163  * @return esp_err_t
164  */
165 esp_err_t msc_host_print_descriptors(msc_host_device_handle_t device);
166 
167 #ifdef __cplusplus
168 }
169 #endif //__cplusplus
170