Kazuki Yamamoto / USBCDCMSC

Dependents:   USBMSD_CDC_11U35test

Committer:
k4zuki
Date:
Tue Apr 21 09:12:22 2015 +0000
Revision:
0:db88c3af3803
Child:
1:0c31d9b30900
[ FORK ] forked from okini3939/code/USB_CDC_MSD_Hello/ only USB CDC+MSD cut out

Who changed what in which revision?

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