BaseJpegDeocde exampe program
Dependencies: BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos
Fork of BaseJpegDecode by
msc/msc.cpp
- Committer:
- va009039
- Date:
- 2012-12-05
- Revision:
- 6:95be1cd2bc14
- Parent:
- 4:7d88de31c55a
File content as of revision 6:95be1cd2bc14:
#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; }