USB device stack - modified

Dependents:   shaun_larada

Fork of USBDevice by mbed official

Committer:
setcom_001
Date:
Mon Jul 22 21:16:27 2013 +0000
Revision:
12:a9671b78d24e
docs update

Who changed what in which revision?

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