Kazuki Yamamoto / USBCDCMSC

Dependents:   USBMSD_CDC_11U35test

Committer:
k4zuki
Date:
Wed Apr 22 04:54:29 2015 +0000
Revision:
2:8f01347859d0
Parent:
1:0c31d9b30900
Child:
3:178491b4d4f3
[ FIX ] some functions copied from USBCDC/USBSerial

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 2:8f01347859d0 175 /*
k4zuki 2:8f01347859d0 176 * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
k4zuki 2:8f01347859d0 177 * This is used to handle extensions to standard requests
k4zuki 2:8f01347859d0 178 * and class specific requests
k4zuki 2:8f01347859d0 179 *
k4zuki 2:8f01347859d0 180 * @returns true if class handles this request
k4zuki 2:8f01347859d0 181 */
k4zuki 0:db88c3af3803 182 virtual bool USBCallback_request();
k4zuki 2:8f01347859d0 183
k4zuki 2:8f01347859d0 184 /*
k4zuki 2:8f01347859d0 185 * Called by USBDevice on Endpoint0 request completion
k4zuki 2:8f01347859d0 186 * if the 'notify' flag has been set to true. Warning: Called in ISR context
k4zuki 2:8f01347859d0 187 *
k4zuki 2:8f01347859d0 188 * In this case it is used to indicate that a HID report has
k4zuki 2:8f01347859d0 189 * been received from the host on endpoint 0
k4zuki 2:8f01347859d0 190 *
k4zuki 2:8f01347859d0 191 * @param buf buffer received on endpoint 0
k4zuki 2:8f01347859d0 192 * @param length length of this buffer
k4zuki 2:8f01347859d0 193 */
k4zuki 2:8f01347859d0 194 virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length); //from USBCDC class
k4zuki 2:8f01347859d0 195
k4zuki 2:8f01347859d0 196 /*
k4zuki 2:8f01347859d0 197 * Called by USBDevice layer. Set configuration of the device.
k4zuki 2:8f01347859d0 198 * For instance, you can add all endpoints that you need on this function.
k4zuki 2:8f01347859d0 199 *
k4zuki 2:8f01347859d0 200 * @param configuration Number of the configuration
k4zuki 2:8f01347859d0 201 */
k4zuki 0:db88c3af3803 202 virtual bool USBCallback_setConfiguration(uint8_t configuration);
k4zuki 0:db88c3af3803 203
k4zuki 2:8f01347859d0 204 /*
k4zuki 2:8f01347859d0 205 * Called by USBCallback_requestCompleted when CDC line coding is changed
k4zuki 2:8f01347859d0 206 * Warning: Called in ISR
k4zuki 2:8f01347859d0 207 *
k4zuki 2:8f01347859d0 208 * @param baud The baud rate
k4zuki 2:8f01347859d0 209 * @param bits The number of bits in a word (5-8)
k4zuki 2:8f01347859d0 210 * @param parity The parity
k4zuki 2:8f01347859d0 211 * @param stop The number of stop bits (1 or 2)
k4zuki 2:8f01347859d0 212 */
k4zuki 2:8f01347859d0 213 virtual void lineCodingChanged(int baud, int bits, int parity, int stop){
k4zuki 2:8f01347859d0 214 if (settingsChangedCallback) {
k4zuki 2:8f01347859d0 215 settingsChangedCallback(baud, bits, parity, stop);
k4zuki 2:8f01347859d0 216 }
k4zuki 2:8f01347859d0 217 }
k4zuki 2:8f01347859d0 218
k4zuki 0:db88c3af3803 219 virtual bool EP2_OUT_callback();
k4zuki 0:db88c3af3803 220
k4zuki 0:db88c3af3803 221 /*
k4zuki 2:8f01347859d0 222 * Callback called when a MSD packet is received
k4zuki 0:db88c3af3803 223 */
k4zuki 1:0c31d9b30900 224 virtual bool EP3_OUT_callback();
k4zuki 0:db88c3af3803 225
k4zuki 0:db88c3af3803 226 /*
k4zuki 2:8f01347859d0 227 * Callback called when a MSD packet has been sent
k4zuki 0:db88c3af3803 228 */
k4zuki 1:0c31d9b30900 229 virtual bool EP3_IN_callback();
k4zuki 0:db88c3af3803 230
k4zuki 0:db88c3af3803 231 private:
k4zuki 0:db88c3af3803 232
k4zuki 0:db88c3af3803 233 FunctionPointer rx;
k4zuki 0:db88c3af3803 234 CircBuffer<uint8_t> cdcbuf;
k4zuki 0:db88c3af3803 235 int cdcbreak;
k4zuki 0:db88c3af3803 236
k4zuki 0:db88c3af3803 237 // MSC Bulk-only Stage
k4zuki 0:db88c3af3803 238 enum Stage {
k4zuki 0:db88c3af3803 239 READ_CBW, // wait a CBW
k4zuki 0:db88c3af3803 240 ERROR, // error
k4zuki 0:db88c3af3803 241 PROCESS_CBW, // process a CBW request
k4zuki 0:db88c3af3803 242 SEND_CSW, // send a CSW
k4zuki 0:db88c3af3803 243 WAIT_CSW, // wait that a CSW has been effectively sent
k4zuki 0:db88c3af3803 244 };
k4zuki 0:db88c3af3803 245
k4zuki 0:db88c3af3803 246 // Bulk-only CBW
k4zuki 0:db88c3af3803 247 typedef __packed struct {
k4zuki 0:db88c3af3803 248 uint32_t Signature;
k4zuki 0:db88c3af3803 249 uint32_t Tag;
k4zuki 0:db88c3af3803 250 uint32_t DataLength;
k4zuki 0:db88c3af3803 251 uint8_t Flags;
k4zuki 0:db88c3af3803 252 uint8_t LUN;
k4zuki 0:db88c3af3803 253 uint8_t CBLength;
k4zuki 0:db88c3af3803 254 uint8_t CB[16];
k4zuki 0:db88c3af3803 255 } CBW;
k4zuki 0:db88c3af3803 256
k4zuki 0:db88c3af3803 257 // Bulk-only CSW
k4zuki 0:db88c3af3803 258 typedef __packed struct {
k4zuki 0:db88c3af3803 259 uint32_t Signature;
k4zuki 0:db88c3af3803 260 uint32_t Tag;
k4zuki 0:db88c3af3803 261 uint32_t DataResidue;
k4zuki 0:db88c3af3803 262 uint8_t Status;
k4zuki 0:db88c3af3803 263 } CSW;
k4zuki 0:db88c3af3803 264
k4zuki 0:db88c3af3803 265 //state of the bulk-only state machine
k4zuki 0:db88c3af3803 266 Stage stage;
k4zuki 0:db88c3af3803 267
k4zuki 0:db88c3af3803 268 // current CBW
k4zuki 0:db88c3af3803 269 CBW cbw;
k4zuki 0:db88c3af3803 270
k4zuki 0:db88c3af3803 271 // CSW which will be sent
k4zuki 0:db88c3af3803 272 CSW csw;
k4zuki 0:db88c3af3803 273
k4zuki 0:db88c3af3803 274 // addr where will be read or written data
k4zuki 0:db88c3af3803 275 uint32_t addr;
k4zuki 0:db88c3af3803 276
k4zuki 0:db88c3af3803 277 // length of a reading or writing
k4zuki 0:db88c3af3803 278 uint32_t length;
k4zuki 0:db88c3af3803 279
k4zuki 0:db88c3af3803 280 // memory OK (after a memoryVerify)
k4zuki 0:db88c3af3803 281 bool memOK;
k4zuki 0:db88c3af3803 282
k4zuki 0:db88c3af3803 283 // cache in RAM before writing in memory. Useful also to read a block.
k4zuki 0:db88c3af3803 284 uint8_t * page;
k4zuki 0:db88c3af3803 285
k4zuki 0:db88c3af3803 286 int BlockSize;
k4zuki 0:db88c3af3803 287 int MemorySize;
k4zuki 0:db88c3af3803 288 int BlockCount;
k4zuki 0:db88c3af3803 289
k4zuki 0:db88c3af3803 290 int _status;
k4zuki 0:db88c3af3803 291 USBSDFileSystem *_sd;
k4zuki 0:db88c3af3803 292
k4zuki 0:db88c3af3803 293 void CBWDecode(uint8_t * buf, uint16_t size);
k4zuki 0:db88c3af3803 294 void sendCSW (void);
k4zuki 0:db88c3af3803 295 bool inquiryRequest (void);
k4zuki 0:db88c3af3803 296 bool msd_write (uint8_t * buf, uint16_t size);
k4zuki 0:db88c3af3803 297 bool readFormatCapacity();
k4zuki 0:db88c3af3803 298 bool readCapacity (void);
k4zuki 0:db88c3af3803 299 bool infoTransfer (void);
k4zuki 0:db88c3af3803 300 void memoryRead (void);
k4zuki 0:db88c3af3803 301 bool modeSense6 (void);
k4zuki 0:db88c3af3803 302 void testUnitReady (void);
k4zuki 0:db88c3af3803 303 bool requestSense (void);
k4zuki 0:db88c3af3803 304 void memoryVerify (uint8_t * buf, uint16_t size);
k4zuki 0:db88c3af3803 305 void memoryWrite (uint8_t * buf, uint16_t size);
k4zuki 0:db88c3af3803 306 void reset();
k4zuki 0:db88c3af3803 307 void fail();
k4zuki 0:db88c3af3803 308
k4zuki 0:db88c3af3803 309 int isBreak();
k4zuki 0:db88c3af3803 310
k4zuki 0:db88c3af3803 311 int disk_initialize();
k4zuki 0:db88c3af3803 312 int _disk_write(const uint8_t *buffer, int block_number);
k4zuki 0:db88c3af3803 313 int disk_read(uint8_t *buffer, int block_number);
k4zuki 0:db88c3af3803 314 int _disk_status();
k4zuki 0:db88c3af3803 315 int disk_sectors();
k4zuki 0:db88c3af3803 316 int disk_size();
k4zuki 0:db88c3af3803 317
k4zuki 2:8f01347859d0 318 void (*settingsChangedCallback)(int baud, int bits, int parity, int stop);
k4zuki 0:db88c3af3803 319 };
k4zuki 0:db88c3af3803 320
k4zuki 0:db88c3af3803 321 #endif