re-enabling serial
[clinton/Smoothieware.git] / gcc4mbed / samples / MSTest / USBDevice / USBMSD / USBMSD.h
CommitLineData
cd011f58
AW
1/* Copyright (c) 2010-2011 mbed.org, MIT License\r
2*\r
3* Permission is hereby granted, free of charge, to any person obtaining a copy of this software\r
4* and associated documentation files (the "Software"), to deal in the Software without\r
5* restriction, including without limitation the rights to use, copy, modify, merge, publish,\r
6* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the\r
7* Software is furnished to do so, subject to the following conditions:\r
8*\r
9* The above copyright notice and this permission notice shall be included in all copies or\r
10* substantial portions of the Software.\r
11*\r
12* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\r
13* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
14* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r
15* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
16* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
17*/\r
18\r
19\r
20#ifndef USBMSD_H\r
21#define USBMSD_H\r
22\r
23/* These headers are included for child class. */\r
24#include "USBEndpoints.h"\r
25#include "USBDescriptor.h"\r
26#include "USBDevice_Types.h"\r
27\r
28#include "USBDevice.h"\r
29\r
30#ifdef __GNUC__\r
31 /* Packing for structs in GCC. */\r
32 #define PACK_STRUCT_STRUCT __attribute__((packed))\r
33 #define PACK_STRUCT_BEGIN\r
34 #define PACK_STRUCT_END\r
35#else /* !__GNUC__ */\r
36 /* Packing for structs in ARM compiler. */\r
37 #define PACK_STRUCT_STRUCT\r
38 #define PACK_STRUCT_BEGIN __packed\r
39 #define PACK_STRUCT_END\r
40#endif /* __GNUC__ */\r
41\r
42/**\r
43 * USBMSD class: generic class in order to use all kinds of blocks storage chip\r
44 *\r
45 * Introduction\r
46 *\r
47 * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)\r
48 * from a computer over USB. But this class doesn't work standalone, you need to subclass this class\r
49 * and define virtual functions which are called in USBMSD.\r
50 *\r
51 * How to use this class with your chip ?\r
52 *\r
53 * You have to inherit and define some pure virtual functions (mandatory step):\r
54 * - virtual int disk_read(char * data, int block): function to read a block\r
55 * - virtual int disk_write(const char * data, int block): function to write a block\r
56 * - virtual int disk_initialize(): function to initialize the memory\r
57 * - virtual int disk_sectors(): return the number of blocks\r
58 * - virtual int disk_size(): return the memory size\r
59 * - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)\r
60 *\r
61 * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with\r
62 * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which\r
63 * will access the sd card. You can do a master/slave system using the disk_status method.\r
64 *\r
65 * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance)\r
66 * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk.\r
67 * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information\r
68 * such as the number of blocks and the memory size.\r
69 */\r
70class USBMSD: public USBDevice {\r
71public:\r
72\r
73 /**\r
74 * Constructor\r
75 *\r
76 * @param vendor_id Your vendor_id\r
77 * @param product_id Your product_id\r
78 * @param product_release Your preoduct_release\r
79 */\r
80 USBMSD(uint16_t vendor_id = 0x0703, uint16_t product_id = 0x0104, uint16_t product_release = 0x0001);\r
81\r
82 /**\r
83 * Connect the USB MSD device. Establish disk initialization before really connect the device.\r
84 *\r
85 * @returns true if successful\r
86 */\r
87 bool connect();\r
88\r
89\r
90protected:\r
91\r
92 /*\r
93 * read a block on a storage chip\r
94 *\r
95 * @param data pointer where will be stored read data\r
96 * @param block block number\r
97 * @returns 0 if successful\r
98 */\r
99 virtual int disk_read(char * data, int block) = 0;\r
100\r
101 /*\r
102 * write a block on a storage chip\r
103 *\r
104 * @param data data to write\r
105 * @param block block number\r
106 * @returns 0 if successful\r
107 */\r
108 virtual int disk_write(const char * data, int block) = 0;\r
109\r
110 /*\r
111 * Disk initilization\r
112 */\r
113 virtual int disk_initialize() = 0;\r
114\r
115 /*\r
116 * Return the number of blocks\r
117 *\r
118 * @returns number of blocks\r
119 */\r
120 virtual int disk_sectors() = 0;\r
121\r
122 /*\r
123 * Return memory size\r
124 *\r
125 * @returns memory size\r
126 */\r
127 virtual int disk_size() = 0;\r
128\r
129\r
130 /*\r
131 * To check the status of the storage chip\r
132 *\r
133 * @returns status: 0: OK, 1: disk not initialized, 2: no medium in the drive, 4: write protected\r
134 */\r
135 virtual int disk_status() = 0;\r
136\r
137 /*\r
138 * Get string product descriptor\r
139 *\r
140 * @returns pointer to the string product descriptor\r
141 */\r
142 virtual uint8_t * stringIproductDesc();\r
143\r
144 /*\r
145 * Get string interface descriptor\r
146 *\r
147 * @returns pointer to the string interface descriptor\r
148 */\r
149 virtual uint8_t * stringIinterfaceDesc();\r
150\r
151 /*\r
152 * Get configuration descriptor\r
153 *\r
154 * @returns pointer to the configuration descriptor\r
155 */\r
156 virtual uint8_t * configurationDesc();\r
157\r
158 /*\r
159 * Callback called when a packet is received\r
160 */\r
161 virtual bool EP2_OUT_callback();\r
162\r
163 /*\r
164 * Callback called when a packet has been sent\r
165 */\r
166 virtual bool EP2_IN_callback();\r
167\r
168 /*\r
169 * Set configuration of device. Add endpoints\r
170 */\r
171 virtual bool USBCallback_setConfiguration(uint8_t configuration);\r
172\r
173 /*\r
174 * Callback called to process class specific requests\r
175 */\r
176 virtual bool USBCallback_request();\r
177\r
178\r
179private:\r
180\r
181 // MSC Bulk-only Stage\r
182 enum Stage {\r
183 READ_CBW, // wait a CBW\r
184 ERROR, // error\r
185 PROCESS_CBW, // process a CBW request\r
186 SEND_CSW, // send a CSW\r
187 WAIT_CSW, // wait that a CSW has been effectively sent\r
188 };\r
189\r
190 // Bulk-only CBW\r
191 typedef PACK_STRUCT_BEGIN struct {\r
192 uint32_t Signature;\r
193 uint32_t Tag;\r
194 uint32_t DataLength;\r
195 uint8_t Flags;\r
196 uint8_t LUN;\r
197 uint8_t CBLength;\r
198 uint8_t CB[16];\r
199 } PACK_STRUCT_STRUCT CBW;\r
200\r
201 // Bulk-only CSW\r
202 typedef PACK_STRUCT_BEGIN struct {\r
203 uint32_t Signature;\r
204 uint32_t Tag;\r
205 uint32_t DataResidue;\r
206 uint8_t Status;\r
207 } PACK_STRUCT_STRUCT CSW;\r
208\r
209 //state of the bulk-only state machine\r
210 Stage stage;\r
211\r
212 // current CBW\r
213 CBW cbw;\r
214\r
215 // CSW which will be sent\r
216 CSW csw;\r
217\r
218 // addr where will be read or written data\r
219 uint32_t addr;\r
220\r
221 // length of a reading or writing\r
222 uint32_t length;\r
223\r
224 // memory OK (after a memoryVerify)\r
225 bool memOK;\r
226\r
227 // cache in RAM before writing in memory. Useful also to read a block.\r
228 uint8_t * page;\r
229\r
230 int BlockSize;\r
231 int MemorySize;\r
232 int BlockCount;\r
233\r
234 void CBWDecode(uint8_t * buf, uint16_t size);\r
235 void sendCSW (void);\r
236 bool inquiryRequest (void);\r
237 bool write (uint8_t * buf, uint16_t size);\r
238 bool readFormatCapacity();\r
239 bool readCapacity (void);\r
240 bool infoTransfer (void);\r
241 void memoryRead (void);\r
242 bool modeSense6 (void);\r
243 void testUnitReady (void);\r
244 bool requestSense (void);\r
245 void memoryVerify (uint8_t * buf, uint16_t size);\r
246 void memoryWrite (uint8_t * buf, uint16_t size);\r
247 void reset();\r
248 void fail();\r
249};\r
250\r
251#endif