Fork of official USB device library just changed PID (Product ID) in constructor in USBMSD.h to be different for USBMSD_AT45_HelloWorld program
Dependents: USBMSD_AT45_HelloWorld
Fork of USBDevice by
USBMSD.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 #include "USBMSD.h" 00021 00022 #define DISK_OK 0x00 00023 #define NO_INIT 0x01 00024 #define NO_DISK 0x02 00025 #define WRITE_PROTECT 0x04 00026 00027 #define CBW_Signature 0x43425355 00028 #define CSW_Signature 0x53425355 00029 00030 // SCSI Commands 00031 #define TEST_UNIT_READY 0x00 00032 #define REQUEST_SENSE 0x03 00033 #define FORMAT_UNIT 0x04 00034 #define INQUIRY 0x12 00035 #define MODE_SELECT6 0x15 00036 #define MODE_SENSE6 0x1A 00037 #define START_STOP_UNIT 0x1B 00038 #define MEDIA_REMOVAL 0x1E 00039 #define READ_FORMAT_CAPACITIES 0x23 00040 #define READ_CAPACITY 0x25 00041 #define READ10 0x28 00042 #define WRITE10 0x2A 00043 #define VERIFY10 0x2F 00044 #define READ12 0xA8 00045 #define WRITE12 0xAA 00046 #define MODE_SELECT10 0x55 00047 #define MODE_SENSE10 0x5A 00048 00049 // MSC class specific requests 00050 #define MSC_REQUEST_RESET 0xFF 00051 #define MSC_REQUEST_GET_MAX_LUN 0xFE 00052 00053 #define DEFAULT_CONFIGURATION (1) 00054 00055 // max packet size 00056 #define MAX_PACKET MAX_PACKET_SIZE_EPBULK 00057 00058 // CSW Status 00059 enum Status { 00060 CSW_PASSED, 00061 CSW_FAILED, 00062 CSW_ERROR, 00063 }; 00064 00065 00066 USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) { 00067 stage = READ_CBW; 00068 memset((void *)&cbw, 0, sizeof(CBW)); 00069 memset((void *)&csw, 0, sizeof(CSW)); 00070 } 00071 00072 00073 00074 // Called in ISR context to process a class specific request 00075 bool USBMSD::USBCallback_request(void) { 00076 00077 bool success = false; 00078 CONTROL_TRANSFER * transfer = getTransferPtr(); 00079 static uint8_t maxLUN[1] = {0}; 00080 00081 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00082 switch (transfer->setup.bRequest) { 00083 case MSC_REQUEST_RESET: 00084 reset(); 00085 success = true; 00086 break; 00087 case MSC_REQUEST_GET_MAX_LUN: 00088 transfer->remaining = 1; 00089 transfer->ptr = maxLUN; 00090 transfer->direction = DEVICE_TO_HOST; 00091 success = true; 00092 break; 00093 default: 00094 break; 00095 } 00096 } 00097 00098 return success; 00099 } 00100 00101 00102 bool USBMSD::connect() { 00103 00104 //disk initialization 00105 if (disk_status() & NO_INIT) { 00106 if (disk_initialize()) { 00107 return false; 00108 } 00109 } 00110 00111 // get number of blocks 00112 BlockCount = disk_sectors(); 00113 00114 // get memory size 00115 MemorySize = disk_size(); 00116 00117 if (BlockCount >= 0) { 00118 BlockSize = MemorySize / BlockCount; 00119 if (BlockSize != 0) { 00120 page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t)); 00121 if (page == NULL) 00122 return false; 00123 } 00124 } else { 00125 return false; 00126 } 00127 00128 //connect the device 00129 USBDevice::connect(); 00130 return true; 00131 } 00132 00133 00134 void USBMSD::reset() { 00135 stage = READ_CBW; 00136 } 00137 00138 00139 // Called in ISR context called when a data is received 00140 bool USBMSD::EP2_OUT_callback() { 00141 uint32_t size = 0; 00142 uint8_t buf[MAX_PACKET_SIZE_EPBULK]; 00143 readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK); 00144 switch (stage) { 00145 // the device has to decode the CBW received 00146 case READ_CBW: 00147 CBWDecode(buf, size); 00148 break; 00149 00150 // the device has to receive data from the host 00151 case PROCESS_CBW: 00152 switch (cbw.CB[0]) { 00153 case WRITE10: 00154 case WRITE12: 00155 memoryWrite(buf, size); 00156 break; 00157 case VERIFY10: 00158 memoryVerify(buf, size); 00159 break; 00160 } 00161 break; 00162 00163 // an error has occured: stall endpoint and send CSW 00164 default: 00165 stallEndpoint(EPBULK_OUT); 00166 csw.Status = CSW_ERROR; 00167 sendCSW(); 00168 break; 00169 } 00170 00171 //reactivate readings on the OUT bulk endpoint 00172 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00173 return true; 00174 } 00175 00176 // Called in ISR context when a data has been transferred 00177 bool USBMSD::EP2_IN_callback() { 00178 switch (stage) { 00179 00180 // the device has to send data to the host 00181 case PROCESS_CBW: 00182 switch (cbw.CB[0]) { 00183 case READ10: 00184 case READ12: 00185 memoryRead(); 00186 break; 00187 } 00188 break; 00189 00190 //the device has to send a CSW 00191 case SEND_CSW: 00192 sendCSW(); 00193 break; 00194 00195 // an error has occured 00196 case ERROR: 00197 stallEndpoint(EPBULK_IN); 00198 sendCSW(); 00199 break; 00200 00201 // the host has received the CSW -> we wait a CBW 00202 case WAIT_CSW: 00203 stage = READ_CBW; 00204 break; 00205 } 00206 return true; 00207 } 00208 00209 00210 void USBMSD::memoryWrite (uint8_t * buf, uint16_t size) { 00211 00212 if ((addr + size) > MemorySize) { 00213 size = MemorySize - addr; 00214 stage = ERROR; 00215 stallEndpoint(EPBULK_OUT); 00216 } 00217 00218 // we fill an array in RAM of 1 block before writing it in memory 00219 for (int i = 0; i < size; i++) 00220 page[addr%BlockSize + i] = buf[i]; 00221 00222 // if the array is filled, write it in memory 00223 if (!((addr + size)%BlockSize)) { 00224 if (!(disk_status() & WRITE_PROTECT)) { 00225 disk_write((const char *)page, addr/BlockSize); 00226 } 00227 } 00228 00229 addr += size; 00230 length -= size; 00231 csw.DataResidue -= size; 00232 00233 if ((!length) || (stage != PROCESS_CBW)) { 00234 csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED; 00235 sendCSW(); 00236 } 00237 } 00238 00239 void USBMSD::memoryVerify (uint8_t * buf, uint16_t size) { 00240 uint32_t n; 00241 00242 if ((addr + size) > MemorySize) { 00243 size = MemorySize - addr; 00244 stage = ERROR; 00245 stallEndpoint(EPBULK_OUT); 00246 } 00247 00248 // beginning of a new block -> load a whole block in RAM 00249 if (!(addr%BlockSize)) 00250 disk_read((char *)page, addr/BlockSize); 00251 00252 // info are in RAM -> no need to re-read memory 00253 for (n = 0; n < size; n++) { 00254 if (page[addr%BlockSize + n] != buf[n]) { 00255 memOK = false; 00256 break; 00257 } 00258 } 00259 00260 addr += size; 00261 length -= size; 00262 csw.DataResidue -= size; 00263 00264 if ( !length || (stage != PROCESS_CBW)) { 00265 csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED; 00266 sendCSW(); 00267 } 00268 } 00269 00270 00271 bool USBMSD::inquiryRequest (void) { 00272 uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01, 00273 36 - 4, 0x80, 0x00, 0x00, 00274 'M', 'B', 'E', 'D', '.', 'O', 'R', 'G', 00275 'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ', 00276 '1', '.', '0', ' ', 00277 }; 00278 if (!write(inquiry, sizeof(inquiry))) { 00279 return false; 00280 } 00281 return true; 00282 } 00283 00284 00285 bool USBMSD::readFormatCapacity() { 00286 uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08, 00287 (BlockCount >> 24) & 0xff, 00288 (BlockCount >> 16) & 0xff, 00289 (BlockCount >> 8) & 0xff, 00290 (BlockCount >> 0) & 0xff, 00291 00292 0x02, 00293 (BlockSize >> 16) & 0xff, 00294 (BlockSize >> 8) & 0xff, 00295 (BlockSize >> 0) & 0xff, 00296 }; 00297 if (!write(capacity, sizeof(capacity))) { 00298 return false; 00299 } 00300 return true; 00301 } 00302 00303 00304 bool USBMSD::readCapacity (void) { 00305 uint8_t capacity[] = { 00306 ((BlockCount - 1) >> 24) & 0xff, 00307 ((BlockCount - 1) >> 16) & 0xff, 00308 ((BlockCount - 1) >> 8) & 0xff, 00309 ((BlockCount - 1) >> 0) & 0xff, 00310 00311 (BlockSize >> 24) & 0xff, 00312 (BlockSize >> 16) & 0xff, 00313 (BlockSize >> 8) & 0xff, 00314 (BlockSize >> 0) & 0xff, 00315 }; 00316 if (!write(capacity, sizeof(capacity))) { 00317 return false; 00318 } 00319 return true; 00320 } 00321 00322 bool USBMSD::write (uint8_t * buf, uint16_t size) { 00323 00324 if (size >= cbw.DataLength) { 00325 size = cbw.DataLength; 00326 } 00327 stage = SEND_CSW; 00328 00329 if (!writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) { 00330 return false; 00331 } 00332 00333 csw.DataResidue -= size; 00334 csw.Status = CSW_PASSED; 00335 return true; 00336 } 00337 00338 00339 bool USBMSD::modeSense6 (void) { 00340 uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 }; 00341 if (!write(sense6, sizeof(sense6))) { 00342 return false; 00343 } 00344 return true; 00345 } 00346 00347 void USBMSD::sendCSW() { 00348 csw.Signature = CSW_Signature; 00349 writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK); 00350 stage = WAIT_CSW; 00351 } 00352 00353 bool USBMSD::requestSense (void) { 00354 uint8_t request_sense[] = { 00355 0x70, 00356 0x00, 00357 0x05, // Sense Key: illegal request 00358 0x00, 00359 0x00, 00360 0x00, 00361 0x00, 00362 0x0A, 00363 0x00, 00364 0x00, 00365 0x00, 00366 0x00, 00367 0x30, 00368 0x01, 00369 0x00, 00370 0x00, 00371 0x00, 00372 0x00, 00373 }; 00374 00375 if (!write(request_sense, sizeof(request_sense))) { 00376 return false; 00377 } 00378 00379 return true; 00380 } 00381 00382 void USBMSD::fail() { 00383 csw.Status = CSW_FAILED; 00384 sendCSW(); 00385 } 00386 00387 00388 void USBMSD::CBWDecode(uint8_t * buf, uint16_t size) { 00389 if (size == sizeof(cbw)) { 00390 memcpy((uint8_t *)&cbw, buf, size); 00391 if (cbw.Signature == CBW_Signature) { 00392 csw.Tag = cbw.Tag; 00393 csw.DataResidue = cbw.DataLength; 00394 if ((cbw.CBLength < 1) || (cbw.CBLength > 16) ) { 00395 fail(); 00396 } else { 00397 switch (cbw.CB[0]) { 00398 case TEST_UNIT_READY: 00399 testUnitReady(); 00400 break; 00401 case REQUEST_SENSE: 00402 requestSense(); 00403 break; 00404 case INQUIRY: 00405 inquiryRequest(); 00406 break; 00407 case MODE_SENSE6: 00408 modeSense6(); 00409 break; 00410 case READ_FORMAT_CAPACITIES: 00411 readFormatCapacity(); 00412 break; 00413 case READ_CAPACITY: 00414 readCapacity(); 00415 break; 00416 case READ10: 00417 case READ12: 00418 if (infoTransfer()) { 00419 if ((cbw.Flags & 0x80)) { 00420 stage = PROCESS_CBW; 00421 memoryRead(); 00422 } else { 00423 stallEndpoint(EPBULK_OUT); 00424 csw.Status = CSW_ERROR; 00425 sendCSW(); 00426 } 00427 } 00428 break; 00429 case WRITE10: 00430 case WRITE12: 00431 if (infoTransfer()) { 00432 if (!(cbw.Flags & 0x80)) { 00433 stage = PROCESS_CBW; 00434 } else { 00435 stallEndpoint(EPBULK_IN); 00436 csw.Status = CSW_ERROR; 00437 sendCSW(); 00438 } 00439 } 00440 break; 00441 case VERIFY10: 00442 if (!(cbw.CB[1] & 0x02)) { 00443 csw.Status = CSW_PASSED; 00444 sendCSW(); 00445 break; 00446 } 00447 if (infoTransfer()) { 00448 if (!(cbw.Flags & 0x80)) { 00449 stage = PROCESS_CBW; 00450 memOK = true; 00451 } else { 00452 stallEndpoint(EPBULK_IN); 00453 csw.Status = CSW_ERROR; 00454 sendCSW(); 00455 } 00456 } 00457 break; 00458 case MEDIA_REMOVAL: 00459 csw.Status = CSW_PASSED; 00460 sendCSW(); 00461 break; 00462 default: 00463 fail(); 00464 break; 00465 } 00466 } 00467 } 00468 } 00469 } 00470 00471 void USBMSD::testUnitReady (void) { 00472 00473 if (cbw.DataLength != 0) { 00474 if ((cbw.Flags & 0x80) != 0) { 00475 stallEndpoint(EPBULK_IN); 00476 } else { 00477 stallEndpoint(EPBULK_OUT); 00478 } 00479 } 00480 00481 csw.Status = CSW_PASSED; 00482 sendCSW(); 00483 } 00484 00485 00486 void USBMSD::memoryRead (void) { 00487 uint32_t n; 00488 00489 n = (length > MAX_PACKET) ? MAX_PACKET : length; 00490 00491 if ((addr + n) > MemorySize) { 00492 n = MemorySize - addr; 00493 stage = ERROR; 00494 } 00495 00496 // we read an entire block 00497 if (!(addr%BlockSize)) 00498 disk_read((char *)page, addr/BlockSize); 00499 00500 // write data which are in RAM 00501 writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK); 00502 00503 addr += n; 00504 length -= n; 00505 00506 csw.DataResidue -= n; 00507 00508 if ( !length || (stage != PROCESS_CBW)) { 00509 csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED; 00510 stage = (stage == PROCESS_CBW) ? SEND_CSW : stage; 00511 } 00512 } 00513 00514 00515 bool USBMSD::infoTransfer (void) { 00516 uint32_t n; 00517 00518 // Logical Block Address of First Block 00519 n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] << 8) | (cbw.CB[5] << 0); 00520 00521 addr = n * BlockSize; 00522 00523 // Number of Blocks to transfer 00524 switch (cbw.CB[0]) { 00525 case READ10: 00526 case WRITE10: 00527 case VERIFY10: 00528 n = (cbw.CB[7] << 8) | (cbw.CB[8] << 0); 00529 break; 00530 00531 case READ12: 00532 case WRITE12: 00533 n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] << 8) | (cbw.CB[9] << 0); 00534 break; 00535 } 00536 00537 length = n * BlockSize; 00538 00539 if (!cbw.DataLength) { // host requests no data 00540 csw.Status = CSW_FAILED; 00541 sendCSW(); 00542 return false; 00543 } 00544 00545 if (cbw.DataLength != length) { 00546 if ((cbw.Flags & 0x80) != 0) { 00547 stallEndpoint(EPBULK_IN); 00548 } else { 00549 stallEndpoint(EPBULK_OUT); 00550 } 00551 00552 csw.Status = CSW_FAILED; 00553 sendCSW(); 00554 return false; 00555 } 00556 00557 return true; 00558 } 00559 00560 00561 00562 00563 00564 // Called in ISR context 00565 // Set configuration. Return false if the 00566 // configuration is not supported. 00567 bool USBMSD::USBCallback_setConfiguration(uint8_t configuration) { 00568 if (configuration != DEFAULT_CONFIGURATION) { 00569 return false; 00570 } 00571 00572 // Configure endpoints > 0 00573 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); 00574 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00575 00576 //activate readings 00577 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00578 return true; 00579 } 00580 00581 00582 uint8_t * USBMSD::stringIinterfaceDesc() { 00583 static uint8_t stringIinterfaceDescriptor[] = { 00584 0x08, //bLength 00585 STRING_DESCRIPTOR, //bDescriptorType 0x03 00586 'M',0,'S',0,'D',0 //bString iInterface - MSD 00587 }; 00588 return stringIinterfaceDescriptor; 00589 } 00590 00591 uint8_t * USBMSD::stringIproductDesc() { 00592 static uint8_t stringIproductDescriptor[] = { 00593 0x12, //bLength 00594 STRING_DESCRIPTOR, //bDescriptorType 0x03 00595 'M',0,'b',0,'e',0,'d',0,' ',0,'M',0,'S',0,'D',0 //bString iProduct - Mbed Audio 00596 }; 00597 return stringIproductDescriptor; 00598 } 00599 00600 00601 uint8_t * USBMSD::configurationDesc() { 00602 static uint8_t configDescriptor[] = { 00603 00604 // Configuration 1 00605 9, // bLength 00606 2, // bDescriptorType 00607 LSB(9 + 9 + 7 + 7), // wTotalLength 00608 MSB(9 + 9 + 7 + 7), 00609 0x01, // bNumInterfaces 00610 0x01, // bConfigurationValue: 0x01 is used to select this configuration 00611 0x00, // iConfiguration: no string to describe this configuration 00612 0xC0, // bmAttributes 00613 100, // bMaxPower, device power consumption is 100 mA 00614 00615 // Interface 0, Alternate Setting 0, MSC Class 00616 9, // bLength 00617 4, // bDescriptorType 00618 0x00, // bInterfaceNumber 00619 0x00, // bAlternateSetting 00620 0x02, // bNumEndpoints 00621 0x08, // bInterfaceClass 00622 0x06, // bInterfaceSubClass 00623 0x50, // bInterfaceProtocol 00624 0x04, // iInterface 00625 00626 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00627 7, // bLength 00628 5, // bDescriptorType 00629 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress 00630 0x02, // bmAttributes (0x02=bulk) 00631 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00632 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00633 0, // bInterval 00634 00635 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00636 7, // bLength 00637 5, // bDescriptorType 00638 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress 00639 0x02, // bmAttributes (0x02=bulk) 00640 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00641 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00642 0 // bInterval 00643 }; 00644 return configDescriptor; 00645 }
Generated on Tue Jul 12 2022 21:32:44 by 1.7.2