forked from sam0737/chibios-rt-usb-msd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
usb_msd.h
247 lines (212 loc) · 5.99 KB
/
usb_msd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/**
* @brief USB mass storage driver and functions
* @file usb_msd.h
*/
#ifndef _USB_MSD_H_
#define _USB_MSD_H_
#include "ch.h"
#include "hal.h"
#define PACK_STRUCT_FIELD(x) x __attribute__((packed))
#define PACK_STRUCT_STRUCT __attribute__((packed))
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
/**
* @brief Command Block Wrapper structure
*/
typedef struct {
uint32_t signature;
uint32_t tag;
uint32_t data_len;
uint8_t flags;
uint8_t lun;
uint8_t scsi_cmd_len;
uint8_t scsi_cmd_data[16];
} PACK_STRUCT_STRUCT msd_cbw_t;
/**
* @brief Command Status Wrapper structure
*/
typedef struct {
uint32_t signature;
uint32_t tag;
uint32_t data_residue;
uint8_t status;
} PACK_STRUCT_STRUCT msd_csw_t;
/**
* @brief Structure holding sense data (status/error information)
*/
typedef struct {
uint8_t byte[18];
} PACK_STRUCT_STRUCT msd_scsi_sense_response_t PACK_STRUCT_END;
/**
* @brief structure holding the data to reply to an INQUIRY SCSI command
*/
PACK_STRUCT_BEGIN typedef struct
{
uint8_t peripheral;
uint8_t removable;
uint8_t version;
uint8_t response_data_format;
uint8_t additional_length;
uint8_t sccstp;
uint8_t bqueetc;
uint8_t cmdque;
uint8_t vendor_id[8];
uint8_t product_id[16];
uint8_t product_rev[4];
} PACK_STRUCT_STRUCT msd_scsi_inquiry_response_t PACK_STRUCT_END;
/**
* @brief Possible states for the USB mass storage driver
*/
typedef enum {
MSD_IDLE = 0x01,
MSD_READ_COMMAND_BLOCK = 0x10,
MSD_RESET = 0xff
} msd_state_t;
/**
* @brief Driver configuration structure
*/
typedef struct {
/**
* @brief USB driver to use for communication
*/
USBDriver *usbp;
/**
* @brief Control interface number
* @note Only used in composite USB device.
* Default is 0 which is good for single device.
*/
uint8_t control_interface;
/**
* @brief Bulk out endpoint number
*/
uint8_t bulk_out_ep;
/**
* @brief Bulk in endpoint number
*/
uint8_t bulk_in_ep;
/**
* @brief Optional callback that will be called whenever there is
* read/write activity
* @note The callback is called with argument TRUE when activity starts,
* and FALSE when activity stops.
*/
void (*rw_activity_callback)(bool_t);
/**
* @brief Short vendor identification
* @note ASCII characters only, maximum 8 characters (pad with zeroes).
*/
uint8_t short_vendor_id[8];
/**
* @brief Short product identification
* @note ASCII characters only, maximum 16 characters (pad with zeroes).
*/
uint8_t short_product_id[16];
/**
* @brief Short product revision
* @note ASCII characters only, maximum 4 characters (pad with zeroes).
*/
uint8_t short_product_version[4];
} USBMassStorageConfig;
/**
* @brief USB mass storage driver structure.
* @details This structure holds all the states and members of a USB mass
* storage driver.
*/
typedef struct USBMassStorageDriver USBMassStorageDriver;
struct USBMassStorageDriver {
const USBMassStorageConfig* config;
binary_semaphore_t bsem_received;
binary_semaphore_t bsem_transmitted;
thread_t* thread;
event_source_t evt_ejected;
/**
* @brief Block device to use for storage
*/
BaseBlockDevice *bbdp;
bool eject_requested;
BlockDeviceInfo block_dev_info;
msd_state_t state;
msd_cbw_t cbw;
msd_csw_t csw;
msd_scsi_sense_response_t sense;
msd_scsi_inquiry_response_t inquiry;
/* Linked list to the next serial USB driver */
USBMassStorageDriver *driver_next;
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes a USB mass storage driver.
*/
void msdObjectInit(USBMassStorageDriver *msdp);
/**
* @brief Starts a USB mass storage driver.
* @details This function is sufficient to have USB mass storage running, it internally
* runs a thread that handles USB requests and transfers.
*/
void msdStart(USBMassStorageDriver *msdp, const USBMassStorageConfig *config);
/**
* @brief Stops a USB mass storage driver.
* @details This function waits for current tasks to be finished, if any, and then
* stops the mass storage thread.
*/
void msdStop(USBMassStorageDriver *msdp);
/**
* @brief Set the device as ready, notify the host that media is inserted
* @details The block device must be connected before calling.
*/
void msdReady(USBMassStorageDriver *msdp, BaseBlockDevice *bbdp);
/**
* @brief Request to eject the media
* @details If transfer is in progress, eject will be done gracefully.
* The ejected event will be notified.
*/
void msdEject(USBMassStorageDriver *msdp);
/**
* @brief USB device configured handler.
* @details This should be called when USB_EVENT_CONFIGURED occurs
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @iclass
*/
void msdConfigureHookI(USBDriver *usbp);
/**
* @brief USB device suspend handler.
* @details This should be called when USB_EVENT_SUSPEND occurs
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @iclass
*/
void msdSuspendHookI(USBDriver *usbp);
/**
* @brief Default requests hook.
* @details Applications wanting to use the Mass Storage over USB driver can use
* this function as requests hook in the USB configuration.
* The following requests are emulated:
* - MSD_REQ_RESET.
* - MSD_GET_MAX_LUN.
*
*
* @param[in] usbp pointer to the @p USBDriver object
* @return The hook status.
* @retval TRUE Message handled internally.
* @retval FALSE Message not handled.
*/
bool msdRequestsHook(USBDriver *usbp);
/**
* @brief USB endpoint data handler.
* @details Hook the Bulk-IN and Bulk-OUT endpoint callback to here
*/
void msdUsbEventIn(USBDriver *usbp, usbep_t ep);
void msdUsbEventOut(USBDriver *usbp, usbep_t ep);
static int counter_tmp_OUT;
int GetCounterOut();
static int counter_tmp_IN;
int GetCounterIn();
#ifdef __cplusplus
}
#endif
#endif /* _USB_MSD_H_ */