USB lib Joerg
Fork of USBHost_DISCO-F746NG by
Diff: USBHostMSD/USBHostMSD.cpp
- Revision:
- 25:7d6d9fc471bf
- Parent:
- 24:5396b6a93262
diff -r 5396b6a93262 -r 7d6d9fc471bf USBHostMSD/USBHostMSD.cpp --- a/USBHostMSD/USBHostMSD.cpp Mon Jun 13 17:21:07 2016 +0000 +++ b/USBHostMSD/USBHostMSD.cpp Fri Jun 17 09:00:35 2016 +0000 @@ -23,13 +23,14 @@ #define CBW_SIGNATURE 0x43425355 #define CSW_SIGNATURE 0x53425355 + #define DEVICE_TO_HOST 0x80 #define HOST_TO_DEVICE 0x00 #define GET_MAX_LUN (0xFE) #define BO_MASS_STORAGE_RESET (0xFF) -USBHostMSD::USBHostMSD(int Interface,const char * rootdir) : FATFileSystem(rootdir) +USBHostMSD::USBHostMSD(const char * rootdir,int Interface) : FATFileSystem(rootdir) { host = USBHost::getHostInst(Interface); init(); @@ -65,19 +66,19 @@ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { - + USB_DBG("Trying to connect MSD device\r\n"); - + if(host->enumerate(dev, this)) break; if (msd_device_found) { bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN); bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT); - + if (!bulk_in || !bulk_out) continue; - + USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf); dev->setName("MSD", msd_intf); host->registerDriver(dev, msd_intf, this, &USBHostMSD::init); @@ -122,9 +123,74 @@ } -int USBHostMSD::testUnitReady() { +int USBHostMSD::testUnitReady(int i) { USB_DBG("Test unit ready"); - return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0); + uint8_t cmd[6] = {0,0,0,0,0,0}; + //SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) + //return SCSITransfer(cmd, 6, DEVICE_TO_HOST, 0, 0); + int res = 0; + + cbw.Signature = CBW_SIGNATURE; + cbw.Tag = 0; + cbw.DataLength = 0; + cbw.Flags = DEVICE_TO_HOST; + cbw.LUN = 0; + cbw.CBLength = 6; + memset(cbw.CB,0,sizeof(cbw.CB)); + if (cmd) { + memcpy(cbw.CB,cmd,6); + } + + // send the cbw + USB_DBG("Send CBW"); + res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31); + if (checkResult(res, bulk_out)) + return -1; + + wait_ms(6000*i); + + // status stage + csw.Signature = 0; + USB_DBG("Read CSW"); + res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13); + if (checkResult(res, bulk_in)) + return -1; + + if (csw.Signature != CSW_SIGNATURE) { + return -1; + } + + USB_DBG("recv csw: status: %d", csw.Status); + + // ModeSense? + if ((csw.Status == 1) && (cmd[0] != 0x03)) { + USB_DBG("request mode sense"); + return SCSIRequestSense(); + } + + // perform reset recovery + if ((csw.Status == 2) && (cmd[0] != 0x03)) { + + // send Bulk-Only Mass Storage Reset request + res = host->controlWrite( dev, + USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, + BO_MASS_STORAGE_RESET, + 0, msd_intf, NULL, 0); + + // unstall both endpoints + res = host->controlWrite( dev, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + CLEAR_FEATURE, + 0, bulk_in->getAddress(), NULL, 0); + + res = host->controlWrite( dev, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + CLEAR_FEATURE, + 0, bulk_out->getAddress(), NULL, 0); + + } + + return csw.Status; } @@ -219,7 +285,7 @@ if (data) { USB_DBG("data stage"); if (flags == HOST_TO_DEVICE) { - + res = host->bulkWrite(dev, bulk_out, data, transfer_len); if (checkResult(res, bulk_out)) return -1; @@ -242,7 +308,7 @@ if (csw.Signature != CSW_SIGNATURE) { return -1; } - + USB_DBG("recv csw: status: %d", csw.Status); // ModeSense? @@ -250,34 +316,34 @@ USB_DBG("request mode sense"); return SCSIRequestSense(); } - + // perform reset recovery if ((csw.Status == 2) && (cmd[0] != 0x03)) { - + // send Bulk-Only Mass Storage Reset request res = host->controlWrite( dev, USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, BO_MASS_STORAGE_RESET, 0, msd_intf, NULL, 0); - + // unstall both endpoints res = host->controlWrite( dev, USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, CLEAR_FEATURE, 0, bulk_in->getAddress(), NULL, 0); - + res = host->controlWrite( dev, USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, CLEAR_FEATURE, 0, bulk_out->getAddress(), NULL, 0); - + } return csw.Status; } -int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) { +int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint32_t nbBlock, int direction) { uint8_t cmd[10]; memset(cmd,0,10); cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A; @@ -304,20 +370,29 @@ int USBHostMSD::disk_initialize() { USB_DBG("FILESYSTEM: init"); /* U16 */int i, timeout = 10; - + getMaxLun(); - + for (i = 0; i < timeout; i++) { wait_ms(100); //Thread::wait(100); - if (!testUnitReady()) + if (!testUnitReady(i+1)) break; + printf("TestUnitReady %d\r\n",i); + if(i>1) + { + host->controlWrite( dev, + USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, + BO_MASS_STORAGE_RESET, + 0, msd_intf, NULL, 0); + + }; } - + if (i == timeout) { disk_init = false; return -1; } - + inquiry(0, 0); disk_init = 1; return readCapacity(); @@ -330,7 +405,9 @@ } if (!disk_init) return -1; - return dataTransfer((uint8_t *)buffer, sector, count, HOST_TO_DEVICE); + if (count>0x800000) + return -1; + return dataTransfer((uint8_t *)buffer, sector,(uint32_t) count, HOST_TO_DEVICE); } int USBHostMSD::disk_read(uint8_t * buffer, uint64_t sector, uint8_t count) { @@ -340,9 +417,12 @@ } if (!disk_init) return -1; - return dataTransfer((uint8_t *)buffer, sector, count, DEVICE_TO_HOST); + if (count>0x800000) + return -1; + return dataTransfer((uint8_t *)buffer, sector,(uint32_t) count, DEVICE_TO_HOST); } + uint64_t USBHostMSD::disk_sectors() { USB_DBG("FILESYSTEM: sectors"); if (!disk_init) {