Kalibriersoftware Stromwerte

Dependencies:   Matrix mbed

Committer:
Racer01014
Date:
Sat Nov 28 13:50:31 2015 +0000
Revision:
1:ea5f520dcdc1
Parent:
0:5e35c180ed4a
-

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Racer01014 0:5e35c180ed4a 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
Racer01014 0:5e35c180ed4a 2 *
Racer01014 0:5e35c180ed4a 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Racer01014 0:5e35c180ed4a 4 * and associated documentation files (the "Software"), to deal in the Software without
Racer01014 0:5e35c180ed4a 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
Racer01014 0:5e35c180ed4a 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Racer01014 0:5e35c180ed4a 7 * Software is furnished to do so, subject to the following conditions:
Racer01014 0:5e35c180ed4a 8 *
Racer01014 0:5e35c180ed4a 9 * The above copyright notice and this permission notice shall be included in all copies or
Racer01014 0:5e35c180ed4a 10 * substantial portions of the Software.
Racer01014 0:5e35c180ed4a 11 *
Racer01014 0:5e35c180ed4a 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Racer01014 0:5e35c180ed4a 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Racer01014 0:5e35c180ed4a 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Racer01014 0:5e35c180ed4a 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Racer01014 0:5e35c180ed4a 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Racer01014 0:5e35c180ed4a 17 */
Racer01014 0:5e35c180ed4a 18
Racer01014 0:5e35c180ed4a 19 #include "stdint.h"
Racer01014 0:5e35c180ed4a 20 #include "USBMSD.h"
Racer01014 0:5e35c180ed4a 21
Racer01014 0:5e35c180ed4a 22 #define DISK_OK 0x00
Racer01014 0:5e35c180ed4a 23 #define NO_INIT 0x01
Racer01014 0:5e35c180ed4a 24 #define NO_DISK 0x02
Racer01014 0:5e35c180ed4a 25 #define WRITE_PROTECT 0x04
Racer01014 0:5e35c180ed4a 26
Racer01014 0:5e35c180ed4a 27 #define CBW_Signature 0x43425355
Racer01014 0:5e35c180ed4a 28 #define CSW_Signature 0x53425355
Racer01014 0:5e35c180ed4a 29
Racer01014 0:5e35c180ed4a 30 // SCSI Commands
Racer01014 0:5e35c180ed4a 31 #define TEST_UNIT_READY 0x00
Racer01014 0:5e35c180ed4a 32 #define REQUEST_SENSE 0x03
Racer01014 0:5e35c180ed4a 33 #define FORMAT_UNIT 0x04
Racer01014 0:5e35c180ed4a 34 #define INQUIRY 0x12
Racer01014 0:5e35c180ed4a 35 #define MODE_SELECT6 0x15
Racer01014 0:5e35c180ed4a 36 #define MODE_SENSE6 0x1A
Racer01014 0:5e35c180ed4a 37 #define START_STOP_UNIT 0x1B
Racer01014 0:5e35c180ed4a 38 #define MEDIA_REMOVAL 0x1E
Racer01014 0:5e35c180ed4a 39 #define READ_FORMAT_CAPACITIES 0x23
Racer01014 0:5e35c180ed4a 40 #define READ_CAPACITY 0x25
Racer01014 0:5e35c180ed4a 41 #define READ10 0x28
Racer01014 0:5e35c180ed4a 42 #define WRITE10 0x2A
Racer01014 0:5e35c180ed4a 43 #define VERIFY10 0x2F
Racer01014 0:5e35c180ed4a 44 #define READ12 0xA8
Racer01014 0:5e35c180ed4a 45 #define WRITE12 0xAA
Racer01014 0:5e35c180ed4a 46 #define MODE_SELECT10 0x55
Racer01014 0:5e35c180ed4a 47 #define MODE_SENSE10 0x5A
Racer01014 0:5e35c180ed4a 48
Racer01014 0:5e35c180ed4a 49 // MSC class specific requests
Racer01014 0:5e35c180ed4a 50 #define MSC_REQUEST_RESET 0xFF
Racer01014 0:5e35c180ed4a 51 #define MSC_REQUEST_GET_MAX_LUN 0xFE
Racer01014 0:5e35c180ed4a 52
Racer01014 0:5e35c180ed4a 53 #define DEFAULT_CONFIGURATION (1)
Racer01014 0:5e35c180ed4a 54
Racer01014 0:5e35c180ed4a 55 // max packet size
Racer01014 0:5e35c180ed4a 56 #define MAX_PACKET MAX_PACKET_SIZE_EPBULK
Racer01014 0:5e35c180ed4a 57
Racer01014 0:5e35c180ed4a 58 // CSW Status
Racer01014 0:5e35c180ed4a 59 enum Status {
Racer01014 0:5e35c180ed4a 60 CSW_PASSED,
Racer01014 0:5e35c180ed4a 61 CSW_FAILED,
Racer01014 0:5e35c180ed4a 62 CSW_ERROR,
Racer01014 0:5e35c180ed4a 63 };
Racer01014 0:5e35c180ed4a 64
Racer01014 0:5e35c180ed4a 65
Racer01014 0:5e35c180ed4a 66 USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
Racer01014 0:5e35c180ed4a 67 stage = READ_CBW;
Racer01014 0:5e35c180ed4a 68 memset((void *)&cbw, 0, sizeof(CBW));
Racer01014 0:5e35c180ed4a 69 memset((void *)&csw, 0, sizeof(CSW));
Racer01014 0:5e35c180ed4a 70 }
Racer01014 0:5e35c180ed4a 71
Racer01014 0:5e35c180ed4a 72
Racer01014 0:5e35c180ed4a 73
Racer01014 0:5e35c180ed4a 74 // Called in ISR context to process a class specific request
Racer01014 0:5e35c180ed4a 75 bool USBMSD::USBCallback_request(void) {
Racer01014 0:5e35c180ed4a 76
Racer01014 0:5e35c180ed4a 77 bool success = false;
Racer01014 0:5e35c180ed4a 78 CONTROL_TRANSFER * transfer = getTransferPtr();
Racer01014 0:5e35c180ed4a 79 static uint8_t maxLUN[1] = {0};
Racer01014 0:5e35c180ed4a 80
Racer01014 0:5e35c180ed4a 81 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
Racer01014 0:5e35c180ed4a 82 switch (transfer->setup.bRequest) {
Racer01014 0:5e35c180ed4a 83 case MSC_REQUEST_RESET:
Racer01014 0:5e35c180ed4a 84 reset();
Racer01014 0:5e35c180ed4a 85 success = true;
Racer01014 0:5e35c180ed4a 86 break;
Racer01014 0:5e35c180ed4a 87 case MSC_REQUEST_GET_MAX_LUN:
Racer01014 0:5e35c180ed4a 88 transfer->remaining = 1;
Racer01014 0:5e35c180ed4a 89 transfer->ptr = maxLUN;
Racer01014 0:5e35c180ed4a 90 transfer->direction = DEVICE_TO_HOST;
Racer01014 0:5e35c180ed4a 91 success = true;
Racer01014 0:5e35c180ed4a 92 break;
Racer01014 0:5e35c180ed4a 93 default:
Racer01014 0:5e35c180ed4a 94 break;
Racer01014 0:5e35c180ed4a 95 }
Racer01014 0:5e35c180ed4a 96 }
Racer01014 0:5e35c180ed4a 97
Racer01014 0:5e35c180ed4a 98 return success;
Racer01014 0:5e35c180ed4a 99 }
Racer01014 0:5e35c180ed4a 100
Racer01014 0:5e35c180ed4a 101
Racer01014 0:5e35c180ed4a 102 bool USBMSD::connect() {
Racer01014 0:5e35c180ed4a 103
Racer01014 0:5e35c180ed4a 104 //disk initialization
Racer01014 0:5e35c180ed4a 105 if (disk_status() & NO_INIT) {
Racer01014 0:5e35c180ed4a 106 if (disk_initialize()) {
Racer01014 0:5e35c180ed4a 107 return false;
Racer01014 0:5e35c180ed4a 108 }
Racer01014 0:5e35c180ed4a 109 }
Racer01014 0:5e35c180ed4a 110
Racer01014 0:5e35c180ed4a 111 // get number of blocks
Racer01014 0:5e35c180ed4a 112 BlockCount = disk_sectors();
Racer01014 0:5e35c180ed4a 113
Racer01014 0:5e35c180ed4a 114 // get memory size
Racer01014 0:5e35c180ed4a 115 MemorySize = disk_size();
Racer01014 0:5e35c180ed4a 116
Racer01014 0:5e35c180ed4a 117 if (BlockCount > 0) {
Racer01014 0:5e35c180ed4a 118 BlockSize = MemorySize / BlockCount;
Racer01014 0:5e35c180ed4a 119 if (BlockSize != 0) {
Racer01014 0:5e35c180ed4a 120 page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t));
Racer01014 0:5e35c180ed4a 121 if (page == NULL)
Racer01014 0:5e35c180ed4a 122 return false;
Racer01014 0:5e35c180ed4a 123 }
Racer01014 0:5e35c180ed4a 124 } else {
Racer01014 0:5e35c180ed4a 125 return false;
Racer01014 0:5e35c180ed4a 126 }
Racer01014 0:5e35c180ed4a 127
Racer01014 0:5e35c180ed4a 128 //connect the device
Racer01014 0:5e35c180ed4a 129 USBDevice::connect();
Racer01014 0:5e35c180ed4a 130 return true;
Racer01014 0:5e35c180ed4a 131 }
Racer01014 0:5e35c180ed4a 132
Racer01014 0:5e35c180ed4a 133
Racer01014 0:5e35c180ed4a 134 void USBMSD::reset() {
Racer01014 0:5e35c180ed4a 135 stage = READ_CBW;
Racer01014 0:5e35c180ed4a 136 }
Racer01014 0:5e35c180ed4a 137
Racer01014 0:5e35c180ed4a 138
Racer01014 0:5e35c180ed4a 139 // Called in ISR context called when a data is received
Racer01014 0:5e35c180ed4a 140 bool USBMSD::EP2_OUT_callback() {
Racer01014 0:5e35c180ed4a 141 uint32_t size = 0;
Racer01014 0:5e35c180ed4a 142 uint8_t buf[MAX_PACKET_SIZE_EPBULK];
Racer01014 0:5e35c180ed4a 143 readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 144 switch (stage) {
Racer01014 0:5e35c180ed4a 145 // the device has to decode the CBW received
Racer01014 0:5e35c180ed4a 146 case READ_CBW:
Racer01014 0:5e35c180ed4a 147 CBWDecode(buf, size);
Racer01014 0:5e35c180ed4a 148 break;
Racer01014 0:5e35c180ed4a 149
Racer01014 0:5e35c180ed4a 150 // the device has to receive data from the host
Racer01014 0:5e35c180ed4a 151 case PROCESS_CBW:
Racer01014 0:5e35c180ed4a 152 switch (cbw.CB[0]) {
Racer01014 0:5e35c180ed4a 153 case WRITE10:
Racer01014 0:5e35c180ed4a 154 case WRITE12:
Racer01014 0:5e35c180ed4a 155 memoryWrite(buf, size);
Racer01014 0:5e35c180ed4a 156 break;
Racer01014 0:5e35c180ed4a 157 case VERIFY10:
Racer01014 0:5e35c180ed4a 158 memoryVerify(buf, size);
Racer01014 0:5e35c180ed4a 159 break;
Racer01014 0:5e35c180ed4a 160 }
Racer01014 0:5e35c180ed4a 161 break;
Racer01014 0:5e35c180ed4a 162
Racer01014 0:5e35c180ed4a 163 // an error has occured: stall endpoint and send CSW
Racer01014 0:5e35c180ed4a 164 default:
Racer01014 0:5e35c180ed4a 165 stallEndpoint(EPBULK_OUT);
Racer01014 0:5e35c180ed4a 166 csw.Status = CSW_ERROR;
Racer01014 0:5e35c180ed4a 167 sendCSW();
Racer01014 0:5e35c180ed4a 168 break;
Racer01014 0:5e35c180ed4a 169 }
Racer01014 0:5e35c180ed4a 170
Racer01014 0:5e35c180ed4a 171 //reactivate readings on the OUT bulk endpoint
Racer01014 0:5e35c180ed4a 172 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 173 return true;
Racer01014 0:5e35c180ed4a 174 }
Racer01014 0:5e35c180ed4a 175
Racer01014 0:5e35c180ed4a 176 // Called in ISR context when a data has been transferred
Racer01014 0:5e35c180ed4a 177 bool USBMSD::EP2_IN_callback() {
Racer01014 0:5e35c180ed4a 178 switch (stage) {
Racer01014 0:5e35c180ed4a 179
Racer01014 0:5e35c180ed4a 180 // the device has to send data to the host
Racer01014 0:5e35c180ed4a 181 case PROCESS_CBW:
Racer01014 0:5e35c180ed4a 182 switch (cbw.CB[0]) {
Racer01014 0:5e35c180ed4a 183 case READ10:
Racer01014 0:5e35c180ed4a 184 case READ12:
Racer01014 0:5e35c180ed4a 185 memoryRead();
Racer01014 0:5e35c180ed4a 186 break;
Racer01014 0:5e35c180ed4a 187 }
Racer01014 0:5e35c180ed4a 188 break;
Racer01014 0:5e35c180ed4a 189
Racer01014 0:5e35c180ed4a 190 //the device has to send a CSW
Racer01014 0:5e35c180ed4a 191 case SEND_CSW:
Racer01014 0:5e35c180ed4a 192 sendCSW();
Racer01014 0:5e35c180ed4a 193 break;
Racer01014 0:5e35c180ed4a 194
Racer01014 0:5e35c180ed4a 195 // an error has occured
Racer01014 0:5e35c180ed4a 196 case ERROR:
Racer01014 0:5e35c180ed4a 197 stallEndpoint(EPBULK_IN);
Racer01014 0:5e35c180ed4a 198 sendCSW();
Racer01014 0:5e35c180ed4a 199 break;
Racer01014 0:5e35c180ed4a 200
Racer01014 0:5e35c180ed4a 201 // the host has received the CSW -> we wait a CBW
Racer01014 0:5e35c180ed4a 202 case WAIT_CSW:
Racer01014 0:5e35c180ed4a 203 stage = READ_CBW;
Racer01014 0:5e35c180ed4a 204 break;
Racer01014 0:5e35c180ed4a 205 }
Racer01014 0:5e35c180ed4a 206 return true;
Racer01014 0:5e35c180ed4a 207 }
Racer01014 0:5e35c180ed4a 208
Racer01014 0:5e35c180ed4a 209
Racer01014 0:5e35c180ed4a 210 void USBMSD::memoryWrite (uint8_t * buf, uint16_t size) {
Racer01014 0:5e35c180ed4a 211
Racer01014 0:5e35c180ed4a 212 if ((addr + size) > MemorySize) {
Racer01014 0:5e35c180ed4a 213 size = MemorySize - addr;
Racer01014 0:5e35c180ed4a 214 stage = ERROR;
Racer01014 0:5e35c180ed4a 215 stallEndpoint(EPBULK_OUT);
Racer01014 0:5e35c180ed4a 216 }
Racer01014 0:5e35c180ed4a 217
Racer01014 0:5e35c180ed4a 218 // we fill an array in RAM of 1 block before writing it in memory
Racer01014 0:5e35c180ed4a 219 for (int i = 0; i < size; i++)
Racer01014 0:5e35c180ed4a 220 page[addr%BlockSize + i] = buf[i];
Racer01014 0:5e35c180ed4a 221
Racer01014 0:5e35c180ed4a 222 // if the array is filled, write it in memory
Racer01014 0:5e35c180ed4a 223 if (!((addr + size)%BlockSize)) {
Racer01014 0:5e35c180ed4a 224 if (!(disk_status() & WRITE_PROTECT)) {
Racer01014 0:5e35c180ed4a 225 disk_write(page, addr/BlockSize);
Racer01014 0:5e35c180ed4a 226 }
Racer01014 0:5e35c180ed4a 227 }
Racer01014 0:5e35c180ed4a 228
Racer01014 0:5e35c180ed4a 229 addr += size;
Racer01014 0:5e35c180ed4a 230 length -= size;
Racer01014 0:5e35c180ed4a 231 csw.DataResidue -= size;
Racer01014 0:5e35c180ed4a 232
Racer01014 0:5e35c180ed4a 233 if ((!length) || (stage != PROCESS_CBW)) {
Racer01014 0:5e35c180ed4a 234 csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED;
Racer01014 0:5e35c180ed4a 235 sendCSW();
Racer01014 0:5e35c180ed4a 236 }
Racer01014 0:5e35c180ed4a 237 }
Racer01014 0:5e35c180ed4a 238
Racer01014 0:5e35c180ed4a 239 void USBMSD::memoryVerify (uint8_t * buf, uint16_t size) {
Racer01014 0:5e35c180ed4a 240 uint32_t n;
Racer01014 0:5e35c180ed4a 241
Racer01014 0:5e35c180ed4a 242 if ((addr + size) > MemorySize) {
Racer01014 0:5e35c180ed4a 243 size = MemorySize - addr;
Racer01014 0:5e35c180ed4a 244 stage = ERROR;
Racer01014 0:5e35c180ed4a 245 stallEndpoint(EPBULK_OUT);
Racer01014 0:5e35c180ed4a 246 }
Racer01014 0:5e35c180ed4a 247
Racer01014 0:5e35c180ed4a 248 // beginning of a new block -> load a whole block in RAM
Racer01014 0:5e35c180ed4a 249 if (!(addr%BlockSize))
Racer01014 0:5e35c180ed4a 250 disk_read(page, addr/BlockSize);
Racer01014 0:5e35c180ed4a 251
Racer01014 0:5e35c180ed4a 252 // info are in RAM -> no need to re-read memory
Racer01014 0:5e35c180ed4a 253 for (n = 0; n < size; n++) {
Racer01014 0:5e35c180ed4a 254 if (page[addr%BlockSize + n] != buf[n]) {
Racer01014 0:5e35c180ed4a 255 memOK = false;
Racer01014 0:5e35c180ed4a 256 break;
Racer01014 0:5e35c180ed4a 257 }
Racer01014 0:5e35c180ed4a 258 }
Racer01014 0:5e35c180ed4a 259
Racer01014 0:5e35c180ed4a 260 addr += size;
Racer01014 0:5e35c180ed4a 261 length -= size;
Racer01014 0:5e35c180ed4a 262 csw.DataResidue -= size;
Racer01014 0:5e35c180ed4a 263
Racer01014 0:5e35c180ed4a 264 if ( !length || (stage != PROCESS_CBW)) {
Racer01014 0:5e35c180ed4a 265 csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED;
Racer01014 0:5e35c180ed4a 266 sendCSW();
Racer01014 0:5e35c180ed4a 267 }
Racer01014 0:5e35c180ed4a 268 }
Racer01014 0:5e35c180ed4a 269
Racer01014 0:5e35c180ed4a 270
Racer01014 0:5e35c180ed4a 271 bool USBMSD::inquiryRequest (void) {
Racer01014 0:5e35c180ed4a 272 uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01,
Racer01014 0:5e35c180ed4a 273 36 - 4, 0x80, 0x00, 0x00,
Racer01014 0:5e35c180ed4a 274 'M', 'B', 'E', 'D', '.', 'O', 'R', 'G',
Racer01014 0:5e35c180ed4a 275 'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ',
Racer01014 0:5e35c180ed4a 276 '1', '.', '0', ' ',
Racer01014 0:5e35c180ed4a 277 };
Racer01014 0:5e35c180ed4a 278 if (!write(inquiry, sizeof(inquiry))) {
Racer01014 0:5e35c180ed4a 279 return false;
Racer01014 0:5e35c180ed4a 280 }
Racer01014 0:5e35c180ed4a 281 return true;
Racer01014 0:5e35c180ed4a 282 }
Racer01014 0:5e35c180ed4a 283
Racer01014 0:5e35c180ed4a 284
Racer01014 0:5e35c180ed4a 285 bool USBMSD::readFormatCapacity() {
Racer01014 0:5e35c180ed4a 286 uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,
Racer01014 0:5e35c180ed4a 287 (BlockCount >> 24) & 0xff,
Racer01014 0:5e35c180ed4a 288 (BlockCount >> 16) & 0xff,
Racer01014 0:5e35c180ed4a 289 (BlockCount >> 8) & 0xff,
Racer01014 0:5e35c180ed4a 290 (BlockCount >> 0) & 0xff,
Racer01014 0:5e35c180ed4a 291
Racer01014 0:5e35c180ed4a 292 0x02,
Racer01014 0:5e35c180ed4a 293 (BlockSize >> 16) & 0xff,
Racer01014 0:5e35c180ed4a 294 (BlockSize >> 8) & 0xff,
Racer01014 0:5e35c180ed4a 295 (BlockSize >> 0) & 0xff,
Racer01014 0:5e35c180ed4a 296 };
Racer01014 0:5e35c180ed4a 297 if (!write(capacity, sizeof(capacity))) {
Racer01014 0:5e35c180ed4a 298 return false;
Racer01014 0:5e35c180ed4a 299 }
Racer01014 0:5e35c180ed4a 300 return true;
Racer01014 0:5e35c180ed4a 301 }
Racer01014 0:5e35c180ed4a 302
Racer01014 0:5e35c180ed4a 303
Racer01014 0:5e35c180ed4a 304 bool USBMSD::readCapacity (void) {
Racer01014 0:5e35c180ed4a 305 uint8_t capacity[] = {
Racer01014 0:5e35c180ed4a 306 ((BlockCount - 1) >> 24) & 0xff,
Racer01014 0:5e35c180ed4a 307 ((BlockCount - 1) >> 16) & 0xff,
Racer01014 0:5e35c180ed4a 308 ((BlockCount - 1) >> 8) & 0xff,
Racer01014 0:5e35c180ed4a 309 ((BlockCount - 1) >> 0) & 0xff,
Racer01014 0:5e35c180ed4a 310
Racer01014 0:5e35c180ed4a 311 (BlockSize >> 24) & 0xff,
Racer01014 0:5e35c180ed4a 312 (BlockSize >> 16) & 0xff,
Racer01014 0:5e35c180ed4a 313 (BlockSize >> 8) & 0xff,
Racer01014 0:5e35c180ed4a 314 (BlockSize >> 0) & 0xff,
Racer01014 0:5e35c180ed4a 315 };
Racer01014 0:5e35c180ed4a 316 if (!write(capacity, sizeof(capacity))) {
Racer01014 0:5e35c180ed4a 317 return false;
Racer01014 0:5e35c180ed4a 318 }
Racer01014 0:5e35c180ed4a 319 return true;
Racer01014 0:5e35c180ed4a 320 }
Racer01014 0:5e35c180ed4a 321
Racer01014 0:5e35c180ed4a 322 bool USBMSD::write (uint8_t * buf, uint16_t size) {
Racer01014 0:5e35c180ed4a 323
Racer01014 0:5e35c180ed4a 324 if (size >= cbw.DataLength) {
Racer01014 0:5e35c180ed4a 325 size = cbw.DataLength;
Racer01014 0:5e35c180ed4a 326 }
Racer01014 0:5e35c180ed4a 327 stage = SEND_CSW;
Racer01014 0:5e35c180ed4a 328
Racer01014 0:5e35c180ed4a 329 if (!writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) {
Racer01014 0:5e35c180ed4a 330 return false;
Racer01014 0:5e35c180ed4a 331 }
Racer01014 0:5e35c180ed4a 332
Racer01014 0:5e35c180ed4a 333 csw.DataResidue -= size;
Racer01014 0:5e35c180ed4a 334 csw.Status = CSW_PASSED;
Racer01014 0:5e35c180ed4a 335 return true;
Racer01014 0:5e35c180ed4a 336 }
Racer01014 0:5e35c180ed4a 337
Racer01014 0:5e35c180ed4a 338
Racer01014 0:5e35c180ed4a 339 bool USBMSD::modeSense6 (void) {
Racer01014 0:5e35c180ed4a 340 uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 };
Racer01014 0:5e35c180ed4a 341 if (!write(sense6, sizeof(sense6))) {
Racer01014 0:5e35c180ed4a 342 return false;
Racer01014 0:5e35c180ed4a 343 }
Racer01014 0:5e35c180ed4a 344 return true;
Racer01014 0:5e35c180ed4a 345 }
Racer01014 0:5e35c180ed4a 346
Racer01014 0:5e35c180ed4a 347 void USBMSD::sendCSW() {
Racer01014 0:5e35c180ed4a 348 csw.Signature = CSW_Signature;
Racer01014 0:5e35c180ed4a 349 writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 350 stage = WAIT_CSW;
Racer01014 0:5e35c180ed4a 351 }
Racer01014 0:5e35c180ed4a 352
Racer01014 0:5e35c180ed4a 353 bool USBMSD::requestSense (void) {
Racer01014 0:5e35c180ed4a 354 uint8_t request_sense[] = {
Racer01014 0:5e35c180ed4a 355 0x70,
Racer01014 0:5e35c180ed4a 356 0x00,
Racer01014 0:5e35c180ed4a 357 0x05, // Sense Key: illegal request
Racer01014 0:5e35c180ed4a 358 0x00,
Racer01014 0:5e35c180ed4a 359 0x00,
Racer01014 0:5e35c180ed4a 360 0x00,
Racer01014 0:5e35c180ed4a 361 0x00,
Racer01014 0:5e35c180ed4a 362 0x0A,
Racer01014 0:5e35c180ed4a 363 0x00,
Racer01014 0:5e35c180ed4a 364 0x00,
Racer01014 0:5e35c180ed4a 365 0x00,
Racer01014 0:5e35c180ed4a 366 0x00,
Racer01014 0:5e35c180ed4a 367 0x30,
Racer01014 0:5e35c180ed4a 368 0x01,
Racer01014 0:5e35c180ed4a 369 0x00,
Racer01014 0:5e35c180ed4a 370 0x00,
Racer01014 0:5e35c180ed4a 371 0x00,
Racer01014 0:5e35c180ed4a 372 0x00,
Racer01014 0:5e35c180ed4a 373 };
Racer01014 0:5e35c180ed4a 374
Racer01014 0:5e35c180ed4a 375 if (!write(request_sense, sizeof(request_sense))) {
Racer01014 0:5e35c180ed4a 376 return false;
Racer01014 0:5e35c180ed4a 377 }
Racer01014 0:5e35c180ed4a 378
Racer01014 0:5e35c180ed4a 379 return true;
Racer01014 0:5e35c180ed4a 380 }
Racer01014 0:5e35c180ed4a 381
Racer01014 0:5e35c180ed4a 382 void USBMSD::fail() {
Racer01014 0:5e35c180ed4a 383 csw.Status = CSW_FAILED;
Racer01014 0:5e35c180ed4a 384 sendCSW();
Racer01014 0:5e35c180ed4a 385 }
Racer01014 0:5e35c180ed4a 386
Racer01014 0:5e35c180ed4a 387
Racer01014 0:5e35c180ed4a 388 void USBMSD::CBWDecode(uint8_t * buf, uint16_t size) {
Racer01014 0:5e35c180ed4a 389 if (size == sizeof(cbw)) {
Racer01014 0:5e35c180ed4a 390 memcpy((uint8_t *)&cbw, buf, size);
Racer01014 0:5e35c180ed4a 391 if (cbw.Signature == CBW_Signature) {
Racer01014 0:5e35c180ed4a 392 csw.Tag = cbw.Tag;
Racer01014 0:5e35c180ed4a 393 csw.DataResidue = cbw.DataLength;
Racer01014 0:5e35c180ed4a 394 if ((cbw.CBLength < 1) || (cbw.CBLength > 16) ) {
Racer01014 0:5e35c180ed4a 395 fail();
Racer01014 0:5e35c180ed4a 396 } else {
Racer01014 0:5e35c180ed4a 397 switch (cbw.CB[0]) {
Racer01014 0:5e35c180ed4a 398 case TEST_UNIT_READY:
Racer01014 0:5e35c180ed4a 399 testUnitReady();
Racer01014 0:5e35c180ed4a 400 break;
Racer01014 0:5e35c180ed4a 401 case REQUEST_SENSE:
Racer01014 0:5e35c180ed4a 402 requestSense();
Racer01014 0:5e35c180ed4a 403 break;
Racer01014 0:5e35c180ed4a 404 case INQUIRY:
Racer01014 0:5e35c180ed4a 405 inquiryRequest();
Racer01014 0:5e35c180ed4a 406 break;
Racer01014 0:5e35c180ed4a 407 case MODE_SENSE6:
Racer01014 0:5e35c180ed4a 408 modeSense6();
Racer01014 0:5e35c180ed4a 409 break;
Racer01014 0:5e35c180ed4a 410 case READ_FORMAT_CAPACITIES:
Racer01014 0:5e35c180ed4a 411 readFormatCapacity();
Racer01014 0:5e35c180ed4a 412 break;
Racer01014 0:5e35c180ed4a 413 case READ_CAPACITY:
Racer01014 0:5e35c180ed4a 414 readCapacity();
Racer01014 0:5e35c180ed4a 415 break;
Racer01014 0:5e35c180ed4a 416 case READ10:
Racer01014 0:5e35c180ed4a 417 case READ12:
Racer01014 0:5e35c180ed4a 418 if (infoTransfer()) {
Racer01014 0:5e35c180ed4a 419 if ((cbw.Flags & 0x80)) {
Racer01014 0:5e35c180ed4a 420 stage = PROCESS_CBW;
Racer01014 0:5e35c180ed4a 421 memoryRead();
Racer01014 0:5e35c180ed4a 422 } else {
Racer01014 0:5e35c180ed4a 423 stallEndpoint(EPBULK_OUT);
Racer01014 0:5e35c180ed4a 424 csw.Status = CSW_ERROR;
Racer01014 0:5e35c180ed4a 425 sendCSW();
Racer01014 0:5e35c180ed4a 426 }
Racer01014 0:5e35c180ed4a 427 }
Racer01014 0:5e35c180ed4a 428 break;
Racer01014 0:5e35c180ed4a 429 case WRITE10:
Racer01014 0:5e35c180ed4a 430 case WRITE12:
Racer01014 0:5e35c180ed4a 431 if (infoTransfer()) {
Racer01014 0:5e35c180ed4a 432 if (!(cbw.Flags & 0x80)) {
Racer01014 0:5e35c180ed4a 433 stage = PROCESS_CBW;
Racer01014 0:5e35c180ed4a 434 } else {
Racer01014 0:5e35c180ed4a 435 stallEndpoint(EPBULK_IN);
Racer01014 0:5e35c180ed4a 436 csw.Status = CSW_ERROR;
Racer01014 0:5e35c180ed4a 437 sendCSW();
Racer01014 0:5e35c180ed4a 438 }
Racer01014 0:5e35c180ed4a 439 }
Racer01014 0:5e35c180ed4a 440 break;
Racer01014 0:5e35c180ed4a 441 case VERIFY10:
Racer01014 0:5e35c180ed4a 442 if (!(cbw.CB[1] & 0x02)) {
Racer01014 0:5e35c180ed4a 443 csw.Status = CSW_PASSED;
Racer01014 0:5e35c180ed4a 444 sendCSW();
Racer01014 0:5e35c180ed4a 445 break;
Racer01014 0:5e35c180ed4a 446 }
Racer01014 0:5e35c180ed4a 447 if (infoTransfer()) {
Racer01014 0:5e35c180ed4a 448 if (!(cbw.Flags & 0x80)) {
Racer01014 0:5e35c180ed4a 449 stage = PROCESS_CBW;
Racer01014 0:5e35c180ed4a 450 memOK = true;
Racer01014 0:5e35c180ed4a 451 } else {
Racer01014 0:5e35c180ed4a 452 stallEndpoint(EPBULK_IN);
Racer01014 0:5e35c180ed4a 453 csw.Status = CSW_ERROR;
Racer01014 0:5e35c180ed4a 454 sendCSW();
Racer01014 0:5e35c180ed4a 455 }
Racer01014 0:5e35c180ed4a 456 }
Racer01014 0:5e35c180ed4a 457 break;
Racer01014 0:5e35c180ed4a 458 case MEDIA_REMOVAL:
Racer01014 0:5e35c180ed4a 459 csw.Status = CSW_PASSED;
Racer01014 0:5e35c180ed4a 460 sendCSW();
Racer01014 0:5e35c180ed4a 461 break;
Racer01014 0:5e35c180ed4a 462 default:
Racer01014 0:5e35c180ed4a 463 fail();
Racer01014 0:5e35c180ed4a 464 break;
Racer01014 0:5e35c180ed4a 465 }
Racer01014 0:5e35c180ed4a 466 }
Racer01014 0:5e35c180ed4a 467 }
Racer01014 0:5e35c180ed4a 468 }
Racer01014 0:5e35c180ed4a 469 }
Racer01014 0:5e35c180ed4a 470
Racer01014 0:5e35c180ed4a 471 void USBMSD::testUnitReady (void) {
Racer01014 0:5e35c180ed4a 472
Racer01014 0:5e35c180ed4a 473 if (cbw.DataLength != 0) {
Racer01014 0:5e35c180ed4a 474 if ((cbw.Flags & 0x80) != 0) {
Racer01014 0:5e35c180ed4a 475 stallEndpoint(EPBULK_IN);
Racer01014 0:5e35c180ed4a 476 } else {
Racer01014 0:5e35c180ed4a 477 stallEndpoint(EPBULK_OUT);
Racer01014 0:5e35c180ed4a 478 }
Racer01014 0:5e35c180ed4a 479 }
Racer01014 0:5e35c180ed4a 480
Racer01014 0:5e35c180ed4a 481 csw.Status = CSW_PASSED;
Racer01014 0:5e35c180ed4a 482 sendCSW();
Racer01014 0:5e35c180ed4a 483 }
Racer01014 0:5e35c180ed4a 484
Racer01014 0:5e35c180ed4a 485
Racer01014 0:5e35c180ed4a 486 void USBMSD::memoryRead (void) {
Racer01014 0:5e35c180ed4a 487 uint32_t n;
Racer01014 0:5e35c180ed4a 488
Racer01014 0:5e35c180ed4a 489 n = (length > MAX_PACKET) ? MAX_PACKET : length;
Racer01014 0:5e35c180ed4a 490
Racer01014 0:5e35c180ed4a 491 if ((addr + n) > MemorySize) {
Racer01014 0:5e35c180ed4a 492 n = MemorySize - addr;
Racer01014 0:5e35c180ed4a 493 stage = ERROR;
Racer01014 0:5e35c180ed4a 494 }
Racer01014 0:5e35c180ed4a 495
Racer01014 0:5e35c180ed4a 496 // we read an entire block
Racer01014 0:5e35c180ed4a 497 if (!(addr%BlockSize))
Racer01014 0:5e35c180ed4a 498 disk_read(page, addr/BlockSize);
Racer01014 0:5e35c180ed4a 499
Racer01014 0:5e35c180ed4a 500 // write data which are in RAM
Racer01014 0:5e35c180ed4a 501 writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 502
Racer01014 0:5e35c180ed4a 503 addr += n;
Racer01014 0:5e35c180ed4a 504 length -= n;
Racer01014 0:5e35c180ed4a 505
Racer01014 0:5e35c180ed4a 506 csw.DataResidue -= n;
Racer01014 0:5e35c180ed4a 507
Racer01014 0:5e35c180ed4a 508 if ( !length || (stage != PROCESS_CBW)) {
Racer01014 0:5e35c180ed4a 509 csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
Racer01014 0:5e35c180ed4a 510 stage = (stage == PROCESS_CBW) ? SEND_CSW : stage;
Racer01014 0:5e35c180ed4a 511 }
Racer01014 0:5e35c180ed4a 512 }
Racer01014 0:5e35c180ed4a 513
Racer01014 0:5e35c180ed4a 514
Racer01014 0:5e35c180ed4a 515 bool USBMSD::infoTransfer (void) {
Racer01014 0:5e35c180ed4a 516 uint32_t n;
Racer01014 0:5e35c180ed4a 517
Racer01014 0:5e35c180ed4a 518 // Logical Block Address of First Block
Racer01014 0:5e35c180ed4a 519 n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] << 8) | (cbw.CB[5] << 0);
Racer01014 0:5e35c180ed4a 520
Racer01014 0:5e35c180ed4a 521 addr = n * BlockSize;
Racer01014 0:5e35c180ed4a 522
Racer01014 0:5e35c180ed4a 523 // Number of Blocks to transfer
Racer01014 0:5e35c180ed4a 524 switch (cbw.CB[0]) {
Racer01014 0:5e35c180ed4a 525 case READ10:
Racer01014 0:5e35c180ed4a 526 case WRITE10:
Racer01014 0:5e35c180ed4a 527 case VERIFY10:
Racer01014 0:5e35c180ed4a 528 n = (cbw.CB[7] << 8) | (cbw.CB[8] << 0);
Racer01014 0:5e35c180ed4a 529 break;
Racer01014 0:5e35c180ed4a 530
Racer01014 0:5e35c180ed4a 531 case READ12:
Racer01014 0:5e35c180ed4a 532 case WRITE12:
Racer01014 0:5e35c180ed4a 533 n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] << 8) | (cbw.CB[9] << 0);
Racer01014 0:5e35c180ed4a 534 break;
Racer01014 0:5e35c180ed4a 535 }
Racer01014 0:5e35c180ed4a 536
Racer01014 0:5e35c180ed4a 537 length = n * BlockSize;
Racer01014 0:5e35c180ed4a 538
Racer01014 0:5e35c180ed4a 539 if (!cbw.DataLength) { // host requests no data
Racer01014 0:5e35c180ed4a 540 csw.Status = CSW_FAILED;
Racer01014 0:5e35c180ed4a 541 sendCSW();
Racer01014 0:5e35c180ed4a 542 return false;
Racer01014 0:5e35c180ed4a 543 }
Racer01014 0:5e35c180ed4a 544
Racer01014 0:5e35c180ed4a 545 if (cbw.DataLength != length) {
Racer01014 0:5e35c180ed4a 546 if ((cbw.Flags & 0x80) != 0) {
Racer01014 0:5e35c180ed4a 547 stallEndpoint(EPBULK_IN);
Racer01014 0:5e35c180ed4a 548 } else {
Racer01014 0:5e35c180ed4a 549 stallEndpoint(EPBULK_OUT);
Racer01014 0:5e35c180ed4a 550 }
Racer01014 0:5e35c180ed4a 551
Racer01014 0:5e35c180ed4a 552 csw.Status = CSW_FAILED;
Racer01014 0:5e35c180ed4a 553 sendCSW();
Racer01014 0:5e35c180ed4a 554 return false;
Racer01014 0:5e35c180ed4a 555 }
Racer01014 0:5e35c180ed4a 556
Racer01014 0:5e35c180ed4a 557 return true;
Racer01014 0:5e35c180ed4a 558 }
Racer01014 0:5e35c180ed4a 559
Racer01014 0:5e35c180ed4a 560
Racer01014 0:5e35c180ed4a 561
Racer01014 0:5e35c180ed4a 562
Racer01014 0:5e35c180ed4a 563
Racer01014 0:5e35c180ed4a 564 // Called in ISR context
Racer01014 0:5e35c180ed4a 565 // Set configuration. Return false if the
Racer01014 0:5e35c180ed4a 566 // configuration is not supported.
Racer01014 0:5e35c180ed4a 567 bool USBMSD::USBCallback_setConfiguration(uint8_t configuration) {
Racer01014 0:5e35c180ed4a 568 if (configuration != DEFAULT_CONFIGURATION) {
Racer01014 0:5e35c180ed4a 569 return false;
Racer01014 0:5e35c180ed4a 570 }
Racer01014 0:5e35c180ed4a 571
Racer01014 0:5e35c180ed4a 572 // Configure endpoints > 0
Racer01014 0:5e35c180ed4a 573 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 574 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 575
Racer01014 0:5e35c180ed4a 576 //activate readings
Racer01014 0:5e35c180ed4a 577 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
Racer01014 0:5e35c180ed4a 578 return true;
Racer01014 0:5e35c180ed4a 579 }
Racer01014 0:5e35c180ed4a 580
Racer01014 0:5e35c180ed4a 581
Racer01014 0:5e35c180ed4a 582 uint8_t * USBMSD::stringIinterfaceDesc() {
Racer01014 0:5e35c180ed4a 583 static uint8_t stringIinterfaceDescriptor[] = {
Racer01014 0:5e35c180ed4a 584 0x08, //bLength
Racer01014 0:5e35c180ed4a 585 STRING_DESCRIPTOR, //bDescriptorType 0x03
Racer01014 0:5e35c180ed4a 586 'M',0,'S',0,'D',0 //bString iInterface - MSD
Racer01014 0:5e35c180ed4a 587 };
Racer01014 0:5e35c180ed4a 588 return stringIinterfaceDescriptor;
Racer01014 0:5e35c180ed4a 589 }
Racer01014 0:5e35c180ed4a 590
Racer01014 0:5e35c180ed4a 591 uint8_t * USBMSD::stringIproductDesc() {
Racer01014 0:5e35c180ed4a 592 static uint8_t stringIproductDescriptor[] = {
Racer01014 0:5e35c180ed4a 593 0x12, //bLength
Racer01014 0:5e35c180ed4a 594 STRING_DESCRIPTOR, //bDescriptorType 0x03
Racer01014 0:5e35c180ed4a 595 'M',0,'b',0,'e',0,'d',0,' ',0,'M',0,'S',0,'D',0 //bString iProduct - Mbed Audio
Racer01014 0:5e35c180ed4a 596 };
Racer01014 0:5e35c180ed4a 597 return stringIproductDescriptor;
Racer01014 0:5e35c180ed4a 598 }
Racer01014 0:5e35c180ed4a 599
Racer01014 0:5e35c180ed4a 600
Racer01014 0:5e35c180ed4a 601 uint8_t * USBMSD::configurationDesc() {
Racer01014 0:5e35c180ed4a 602 static uint8_t configDescriptor[] = {
Racer01014 0:5e35c180ed4a 603
Racer01014 0:5e35c180ed4a 604 // Configuration 1
Racer01014 0:5e35c180ed4a 605 9, // bLength
Racer01014 0:5e35c180ed4a 606 2, // bDescriptorType
Racer01014 0:5e35c180ed4a 607 LSB(9 + 9 + 7 + 7), // wTotalLength
Racer01014 0:5e35c180ed4a 608 MSB(9 + 9 + 7 + 7),
Racer01014 0:5e35c180ed4a 609 0x01, // bNumInterfaces
Racer01014 0:5e35c180ed4a 610 0x01, // bConfigurationValue: 0x01 is used to select this configuration
Racer01014 0:5e35c180ed4a 611 0x00, // iConfiguration: no string to describe this configuration
Racer01014 0:5e35c180ed4a 612 0xC0, // bmAttributes
Racer01014 0:5e35c180ed4a 613 100, // bMaxPower, device power consumption is 100 mA
Racer01014 0:5e35c180ed4a 614
Racer01014 0:5e35c180ed4a 615 // Interface 0, Alternate Setting 0, MSC Class
Racer01014 0:5e35c180ed4a 616 9, // bLength
Racer01014 0:5e35c180ed4a 617 4, // bDescriptorType
Racer01014 0:5e35c180ed4a 618 0x00, // bInterfaceNumber
Racer01014 0:5e35c180ed4a 619 0x00, // bAlternateSetting
Racer01014 0:5e35c180ed4a 620 0x02, // bNumEndpoints
Racer01014 0:5e35c180ed4a 621 0x08, // bInterfaceClass
Racer01014 0:5e35c180ed4a 622 0x06, // bInterfaceSubClass
Racer01014 0:5e35c180ed4a 623 0x50, // bInterfaceProtocol
Racer01014 0:5e35c180ed4a 624 0x04, // iInterface
Racer01014 0:5e35c180ed4a 625
Racer01014 0:5e35c180ed4a 626 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
Racer01014 0:5e35c180ed4a 627 7, // bLength
Racer01014 0:5e35c180ed4a 628 5, // bDescriptorType
Racer01014 0:5e35c180ed4a 629 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
Racer01014 0:5e35c180ed4a 630 0x02, // bmAttributes (0x02=bulk)
Racer01014 0:5e35c180ed4a 631 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
Racer01014 0:5e35c180ed4a 632 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
Racer01014 0:5e35c180ed4a 633 0, // bInterval
Racer01014 0:5e35c180ed4a 634
Racer01014 0:5e35c180ed4a 635 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
Racer01014 0:5e35c180ed4a 636 7, // bLength
Racer01014 0:5e35c180ed4a 637 5, // bDescriptorType
Racer01014 0:5e35c180ed4a 638 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress
Racer01014 0:5e35c180ed4a 639 0x02, // bmAttributes (0x02=bulk)
Racer01014 0:5e35c180ed4a 640 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
Racer01014 0:5e35c180ed4a 641 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
Racer01014 0:5e35c180ed4a 642 0 // bInterval
Racer01014 0:5e35c180ed4a 643 };
Racer01014 0:5e35c180ed4a 644 return configDescriptor;
Racer01014 0:5e35c180ed4a 645 }