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