USB CDC (serial) and USB MSC (strage) Composite Device. http://mbed.org/users/okini3939/notebook/USB_Device/

Dependencies:   ChaNFSSD mbed ChaNFS

Committer:
okini3939
Date:
Fri Dec 23 16:37:58 2011 +0000
Revision:
2:5db90410bb90
Parent:
1:bb08a84162b7

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 1:bb08a84162b7 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
okini3939 1:bb08a84162b7 2 *
okini3939 1:bb08a84162b7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
okini3939 1:bb08a84162b7 4 * and associated documentation files (the "Software"), to deal in the Software without
okini3939 1:bb08a84162b7 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
okini3939 1:bb08a84162b7 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
okini3939 1:bb08a84162b7 7 * Software is furnished to do so, subject to the following conditions:
okini3939 1:bb08a84162b7 8 *
okini3939 1:bb08a84162b7 9 * The above copyright notice and this permission notice shall be included in all copies or
okini3939 1:bb08a84162b7 10 * substantial portions of the Software.
okini3939 1:bb08a84162b7 11 *
okini3939 1:bb08a84162b7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
okini3939 1:bb08a84162b7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
okini3939 1:bb08a84162b7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
okini3939 1:bb08a84162b7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
okini3939 1:bb08a84162b7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
okini3939 1:bb08a84162b7 17 */
okini3939 1:bb08a84162b7 18
okini3939 1:bb08a84162b7 19 #ifndef USBCDCMSC_H
okini3939 1:bb08a84162b7 20 #define USBCDCMSC_H
okini3939 1:bb08a84162b7 21
okini3939 1:bb08a84162b7 22 /* These headers are included for child class. */
okini3939 1:bb08a84162b7 23 #include "USBEndpoints.h"
okini3939 1:bb08a84162b7 24 #include "USBDescriptor.h"
okini3939 1:bb08a84162b7 25 #include "USBDevice_Types.h"
okini3939 1:bb08a84162b7 26
okini3939 1:bb08a84162b7 27 #include "USBDevice.h"
okini3939 1:bb08a84162b7 28
okini3939 1:bb08a84162b7 29 #include "Stream.h"
okini3939 1:bb08a84162b7 30 #include "CircBuffer.h"
okini3939 1:bb08a84162b7 31
okini3939 1:bb08a84162b7 32 #include "SDFileSystem.h"
okini3939 1:bb08a84162b7 33
okini3939 1:bb08a84162b7 34
okini3939 1:bb08a84162b7 35 class USBCDCMSC: public USBDevice, public Stream {
okini3939 1:bb08a84162b7 36 public:
okini3939 1:bb08a84162b7 37
okini3939 1:bb08a84162b7 38 /*
okini3939 1:bb08a84162b7 39 * Constructor
okini3939 1:bb08a84162b7 40 *
okini3939 1:bb08a84162b7 41 * @param vendor_id Your vendor_id
okini3939 1:bb08a84162b7 42 * @param product_id Your product_id
okini3939 1:bb08a84162b7 43 * @param product_release Your preoduct_release
okini3939 1:bb08a84162b7 44 */
okini3939 1:bb08a84162b7 45 USBCDCMSC(SDFileSystem *sd, uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001);
okini3939 1:bb08a84162b7 46
okini3939 1:bb08a84162b7 47 /**
okini3939 1:bb08a84162b7 48 * Send a character. You can use puts, printf.
okini3939 1:bb08a84162b7 49 *
okini3939 1:bb08a84162b7 50 * @param c character to be sent
okini3939 1:bb08a84162b7 51 * @returns true if there is no error, false otherwise
okini3939 1:bb08a84162b7 52 */
okini3939 1:bb08a84162b7 53 virtual int _putc(int c);
okini3939 1:bb08a84162b7 54
okini3939 1:bb08a84162b7 55 /**
okini3939 1:bb08a84162b7 56 * Read a character: blocking
okini3939 1:bb08a84162b7 57 *
okini3939 1:bb08a84162b7 58 * @returns character read
okini3939 1:bb08a84162b7 59 */
okini3939 1:bb08a84162b7 60 virtual int _getc();
okini3939 1:bb08a84162b7 61
okini3939 1:bb08a84162b7 62 /**
okini3939 1:bb08a84162b7 63 * Check the number of bytes available.
okini3939 1:bb08a84162b7 64 *
okini3939 1:bb08a84162b7 65 * @returns the number of bytes available
okini3939 1:bb08a84162b7 66 */
okini3939 1:bb08a84162b7 67 uint8_t available();
okini3939 1:bb08a84162b7 68
okini3939 1:bb08a84162b7 69 /**
okini3939 1:bb08a84162b7 70 * Write a block of data.
okini3939 1:bb08a84162b7 71 *
okini3939 1:bb08a84162b7 72 * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written.
okini3939 1:bb08a84162b7 73 *
okini3939 1:bb08a84162b7 74 * @param buf pointer on data which will be written
okini3939 1:bb08a84162b7 75 * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes)
okini3939 1:bb08a84162b7 76 *
okini3939 1:bb08a84162b7 77 * @returns true if successfull
okini3939 1:bb08a84162b7 78 */
okini3939 1:bb08a84162b7 79 bool writeBlock(uint8_t * buf, uint16_t size);
okini3939 1:bb08a84162b7 80
okini3939 1:bb08a84162b7 81 /**
okini3939 1:bb08a84162b7 82 * Attach a member function to call when a packet is received.
okini3939 1:bb08a84162b7 83 *
okini3939 1:bb08a84162b7 84 * @param tptr pointer to the object to call the member function on
okini3939 1:bb08a84162b7 85 * @param mptr pointer to the member function to be called
okini3939 1:bb08a84162b7 86 */
okini3939 1:bb08a84162b7 87 template<typename T>
okini3939 1:bb08a84162b7 88 void attach(T* tptr, void (T::*mptr)(void)) {
okini3939 1:bb08a84162b7 89 if((mptr != NULL) && (tptr != NULL)) {
okini3939 1:bb08a84162b7 90 rx.attach(tptr, mptr);
okini3939 1:bb08a84162b7 91 }
okini3939 1:bb08a84162b7 92 }
okini3939 1:bb08a84162b7 93
okini3939 1:bb08a84162b7 94 /**
okini3939 1:bb08a84162b7 95 * Attach a callback called when a packet is received
okini3939 1:bb08a84162b7 96 *
okini3939 1:bb08a84162b7 97 * @param fptr function pointer
okini3939 1:bb08a84162b7 98 */
okini3939 1:bb08a84162b7 99 void attach(void (*fn)(void)) {
okini3939 1:bb08a84162b7 100 if(fn != NULL) {
okini3939 1:bb08a84162b7 101 rx.attach(fn);
okini3939 1:bb08a84162b7 102 }
okini3939 1:bb08a84162b7 103 }
okini3939 1:bb08a84162b7 104
okini3939 1:bb08a84162b7 105
okini3939 1:bb08a84162b7 106 /**
okini3939 1:bb08a84162b7 107 * Connect the USB MSD device. Establish disk initialization before really connect the device.
okini3939 1:bb08a84162b7 108 *
okini3939 1:bb08a84162b7 109 * @returns true if successful
okini3939 1:bb08a84162b7 110 */
okini3939 1:bb08a84162b7 111 bool connect();
okini3939 1:bb08a84162b7 112
okini3939 1:bb08a84162b7 113 protected:
okini3939 1:bb08a84162b7 114
okini3939 1:bb08a84162b7 115 /*
okini3939 1:bb08a84162b7 116 * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
okini3939 1:bb08a84162b7 117 *
okini3939 1:bb08a84162b7 118 * @returns pointer to the device descriptor
okini3939 1:bb08a84162b7 119 */
okini3939 1:bb08a84162b7 120 virtual uint8_t * deviceDesc();
okini3939 1:bb08a84162b7 121
okini3939 1:bb08a84162b7 122 /*
okini3939 1:bb08a84162b7 123 * Get string product descriptor
okini3939 1:bb08a84162b7 124 *
okini3939 1:bb08a84162b7 125 * @returns pointer to the string product descriptor
okini3939 1:bb08a84162b7 126 */
okini3939 1:bb08a84162b7 127 virtual uint8_t * stringIproductDesc();
okini3939 1:bb08a84162b7 128
okini3939 1:bb08a84162b7 129 /*
okini3939 1:bb08a84162b7 130 * Get string interface descriptor
okini3939 1:bb08a84162b7 131 *
okini3939 1:bb08a84162b7 132 * @returns pointer to the string interface descriptor
okini3939 1:bb08a84162b7 133 */
okini3939 1:bb08a84162b7 134 virtual uint8_t * stringIinterfaceDesc();
okini3939 1:bb08a84162b7 135
okini3939 1:bb08a84162b7 136 /*
okini3939 1:bb08a84162b7 137 * Get configuration descriptor
okini3939 1:bb08a84162b7 138 *
okini3939 1:bb08a84162b7 139 * @returns pointer to the configuration descriptor
okini3939 1:bb08a84162b7 140 */
okini3939 1:bb08a84162b7 141 virtual uint8_t * configurationDesc();
okini3939 1:bb08a84162b7 142
okini3939 1:bb08a84162b7 143 /*
okini3939 1:bb08a84162b7 144 * Send a buffer
okini3939 1:bb08a84162b7 145 *
okini3939 1:bb08a84162b7 146 * @param endpoint endpoint which will be sent the buffer
okini3939 1:bb08a84162b7 147 * @param buffer buffer to be sent
okini3939 1:bb08a84162b7 148 * @param size length of the buffer
okini3939 1:bb08a84162b7 149 * @returns true if successful
okini3939 1:bb08a84162b7 150 */
okini3939 1:bb08a84162b7 151 bool send(uint8_t * buffer, uint16_t size);
okini3939 1:bb08a84162b7 152
okini3939 1:bb08a84162b7 153 /*
okini3939 1:bb08a84162b7 154 * Read a buffer from a certain endpoint. Warning: blocking
okini3939 1:bb08a84162b7 155 *
okini3939 1:bb08a84162b7 156 * @param endpoint endpoint to read
okini3939 1:bb08a84162b7 157 * @param buffer buffer where will be stored bytes
okini3939 1:bb08a84162b7 158 * @param size the number of bytes read will be stored in *size
okini3939 1:bb08a84162b7 159 * @param maxSize the maximum length that can be read
okini3939 1:bb08a84162b7 160 * @returns true if successful
okini3939 1:bb08a84162b7 161 */
okini3939 1:bb08a84162b7 162 bool readEP(uint8_t * buffer, uint16_t * size);
okini3939 1:bb08a84162b7 163
okini3939 1:bb08a84162b7 164 /*
okini3939 1:bb08a84162b7 165 * Read a buffer from a certain endpoint. Warning: non blocking
okini3939 1:bb08a84162b7 166 *
okini3939 1:bb08a84162b7 167 * @param endpoint endpoint to read
okini3939 1:bb08a84162b7 168 * @param buffer buffer where will be stored bytes
okini3939 1:bb08a84162b7 169 * @param size the number of bytes read will be stored in *size
okini3939 1:bb08a84162b7 170 * @param maxSize the maximum length that can be read
okini3939 1:bb08a84162b7 171 * @returns true if successful
okini3939 1:bb08a84162b7 172 */
okini3939 1:bb08a84162b7 173 bool readEP_NB(uint8_t * buffer, uint16_t * size);
okini3939 1:bb08a84162b7 174
okini3939 1:bb08a84162b7 175 virtual bool USBCallback_request();
okini3939 1:bb08a84162b7 176 virtual bool USBCallback_setConfiguration(uint8_t configuration);
okini3939 1:bb08a84162b7 177
okini3939 1:bb08a84162b7 178 virtual bool EP2_OUT_callback();
okini3939 1:bb08a84162b7 179
okini3939 1:bb08a84162b7 180 /*
okini3939 1:bb08a84162b7 181 * Callback called when a packet is received
okini3939 1:bb08a84162b7 182 */
okini3939 1:bb08a84162b7 183 virtual bool EP5_OUT_callback();
okini3939 1:bb08a84162b7 184
okini3939 1:bb08a84162b7 185 /*
okini3939 1:bb08a84162b7 186 * Callback called when a packet has been sent
okini3939 1:bb08a84162b7 187 */
okini3939 1:bb08a84162b7 188 virtual bool EP5_IN_callback();
okini3939 1:bb08a84162b7 189
okini3939 1:bb08a84162b7 190 private:
okini3939 1:bb08a84162b7 191
okini3939 1:bb08a84162b7 192 FunctionPointer rx;
okini3939 1:bb08a84162b7 193 CircBuffer<uint8_t> cdcbuf;
okini3939 2:5db90410bb90 194 int cdcbreak;
okini3939 1:bb08a84162b7 195
okini3939 1:bb08a84162b7 196 // MSC Bulk-only Stage
okini3939 1:bb08a84162b7 197 enum Stage {
okini3939 1:bb08a84162b7 198 READ_CBW, // wait a CBW
okini3939 1:bb08a84162b7 199 ERROR, // error
okini3939 1:bb08a84162b7 200 PROCESS_CBW, // process a CBW request
okini3939 1:bb08a84162b7 201 SEND_CSW, // send a CSW
okini3939 1:bb08a84162b7 202 WAIT_CSW, // wait that a CSW has been effectively sent
okini3939 1:bb08a84162b7 203 };
okini3939 1:bb08a84162b7 204
okini3939 1:bb08a84162b7 205 // Bulk-only CBW
okini3939 1:bb08a84162b7 206 typedef __packed struct {
okini3939 1:bb08a84162b7 207 uint32_t Signature;
okini3939 1:bb08a84162b7 208 uint32_t Tag;
okini3939 1:bb08a84162b7 209 uint32_t DataLength;
okini3939 1:bb08a84162b7 210 uint8_t Flags;
okini3939 1:bb08a84162b7 211 uint8_t LUN;
okini3939 1:bb08a84162b7 212 uint8_t CBLength;
okini3939 1:bb08a84162b7 213 uint8_t CB[16];
okini3939 1:bb08a84162b7 214 } CBW;
okini3939 1:bb08a84162b7 215
okini3939 1:bb08a84162b7 216 // Bulk-only CSW
okini3939 1:bb08a84162b7 217 typedef __packed struct {
okini3939 1:bb08a84162b7 218 uint32_t Signature;
okini3939 1:bb08a84162b7 219 uint32_t Tag;
okini3939 1:bb08a84162b7 220 uint32_t DataResidue;
okini3939 1:bb08a84162b7 221 uint8_t Status;
okini3939 1:bb08a84162b7 222 } CSW;
okini3939 1:bb08a84162b7 223
okini3939 1:bb08a84162b7 224 //state of the bulk-only state machine
okini3939 1:bb08a84162b7 225 Stage stage;
okini3939 1:bb08a84162b7 226
okini3939 1:bb08a84162b7 227 // current CBW
okini3939 1:bb08a84162b7 228 CBW cbw;
okini3939 1:bb08a84162b7 229
okini3939 1:bb08a84162b7 230 // CSW which will be sent
okini3939 1:bb08a84162b7 231 CSW csw;
okini3939 1:bb08a84162b7 232
okini3939 1:bb08a84162b7 233 // addr where will be read or written data
okini3939 1:bb08a84162b7 234 uint32_t addr;
okini3939 1:bb08a84162b7 235
okini3939 1:bb08a84162b7 236 // length of a reading or writing
okini3939 1:bb08a84162b7 237 uint32_t length;
okini3939 1:bb08a84162b7 238
okini3939 1:bb08a84162b7 239 // memory OK (after a memoryVerify)
okini3939 1:bb08a84162b7 240 bool memOK;
okini3939 1:bb08a84162b7 241
okini3939 1:bb08a84162b7 242 // cache in RAM before writing in memory. Useful also to read a block.
okini3939 1:bb08a84162b7 243 uint8_t * page;
okini3939 1:bb08a84162b7 244
okini3939 1:bb08a84162b7 245 int BlockSize;
okini3939 1:bb08a84162b7 246 int MemorySize;
okini3939 1:bb08a84162b7 247 int BlockCount;
okini3939 1:bb08a84162b7 248
okini3939 1:bb08a84162b7 249 int _status;
okini3939 1:bb08a84162b7 250 SDFileSystem *_sd;
okini3939 1:bb08a84162b7 251
okini3939 1:bb08a84162b7 252 void CBWDecode(uint8_t * buf, uint16_t size);
okini3939 1:bb08a84162b7 253 void sendCSW (void);
okini3939 1:bb08a84162b7 254 bool inquiryRequest (void);
okini3939 1:bb08a84162b7 255 bool msd_write (uint8_t * buf, uint16_t size);
okini3939 1:bb08a84162b7 256 bool readFormatCapacity();
okini3939 1:bb08a84162b7 257 bool readCapacity (void);
okini3939 1:bb08a84162b7 258 bool infoTransfer (void);
okini3939 1:bb08a84162b7 259 void memoryRead (void);
okini3939 1:bb08a84162b7 260 bool modeSense6 (void);
okini3939 1:bb08a84162b7 261 void testUnitReady (void);
okini3939 1:bb08a84162b7 262 bool requestSense (void);
okini3939 1:bb08a84162b7 263 void memoryVerify (uint8_t * buf, uint16_t size);
okini3939 1:bb08a84162b7 264 void memoryWrite (uint8_t * buf, uint16_t size);
okini3939 1:bb08a84162b7 265 void reset();
okini3939 1:bb08a84162b7 266 void fail();
okini3939 1:bb08a84162b7 267
okini3939 2:5db90410bb90 268 int isBreak();
okini3939 2:5db90410bb90 269
okini3939 1:bb08a84162b7 270 int disk_initialize();
okini3939 1:bb08a84162b7 271 int disk_write(const char *buffer, int block_number);
okini3939 1:bb08a84162b7 272 int disk_read(char *buffer, int block_number);
okini3939 1:bb08a84162b7 273 int disk_status();
okini3939 1:bb08a84162b7 274 int disk_sectors();
okini3939 1:bb08a84162b7 275 int disk_size();
okini3939 1:bb08a84162b7 276
okini3939 1:bb08a84162b7 277 };
okini3939 1:bb08a84162b7 278
okini3939 1:bb08a84162b7 279 #endif