| #define println USBHost::println_ | #define println USBHost::println_ | ||||
| // Uncomment this to display function usage and sequencing. | // Uncomment this to display function usage and sequencing. | ||||
| //#define DBGprint 1 | |||||
| #define DBGprint 1 | |||||
| // Big Endian/Little Endian | // Big Endian/Little Endian | ||||
| #define swap32(x) ((x >> 24) & 0xff) | \ | #define swap32(x) ((x >> 24) & 0xff) | \ | ||||
| msDriveInfo.initialized = false; | msDriveInfo.initialized = false; | ||||
| msDriveInfo.connected = true; | msDriveInfo.connected = true; | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf(" connected %d\n",msDriveInfo.connected); | |||||
| Serial.printf(" initialized %d\n",msDriveInfo.initialized); | |||||
| print(" connected = "); | |||||
| println(msDriveInfo.connected); | |||||
| print(" initialized = "); | |||||
| println(msDriveInfo.initialized); | |||||
| #endif | #endif | ||||
| return true; | return true; | ||||
| } | } | ||||
| memset(&msDriveInfo, 0, sizeof(msDriveInfo_t)); | memset(&msDriveInfo, 0, sizeof(msDriveInfo_t)); | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf(" connected %d\n",msDriveInfo.connected); | |||||
| Serial.printf(" initialized %d\n",msDriveInfo.initialized); | |||||
| print(" connected "); | |||||
| println(msDriveInfo.connected); | |||||
| print(" initialized "); | |||||
| println(msDriveInfo.initialized); | |||||
| #endif | #endif | ||||
| } | } | ||||
| // Initialize Mass Storage Device | // Initialize Mass Storage Device | ||||
| uint8_t msController::mscInit(void) { | uint8_t msController::mscInit(void) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("mscIint()\n"); | |||||
| println("mscIint()"); | |||||
| #endif | #endif | ||||
| uint8_t msResult = MS_CBW_PASS; | uint8_t msResult = MS_CBW_PASS; | ||||
| } while(!available()); | } while(!available()); | ||||
| msReset(0); // Assume bNumInterfaces = 1 for now. | msReset(0); // Assume bNumInterfaces = 1 for now. | ||||
| delay(500); | |||||
| // delay(500); // Not needed any more. | |||||
| maxLUN = msGetMaxLun(0); // Assume bNumInterfaces = 1 for now | maxLUN = msGetMaxLun(0); // Assume bNumInterfaces = 1 for now | ||||
| // msResult = msReportLUNs(&maxLUN); | // msResult = msReportLUNs(&maxLUN); | ||||
| //Serial.printf("maxLUN = %d\n",maxLUN); | |||||
| //println("maxLUN = "); | |||||
| //println(maxLUN); | |||||
| // delay(150); | // delay(150); | ||||
| //------------------------------------------------------- | //------------------------------------------------------- | ||||
| // msResult = msStartStopUnit(1); | |||||
| msResult = msStartStopUnit(1); | |||||
| msResult = WaitMediaReady(); | msResult = WaitMediaReady(); | ||||
| if(msResult) | if(msResult) | ||||
| return msResult; | return msResult; | ||||
| // Perform Mass Storage Reset | // Perform Mass Storage Reset | ||||
| void msController::msReset(uint32_t interfaceNumber) { | void msController::msReset(uint32_t interfaceNumber) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msReset()\n"); | |||||
| println("msReset()"); | |||||
| #endif | #endif | ||||
| mk_setup(setup, 0x21, 0xff, 0, interfaceNumber, 0); | mk_setup(setup, 0x21, 0xff, 0, interfaceNumber, 0); | ||||
| queue_Control_Transfer(device, &setup, NULL, this); | queue_Control_Transfer(device, &setup, NULL, this); | ||||
| // Get MAX LUN | // Get MAX LUN | ||||
| uint8_t msController::msGetMaxLun(uint32_t interfaceNumber) { | uint8_t msController::msGetMaxLun(uint32_t interfaceNumber) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msGetMaxLun()\n"); | |||||
| println("msGetMaxLun()"); | |||||
| #endif | #endif | ||||
| report[0] = 0; | report[0] = 0; | ||||
| mk_setup(setup, 0xa1, 0xfe, 0, interfaceNumber, 1); | mk_setup(setup, 0xa1, 0xfe, 0, interfaceNumber, 1); | ||||
| uint8_t msResult; | uint8_t msResult; | ||||
| uint32_t start = millis(); | uint32_t start = millis(); | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("WaitMediaReady()\n"); | |||||
| println("WaitMediaReady()"); | |||||
| #endif | #endif | ||||
| do { | do { | ||||
| if((millis() - start) >= MEDIA_READY_TIMEOUT) { | if((millis() - start) >= MEDIA_READY_TIMEOUT) { | ||||
| uint8_t msController::checkConnectedInitialized(void) { | uint8_t msController::checkConnectedInitialized(void) { | ||||
| uint8_t msResult = MS_CBW_PASS; | uint8_t msResult = MS_CBW_PASS; | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("checkConnectedInitialized()\n"); | |||||
| print("checkConnectedInitialized()"); | |||||
| #endif | #endif | ||||
| if(!msDriveInfo.connected) { | if(!msDriveInfo.connected) { | ||||
| return MS_NO_MEDIA_ERR; | return MS_NO_MEDIA_ERR; | ||||
| uint8_t CSWResult = 0; | uint8_t CSWResult = 0; | ||||
| mscTransferComplete = false; | mscTransferComplete = false; | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msDoCommand():\n"); | |||||
| println("msDoCommand()"); | |||||
| #endif | #endif | ||||
| if(CBWTag == 0xFFFFFFFF) CBWTag = 1; | if(CBWTag == 0xFFFFFFFF) CBWTag = 1; | ||||
| queue_Data_Transfer(datapipeOut, CBW, sizeof(msCommandBlockWrapper_t), this); // Command stage. | queue_Data_Transfer(datapipeOut, CBW, sizeof(msCommandBlockWrapper_t), this); // Command stage. | ||||
| // Get Command Status Wrapper | // Get Command Status Wrapper | ||||
| uint8_t msController::msGetCSW(void) { | uint8_t msController::msGetCSW(void) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msGetCSW()\n"); | |||||
| println("msGetCSW()"); | |||||
| #endif | #endif | ||||
| msCommandStatusWrapper_t StatusBlockWrapper = (msCommandStatusWrapper_t) | msCommandStatusWrapper_t StatusBlockWrapper = (msCommandStatusWrapper_t) | ||||
| { | { | ||||
| // Test Unit Ready | // Test Unit Ready | ||||
| uint8_t msController::msTestReady() { | uint8_t msController::msTestReady() { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msTestReady()\n"); | |||||
| println("msTestReady()"); | |||||
| #endif | #endif | ||||
| msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | ||||
| { | { | ||||
| // Start/Stop unit | // Start/Stop unit | ||||
| uint8_t msController::msStartStopUnit(uint8_t mode) { | uint8_t msController::msStartStopUnit(uint8_t mode) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msStartStopUnit()\n"); | |||||
| println("msStartStopUnit()"); | |||||
| #endif | #endif | ||||
| msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | ||||
| { | { | ||||
| // Read Mass Storage Device Capacity (Number of Blocks and Block Size) | // Read Mass Storage Device Capacity (Number of Blocks and Block Size) | ||||
| uint8_t msController::msReadDeviceCapacity(msSCSICapacity_t * const Capacity) { | uint8_t msController::msReadDeviceCapacity(msSCSICapacity_t * const Capacity) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msReadDeviceCapacity()\n"); | |||||
| println("msReadDeviceCapacity()"); | |||||
| #endif | #endif | ||||
| uint8_t result = 0; | uint8_t result = 0; | ||||
| msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | ||||
| uint8_t msController::msDeviceInquiry(msInquiryResponse_t * const Inquiry) | uint8_t msController::msDeviceInquiry(msInquiryResponse_t * const Inquiry) | ||||
| { | { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msDeviceInquiry()\n"); | |||||
| println("msDeviceInquiry()"); | |||||
| #endif | #endif | ||||
| msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | ||||
| { | { | ||||
| uint8_t msController::msRequestSense(msRequestSenseResponse_t * const Sense) | uint8_t msController::msRequestSense(msRequestSenseResponse_t * const Sense) | ||||
| { | { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msRequestSense()\n"); | |||||
| println("msRequestSense()"); | |||||
| #endif | #endif | ||||
| msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | ||||
| { | { | ||||
| uint8_t msController::msReportLUNs(uint8_t *Buffer) | uint8_t msController::msReportLUNs(uint8_t *Buffer) | ||||
| { | { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msReportLuns()\n"); | |||||
| println("msReportLuns()"); | |||||
| #endif | #endif | ||||
| msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t) | ||||
| { | { | ||||
| void * sectorBuffer) | void * sectorBuffer) | ||||
| { | { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msReadBlocks()\n"); | |||||
| println("msReadBlocks()"); | |||||
| #endif | #endif | ||||
| uint8_t BlockHi = (Blocks >> 8) & 0xFF; | uint8_t BlockHi = (Blocks >> 8) & 0xFF; | ||||
| uint8_t BlockLo = Blocks & 0xFF; | uint8_t BlockLo = Blocks & 0xFF; | ||||
| const void * sectorBuffer) | const void * sectorBuffer) | ||||
| { | { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msWriteBlocks()\n"); | |||||
| println("msWriteBlocks()"); | |||||
| #endif | #endif | ||||
| uint8_t BlockHi = (Blocks >> 8) & 0xFF; | uint8_t BlockHi = (Blocks >> 8) & 0xFF; | ||||
| uint8_t BlockLo = Blocks & 0xFF; | uint8_t BlockLo = Blocks & 0xFF; | ||||
| // Proccess Possible SCSI errors | // Proccess Possible SCSI errors | ||||
| uint8_t msController::msProcessError(uint8_t msStatus) { | uint8_t msController::msProcessError(uint8_t msStatus) { | ||||
| #ifdef DBGprint | #ifdef DBGprint | ||||
| Serial.printf("msProcessError()\n"); | |||||
| println("msProcessError()"); | |||||
| #endif | #endif | ||||
| uint8_t msResult = 0; | uint8_t msResult = 0; | ||||
| switch(msStatus) { | switch(msStatus) { | ||||
| return MS_CBW_PASS; | return MS_CBW_PASS; | ||||
| break; | break; | ||||
| case MS_CBW_PHASE_ERROR: | case MS_CBW_PHASE_ERROR: | ||||
| Serial.printf("SCSI Phase Error: %d\n",msStatus); | |||||
| print("SCSI Phase Error: "); | |||||
| println(msStatus); | |||||
| return MS_SCSI_ERROR; | return MS_SCSI_ERROR; | ||||
| break; | break; | ||||
| case MS_CSW_TAG_ERROR: | case MS_CSW_TAG_ERROR: | ||||
| Serial.printf("CSW Tag Error: %d\n",MS_CSW_TAG_ERROR); | |||||
| print("CSW Tag Error: "); | |||||
| println(MS_CSW_TAG_ERROR); | |||||
| return MS_CSW_TAG_ERROR; | return MS_CSW_TAG_ERROR; | ||||
| break; | break; | ||||
| case MS_CSW_SIG_ERROR: | case MS_CSW_SIG_ERROR: | ||||
| Serial.printf("CSW Signature Error: %d\n",MS_CSW_SIG_ERROR); | |||||
| print("CSW Signature Error: "); | |||||
| println(MS_CSW_SIG_ERROR); | |||||
| return MS_CSW_SIG_ERROR; | return MS_CSW_SIG_ERROR; | ||||
| break; | break; | ||||
| case MS_CBW_FAIL: | case MS_CBW_FAIL: | ||||
| if(msResult = msRequestSense(&msSense)) | |||||
| Serial.printf("Failed to get sense codes. Returned code: %d\n",msResult); | |||||
| if(msResult = msRequestSense(&msSense)) { | |||||
| print("Failed to get sense codes. Returned code: "); | |||||
| println(msResult); | |||||
| } | |||||
| return MS_CBW_FAIL; | return MS_CBW_FAIL; | ||||
| break; | break; | ||||
| default: | default: | ||||
| Serial.printf("SCSI Error: %d\n",msStatus); | |||||
| print("SCSI Error: "); | |||||
| println(msStatus); | |||||
| return msStatus; | return msStatus; | ||||
| } | } | ||||
| } | } |