BaseJpegDeocde exampe program
Dependencies: BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos
Fork of BaseJpegDecode by
Diff: msc/msc.cpp
- Revision:
- 6:95be1cd2bc14
- Parent:
- 4:7d88de31c55a
--- a/msc/msc.cpp Thu Nov 15 10:20:38 2012 +0000 +++ b/msc/msc.cpp Wed Dec 05 12:41:25 2012 +0000 @@ -1,390 +1,390 @@ -#include "msc.h" -//#define __DEBUG -#include "mydbg.h" -#include "Utils.h" - -//#define WRITE_PROTECT - -msc::msc(const char* name, int drive): FATFileSystem(name) -{ - DBG("drive=%d\n", drive); - m_name = name; - m_drive = drive; - DBG_ASSERT(sizeof(CBW) == 31); - DBG_ASSERT(sizeof(CSW) == 13); - m_numBlocks = 0; - m_BlockSize = 0; - m_lun = 0; - m_interface = 0; - m_pDev = NULL; - m_pEpBulkIn = NULL; - m_pEpBulkOut = NULL; -} - -int msc::disk_initialize() -{ - DBG("m_BlockSize=%d\n", m_BlockSize); - if (m_BlockSize != 512) { - return 1; - } - return 0; -} - -int msc::disk_write(const char *buffer, int block_number) -{ - DBG("buffer=%p block_number=%d\n", buffer, block_number); - int ret = MS_BulkSend(block_number, 1, (uint8_t*)buffer); - if (ret >= 0) { - return 0; - } - return 1; -} - -int msc::disk_read(char *buffer, int block_number) -{ - DBG("buffer=%p block_number=%d\n", buffer, block_number); - int ret = MS_BulkRecv(block_number, 1, (uint8_t*)buffer); - if (ret >= 0) { - return 0; - } - return 1; -} - -int msc::disk_status() -{ - DBG("\n"); - return 0; -} - -int msc::disk_sync() -{ - DBG("\n"); - return 0; -} - -int msc::disk_sectors() -{ - DBG("m_numBlocks=%d\n", m_numBlocks); - return m_numBlocks; -} - -int msc::setup(int timeout) -{ - for(int i = 0; i < 2; i++) { - m_pDev = m_pHost->getDeviceByClass(0x08, m_drive); // USB Mass Storage Class - if (m_pDev || i > 0) { - break; - } - UsbErr rc = Usb_poll(); - if (rc == USBERR_PROCESSING) { - VERBOSE("%p USBERR_PROCESSING\n", this); - return -1; - } - } - DBG("m_pDev=%p\n", m_pDev); - if (m_pDev == NULL) { - VERBOSE("%p MSC DISK(%d) NOT FOUND\n", this, m_drive); - return -1; - } - DBG_ASSERT(m_pDev); - - ParseConfiguration(); - - GetMaxLUN(); - - int retry = 0; - Timer t; - t.start(); - t.reset(); - while(t.read_ms() < timeout) { - DBG("retry=%d t=%d\n", retry, t.read_ms()); - if (retry > 80) { - return -1; - } - int rc = TestUnitReady(); - DBG("TestUnitReady(): %d\n", rc); - if (rc == USBERR_OK) { - DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus); - if (m_CSW.bCSWStatus == 0x00) { - break; - } - } - GetSenseInfo(); - retry++; - wait_ms(50); - } - if (t.read_ms() >= timeout) { - return -1; - } - ReadCapacity(); - Inquire(); - return 0; -} -void msc::_test() -{ - ReadCapacity(); - - char buf[512]; - for(int block = 0; block < m_numBlocks; block++) { - DBG("block=%d\n", block); - disk_read(buf, block); - } - exit(1); -} - -int msc::ParseConfiguration() -{ - UsbErr rc; - uint8_t ConfigDesc[9]; - int index = 0; - DBG_ASSERT(m_pDev); - rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); - DBG_ASSERT(ConfigDesc[0] == 9); - DBG_ASSERT(ConfigDesc[1] == 0x02); - int wTotalLength = *((uint16_t*)&ConfigDesc[2]); - DBG("TotalLength: %d\n", wTotalLength); - int bConfigValue = ConfigDesc[5]; - DBG_ASSERT(bConfigValue == 1); - DBG("ConfigValue: %d\n", bConfigValue); - DBG("MaxPower: %d mA\n", ConfigDesc[8]*2); - - uint8_t* buf = new uint8_t[wTotalLength]; - DBG_ASSERT(buf); - rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); - DBG_ASSERT(rc == USBERR_OK); - DBG_ASSERT(ConfigDesc[1] == 0x02); - for (int pos = 0; pos < wTotalLength; pos += buf[pos]) { - DBG_BYTES("CFG", buf+pos, buf[pos]); - int type = buf[pos+1]; - if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04 - DBG("InterfaceNumber: %d\n", buf[pos+2]); - DBG("AlternateSetting: %d\n", buf[pos+3]); - DBG("NumEndpoint: %d\n", buf[pos+4]); - DBG("InterfaceClass: %02X\n", buf[pos+5]); - DBG("InterfaceSubClass: %02X\n", buf[pos+6]); - DBG("InterfaceProtocol: %02X\n", buf[pos+7]); - DBG_ASSERT(buf[pos+6] == 0x06); // SCSI - DBG_ASSERT(buf[pos+7] == 0x50); // bulk only - } - if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) { - DBG_ASSERT(buf[pos] == 7); - uint8_t att = buf[pos+3]; - if (att == 2) { // bulk - uint8_t ep = buf[pos+2]; - bool dir = ep & 0x80; // true=IN - uint16_t size = LE16(buf+pos+4); - DBG("EndpointAddress: %02X\n", ep); - DBG("Attribute: %02X\n", att); - DBG("MaxPacketSize: %d\n", size); - UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, USB_BULK, size); - DBG_ASSERT(pEp); - if (dir) { - m_pEpBulkIn = pEp; - } else { - m_pEpBulkOut = pEp; - } - } - } - } - delete[] buf; - DBG_ASSERT(m_pEpBulkIn); - DBG_ASSERT(m_pEpBulkOut); - return 0; -} - -int msc::BulkOnlyMassStorageReset() -{ - DBG_ASSERT(m_pDev); - UsbErr rc = m_pDev->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); - DBG_ASSERT(rc == USBERR_OK); - return rc; -} - -int msc::GetMaxLUN() -{ - DBG_ASSERT(m_interface == 0); - uint8_t temp[1]; - DBG_ASSERT(m_pDev); - UsbErr rc = m_pDev->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("GetMaxLUN", temp, sizeof(temp)); - m_MaxLUN = temp[0]; - DBG_ASSERT(m_MaxLUN <= 15); - return rc; -} - - -int msc::TestUnitReady() -{ - const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00}; - m_CBW.dCBWDataTraansferLength = 0; - m_CBW.bmCBWFlags = 0x00; - CommandTransport(cdb, sizeof(cdb)); - StatusTransport(); - return 0; -} - -int msc::GetSenseInfo() -{ - const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00}; - m_CBW.dCBWDataTraansferLength = 18; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - uint8_t buf[18]; - _bulkRecv(buf, sizeof(buf)); - DBG_HEX(buf, sizeof(buf)); - - StatusTransport(); - DBG_ASSERT(m_CSW.bCSWStatus == 0x00); - return 0; -} - -int msc::ReadCapacity() -{ - const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}; - m_CBW.dCBWDataTraansferLength = 8; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - uint8_t buf[8]; - int rc = _bulkRecv(buf, sizeof(buf)); - DBG_ASSERT(rc >= 0); - DBG_HEX(buf, sizeof(buf)); - - StatusTransport(); - DBG_ASSERT(m_CSW.bCSWStatus == 0x00); - - m_numBlocks = BE32(buf); - m_BlockSize = BE32(buf+4); - DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize); - DBG_ASSERT(m_BlockSize == 512); - DBG_ASSERT(m_numBlocks > 0); - return 0; -} - -int msc::Inquire() -{ - const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00}; - m_CBW.dCBWDataTraansferLength = 36; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - uint8_t buf[36]; - _bulkRecv(buf, sizeof(buf)); - DBG_HEX(buf, sizeof(buf)); - - StatusTransport(); - return 0; -} - -int msc::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer) -{ - DBG_ASSERT(m_BlockSize == 512); - DBG_ASSERT(num_blocks == 1); - DBG_ASSERT(user_buffer); - uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}; - BE32(block_number, cdb+2); - BE16(num_blocks, cdb+7); - uint32_t len = m_BlockSize * num_blocks; - DBG_ASSERT(len <= 512); - m_CBW.dCBWDataTraansferLength = len; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - int ret = _bulkRecv(user_buffer, len); - //DBG_HEX(user_buffer, len); - - StatusTransport(); - DBG_ASSERT(m_CSW.bCSWStatus == 0x00); - return ret; -} - -int msc::MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer) -{ -#ifdef WRITE_PROTECT - return 0; -#else - DBG_ASSERT(num_blocks == 1); - DBG_ASSERT(user_buffer); - uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}; - BE32(block_number, cdb+2); - BE16(num_blocks, cdb+7); - uint32_t len = m_BlockSize * num_blocks; - DBG_ASSERT(len <= 512); - m_CBW.dCBWDataTraansferLength = len; - m_CBW.bmCBWFlags = 0x00; // data Out - CommandTransport(cdb, sizeof(cdb)); - - int ret = _bulkSend(user_buffer, len); - //DBG_HEX(user_buffer, len); - - StatusTransport(); - DBG_ASSERT(m_CSW.bCSWStatus == 0x00); - return ret; -#endif //WRITE_PROTECT -} - -int msc::CommandTransport(const uint8_t* cdb, int size) -{ - DBG_ASSERT(cdb); - DBG_ASSERT(size >= 6); - DBG_ASSERT(size <= 16); - m_CBW.bCBWLUN = m_lun; - m_CBW.bCBWCBLength = size; - memcpy(m_CBW.CBWCB, cdb, size); - - m_CBW.dCBWSignature = 0x43425355; - m_CBW.dCBWTag = m_tag++; - m_CBW.bCBWLUN = 0; - //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW)); - int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW)); - return rc; -} - -int msc::StatusTransport() -{ - DBG_ASSERT(sizeof(CSW) == 13); - int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW)); - //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW)); - DBG_ASSERT(m_CSW.dCSWSignature == 0x53425355); - DBG_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag); - DBG_ASSERT(m_CSW.dCSWDataResidue == 0); - return rc; -} - -int msc::_bulkRecv(uint8_t* buf, int size) -{ - UsbErr rc = m_pEpBulkIn->transfer(buf, size); - DBG_ASSERT(rc == USBERR_PROCESSING); - while(m_pEpBulkIn->status() == USBERR_PROCESSING){ - wait_us(1); - } - int ret = m_pEpBulkIn->status(); - if (ret >= 0) { - return ret; - } - DBG("buf=%p size=%d ret=%d\n", buf, size, ret); - return ret; -} - -int msc::_bulkSend(uint8_t* buf, int size) -{ - DBG_ASSERT(m_pEpBulkOut); - UsbErr rc = m_pEpBulkOut->transfer(buf, size); - DBG_ASSERT(rc == USBERR_PROCESSING); - while(m_pEpBulkOut->status() == USBERR_PROCESSING){ - wait_us(1); - } - int ret = m_pEpBulkOut->status(); - if (ret >= 0) { - return ret; - } - DBG("buf=%p size=%d ret=%d\n", buf, size, ret); - return ret; -} +#include "msc.h" +//#define __DEBUG +#include "mydbg.h" +#include "Utils.h" + +//#define WRITE_PROTECT + +msc::msc(const char* name, int drive): FATFileSystem(name) +{ + DBG("drive=%d\n", drive); + m_name = name; + m_drive = drive; + DBG_ASSERT(sizeof(CBW) == 31); + DBG_ASSERT(sizeof(CSW) == 13); + m_numBlocks = 0; + m_BlockSize = 0; + m_lun = 0; + m_interface = 0; + m_pDev = NULL; + m_pEpBulkIn = NULL; + m_pEpBulkOut = NULL; +} + +int msc::disk_initialize() +{ + DBG("m_BlockSize=%d\n", m_BlockSize); + if (m_BlockSize != 512) { + return 1; + } + return 0; +} + +int msc::disk_write(const uint8_t *buffer, uint64_t block_number) +{ + DBG("buffer=%p block_number=%d\n", buffer, block_number); + int ret = MS_BulkSend(block_number, 1, (uint8_t*)buffer); + if (ret >= 0) { + return 0; + } + return 1; +} + +int msc::disk_read(uint8_t *buffer, uint64_t block_number) +{ + DBG("buffer=%p block_number=%d\n", buffer, block_number); + int ret = MS_BulkRecv(block_number, 1, (uint8_t*)buffer); + if (ret >= 0) { + return 0; + } + return 1; +} + +int msc::disk_status() +{ + DBG("\n"); + return 0; +} + +int msc::disk_sync() +{ + DBG("\n"); + return 0; +} + +uint64_t msc::disk_sectors() +{ + DBG("m_numBlocks=%d\n", m_numBlocks); + return m_numBlocks; +} + +int msc::setup(int timeout) +{ + for(int i = 0; i < 2; i++) { + m_pDev = m_pHost->getDeviceByClass(0x08, m_drive); // USB Mass Storage Class + if (m_pDev || i > 0) { + break; + } + UsbErr rc = Usb_poll(); + if (rc == USBERR_PROCESSING) { + VERBOSE("%p USBERR_PROCESSING\n", this); + return -1; + } + } + DBG("m_pDev=%p\n", m_pDev); + if (m_pDev == NULL) { + VERBOSE("%p MSC DISK(%d) NOT FOUND\n", this, m_drive); + return -1; + } + DBG_ASSERT(m_pDev); + + ParseConfiguration(); + + GetMaxLUN(); + + int retry = 0; + Timer t; + t.start(); + t.reset(); + while(t.read_ms() < timeout) { + DBG("retry=%d t=%d\n", retry, t.read_ms()); + if (retry > 80) { + return -1; + } + int rc = TestUnitReady(); + DBG("TestUnitReady(): %d\n", rc); + if (rc == USBERR_OK) { + DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus); + if (m_CSW.bCSWStatus == 0x00) { + break; + } + } + GetSenseInfo(); + retry++; + wait_ms(50); + } + if (t.read_ms() >= timeout) { + return -1; + } + ReadCapacity(); + Inquire(); + return 0; +} +void msc::_test() +{ + ReadCapacity(); + + uint8_t buf[512]; + for(int block = 0; block < m_numBlocks; block++) { + DBG("block=%d\n", block); + disk_read(buf, block); + } + exit(1); +} + +int msc::ParseConfiguration() +{ + UsbErr rc; + uint8_t ConfigDesc[9]; + int index = 0; + DBG_ASSERT(m_pDev); + rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); + DBG_ASSERT(rc == USBERR_OK); + DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); + DBG_ASSERT(ConfigDesc[0] == 9); + DBG_ASSERT(ConfigDesc[1] == 0x02); + int wTotalLength = *((uint16_t*)&ConfigDesc[2]); + DBG("TotalLength: %d\n", wTotalLength); + int bConfigValue = ConfigDesc[5]; + DBG_ASSERT(bConfigValue == 1); + DBG("ConfigValue: %d\n", bConfigValue); + DBG("MaxPower: %d mA\n", ConfigDesc[8]*2); + + uint8_t* buf = new uint8_t[wTotalLength]; + DBG_ASSERT(buf); + rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); + DBG_ASSERT(rc == USBERR_OK); + DBG_ASSERT(ConfigDesc[1] == 0x02); + for (int pos = 0; pos < wTotalLength; pos += buf[pos]) { + DBG_BYTES("CFG", buf+pos, buf[pos]); + int type = buf[pos+1]; + if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04 + DBG("InterfaceNumber: %d\n", buf[pos+2]); + DBG("AlternateSetting: %d\n", buf[pos+3]); + DBG("NumEndpoint: %d\n", buf[pos+4]); + DBG("InterfaceClass: %02X\n", buf[pos+5]); + DBG("InterfaceSubClass: %02X\n", buf[pos+6]); + DBG("InterfaceProtocol: %02X\n", buf[pos+7]); + DBG_ASSERT(buf[pos+6] == 0x06); // SCSI + DBG_ASSERT(buf[pos+7] == 0x50); // bulk only + } + if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) { + DBG_ASSERT(buf[pos] == 7); + uint8_t att = buf[pos+3]; + if (att == 2) { // bulk + uint8_t ep = buf[pos+2]; + bool dir = ep & 0x80; // true=IN + uint16_t size = LE16(buf+pos+4); + DBG("EndpointAddress: %02X\n", ep); + DBG("Attribute: %02X\n", att); + DBG("MaxPacketSize: %d\n", size); + UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, USB_BULK, size); + DBG_ASSERT(pEp); + if (dir) { + m_pEpBulkIn = pEp; + } else { + m_pEpBulkOut = pEp; + } + } + } + } + delete[] buf; + DBG_ASSERT(m_pEpBulkIn); + DBG_ASSERT(m_pEpBulkOut); + return 0; +} + +int msc::BulkOnlyMassStorageReset() +{ + DBG_ASSERT(m_pDev); + UsbErr rc = m_pDev->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); + DBG_ASSERT(rc == USBERR_OK); + return rc; +} + +int msc::GetMaxLUN() +{ + DBG_ASSERT(m_interface == 0); + uint8_t temp[1]; + DBG_ASSERT(m_pDev); + UsbErr rc = m_pDev->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); + DBG_ASSERT(rc == USBERR_OK); + DBG_BYTES("GetMaxLUN", temp, sizeof(temp)); + m_MaxLUN = temp[0]; + DBG_ASSERT(m_MaxLUN <= 15); + return rc; +} + + +int msc::TestUnitReady() +{ + const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00}; + m_CBW.dCBWDataTraansferLength = 0; + m_CBW.bmCBWFlags = 0x00; + CommandTransport(cdb, sizeof(cdb)); + StatusTransport(); + return 0; +} + +int msc::GetSenseInfo() +{ + const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00}; + m_CBW.dCBWDataTraansferLength = 18; + m_CBW.bmCBWFlags = 0x80; // data In + CommandTransport(cdb, sizeof(cdb)); + + uint8_t buf[18]; + _bulkRecv(buf, sizeof(buf)); + DBG_HEX(buf, sizeof(buf)); + + StatusTransport(); + DBG_ASSERT(m_CSW.bCSWStatus == 0x00); + return 0; +} + +int msc::ReadCapacity() +{ + const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; + m_CBW.dCBWDataTraansferLength = 8; + m_CBW.bmCBWFlags = 0x80; // data In + CommandTransport(cdb, sizeof(cdb)); + + uint8_t buf[8]; + int rc = _bulkRecv(buf, sizeof(buf)); + DBG_ASSERT(rc >= 0); + DBG_HEX(buf, sizeof(buf)); + + StatusTransport(); + DBG_ASSERT(m_CSW.bCSWStatus == 0x00); + + m_numBlocks = BE32(buf); + m_BlockSize = BE32(buf+4); + DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize); + DBG_ASSERT(m_BlockSize == 512); + DBG_ASSERT(m_numBlocks > 0); + return 0; +} + +int msc::Inquire() +{ + const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00}; + m_CBW.dCBWDataTraansferLength = 36; + m_CBW.bmCBWFlags = 0x80; // data In + CommandTransport(cdb, sizeof(cdb)); + + uint8_t buf[36]; + _bulkRecv(buf, sizeof(buf)); + DBG_HEX(buf, sizeof(buf)); + + StatusTransport(); + return 0; +} + +int msc::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer) +{ + DBG_ASSERT(m_BlockSize == 512); + DBG_ASSERT(num_blocks == 1); + DBG_ASSERT(user_buffer); + uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; + BE32(block_number, cdb+2); + BE16(num_blocks, cdb+7); + uint32_t len = m_BlockSize * num_blocks; + DBG_ASSERT(len <= 512); + m_CBW.dCBWDataTraansferLength = len; + m_CBW.bmCBWFlags = 0x80; // data In + CommandTransport(cdb, sizeof(cdb)); + + int ret = _bulkRecv(user_buffer, len); + //DBG_HEX(user_buffer, len); + + StatusTransport(); + DBG_ASSERT(m_CSW.bCSWStatus == 0x00); + return ret; +} + +int msc::MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer) +{ +#ifdef WRITE_PROTECT + return 0; +#else + DBG_ASSERT(num_blocks == 1); + DBG_ASSERT(user_buffer); + uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; + BE32(block_number, cdb+2); + BE16(num_blocks, cdb+7); + uint32_t len = m_BlockSize * num_blocks; + DBG_ASSERT(len <= 512); + m_CBW.dCBWDataTraansferLength = len; + m_CBW.bmCBWFlags = 0x00; // data Out + CommandTransport(cdb, sizeof(cdb)); + + int ret = _bulkSend(user_buffer, len); + //DBG_HEX(user_buffer, len); + + StatusTransport(); + DBG_ASSERT(m_CSW.bCSWStatus == 0x00); + return ret; +#endif //WRITE_PROTECT +} + +int msc::CommandTransport(const uint8_t* cdb, int size) +{ + DBG_ASSERT(cdb); + DBG_ASSERT(size >= 6); + DBG_ASSERT(size <= 16); + m_CBW.bCBWLUN = m_lun; + m_CBW.bCBWCBLength = size; + memcpy(m_CBW.CBWCB, cdb, size); + + m_CBW.dCBWSignature = 0x43425355; + m_CBW.dCBWTag = m_tag++; + m_CBW.bCBWLUN = 0; + //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW)); + int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW)); + return rc; +} + +int msc::StatusTransport() +{ + DBG_ASSERT(sizeof(CSW) == 13); + int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW)); + //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW)); + DBG_ASSERT(m_CSW.dCSWSignature == 0x53425355); + DBG_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag); + DBG_ASSERT(m_CSW.dCSWDataResidue == 0); + return rc; +} + +int msc::_bulkRecv(uint8_t* buf, int size) +{ + UsbErr rc = m_pEpBulkIn->transfer(buf, size); + DBG_ASSERT(rc == USBERR_PROCESSING); + while(m_pEpBulkIn->status() == USBERR_PROCESSING){ + wait_us(1); + } + int ret = m_pEpBulkIn->status(); + if (ret >= 0) { + return ret; + } + DBG("buf=%p size=%d ret=%d\n", buf, size, ret); + return ret; +} + +int msc::_bulkSend(uint8_t* buf, int size) +{ + DBG_ASSERT(m_pEpBulkOut); + UsbErr rc = m_pEpBulkOut->transfer(buf, size); + DBG_ASSERT(rc == USBERR_PROCESSING); + while(m_pEpBulkOut->status() == USBERR_PROCESSING){ + wait_us(1); + } + int ret = m_pEpBulkOut->status(); + if (ret >= 0) { + return ret; + } + DBG("buf=%p size=%d ret=%d\n", buf, size, ret); + return ret; +}