Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystem TB6612FNG2 mbed
msc/msc.cpp@0:de03cbbcd0ff, 2015-11-30 (annotated)
- Committer:
- mbed_Cookbook_SE
- Date:
- Mon Nov 30 09:32:15 2015 +0000
- Revision:
- 0:de03cbbcd0ff
??
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 1 | #include "msc.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 2 | //#define __DEBUG |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 3 | #include "mydbg.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 4 | #include "Utils.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 5 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 6 | //#define WRITE_PROTECT |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 7 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 8 | msc::msc(const char* name, int drive): FATFileSystem(name) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 9 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 10 | DBG("drive=%d\n", drive); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 11 | m_name = name; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 12 | m_drive = drive; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 13 | DBG_ASSERT(sizeof(CBW) == 31); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 14 | DBG_ASSERT(sizeof(CSW) == 13); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 15 | m_numBlocks = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 16 | m_BlockSize = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 17 | m_lun = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 18 | m_interface = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 19 | m_pDev = NULL; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 20 | m_pEpBulkIn = NULL; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 21 | m_pEpBulkOut = NULL; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 22 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 23 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 24 | int msc::disk_initialize() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 25 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 26 | DBG("m_BlockSize=%d\n", m_BlockSize); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 27 | if (m_BlockSize != 512) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 28 | return 1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 29 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 30 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 31 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 32 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 33 | int msc::disk_write(const char *buffer, int block_number) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 34 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 35 | DBG("buffer=%p block_number=%d\n", buffer, block_number); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 36 | int ret = MS_BulkSend(block_number, 1, (uint8_t*)buffer); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 37 | if (ret >= 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 38 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 39 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 40 | return 1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 41 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 42 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 43 | int msc::disk_read(char *buffer, int block_number) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 44 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 45 | DBG("buffer=%p block_number=%d\n", buffer, block_number); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 46 | int ret = MS_BulkRecv(block_number, 1, (uint8_t*)buffer); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 47 | if (ret >= 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 48 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 49 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 50 | return 1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 51 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 52 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 53 | int msc::disk_status() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 54 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 55 | DBG("\n"); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 56 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 57 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 58 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 59 | int msc::disk_sync() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 60 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 61 | DBG("\n"); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 62 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 63 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 64 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 65 | int msc::disk_sectors() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 66 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 67 | DBG("m_numBlocks=%d\n", m_numBlocks); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 68 | return m_numBlocks; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 69 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 70 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 71 | int msc::setup(int timeout) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 72 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 73 | for(int i = 0; i < 2; i++) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 74 | m_pDev = m_pHost->getDeviceByClass(0x08, m_drive); // USB Mass Storage Class |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 75 | if (m_pDev || i > 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 76 | break; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 77 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 78 | UsbErr rc = Usb_poll(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 79 | if (rc == USBERR_PROCESSING) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 80 | VERBOSE("%p USBERR_PROCESSING\n", this); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 81 | return -1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 82 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 83 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 84 | DBG("m_pDev=%p\n", m_pDev); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 85 | if (m_pDev == NULL) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 86 | VERBOSE("%p MSC DISK(%d) NOT FOUND\n", this, m_drive); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 87 | return -1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 88 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 89 | DBG_ASSERT(m_pDev); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 90 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 91 | ParseConfiguration(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 92 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 93 | GetMaxLUN(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 94 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 95 | int retry = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 96 | Timer t; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 97 | t.start(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 98 | t.reset(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 99 | while(t.read_ms() < timeout) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 100 | DBG("retry=%d t=%d\n", retry, t.read_ms()); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 101 | if (retry > 80) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 102 | return -1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 103 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 104 | int rc = TestUnitReady(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 105 | DBG("TestUnitReady(): %d\n", rc); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 106 | if (rc == USBERR_OK) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 107 | DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 108 | if (m_CSW.bCSWStatus == 0x00) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 109 | break; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 110 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 111 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 112 | GetSenseInfo(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 113 | retry++; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 114 | wait_ms(50); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 115 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 116 | if (t.read_ms() >= timeout) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 117 | return -1; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 118 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 119 | ReadCapacity(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 120 | Inquire(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 121 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 122 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 123 | void msc::_test() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 124 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 125 | ReadCapacity(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 126 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 127 | char buf[512]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 128 | for(int block = 0; block < m_numBlocks; block++) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 129 | DBG("block=%d\n", block); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 130 | disk_read(buf, block); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 131 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 132 | exit(1); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 133 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 134 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 135 | int msc::ParseConfiguration() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 136 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 137 | UsbErr rc; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 138 | uint8_t ConfigDesc[9]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 139 | int index = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 140 | DBG_ASSERT(m_pDev); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 141 | rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 142 | DBG_ASSERT(rc == USBERR_OK); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 143 | DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 144 | DBG_ASSERT(ConfigDesc[0] == 9); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 145 | DBG_ASSERT(ConfigDesc[1] == 0x02); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 146 | int wTotalLength = *((uint16_t*)&ConfigDesc[2]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 147 | DBG("TotalLength: %d\n", wTotalLength); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 148 | int bConfigValue = ConfigDesc[5]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 149 | DBG_ASSERT(bConfigValue == 1); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 150 | DBG("ConfigValue: %d\n", bConfigValue); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 151 | DBG("MaxPower: %d mA\n", ConfigDesc[8]*2); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 152 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 153 | uint8_t* buf = new uint8_t[wTotalLength]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 154 | DBG_ASSERT(buf); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 155 | rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 156 | DBG_ASSERT(rc == USBERR_OK); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 157 | DBG_ASSERT(ConfigDesc[1] == 0x02); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 158 | for (int pos = 0; pos < wTotalLength; pos += buf[pos]) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 159 | DBG_BYTES("CFG", buf+pos, buf[pos]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 160 | int type = buf[pos+1]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 161 | if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 162 | DBG("InterfaceNumber: %d\n", buf[pos+2]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 163 | DBG("AlternateSetting: %d\n", buf[pos+3]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 164 | DBG("NumEndpoint: %d\n", buf[pos+4]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 165 | DBG("InterfaceClass: %02X\n", buf[pos+5]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 166 | DBG("InterfaceSubClass: %02X\n", buf[pos+6]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 167 | DBG("InterfaceProtocol: %02X\n", buf[pos+7]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 168 | DBG_ASSERT(buf[pos+6] == 0x06); // SCSI |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 169 | DBG_ASSERT(buf[pos+7] == 0x50); // bulk only |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 170 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 171 | if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 172 | DBG_ASSERT(buf[pos] == 7); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 173 | uint8_t att = buf[pos+3]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 174 | if (att == 2) { // bulk |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 175 | uint8_t ep = buf[pos+2]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 176 | bool dir = ep & 0x80; // true=IN |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 177 | uint16_t size = LE16(buf+pos+4); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 178 | DBG("EndpointAddress: %02X\n", ep); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 179 | DBG("Attribute: %02X\n", att); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 180 | DBG("MaxPacketSize: %d\n", size); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 181 | UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, USB_BULK, size); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 182 | DBG_ASSERT(pEp); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 183 | if (dir) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 184 | m_pEpBulkIn = pEp; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 185 | } else { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 186 | m_pEpBulkOut = pEp; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 187 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 188 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 189 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 190 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 191 | delete[] buf; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 192 | DBG_ASSERT(m_pEpBulkIn); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 193 | DBG_ASSERT(m_pEpBulkOut); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 194 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 195 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 196 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 197 | int msc::BulkOnlyMassStorageReset() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 198 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 199 | DBG_ASSERT(m_pDev); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 200 | UsbErr rc = m_pDev->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 201 | DBG_ASSERT(rc == USBERR_OK); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 202 | return rc; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 203 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 204 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 205 | int msc::GetMaxLUN() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 206 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 207 | DBG_ASSERT(m_interface == 0); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 208 | uint8_t temp[1]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 209 | DBG_ASSERT(m_pDev); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 210 | UsbErr rc = m_pDev->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 211 | DBG_ASSERT(rc == USBERR_OK); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 212 | DBG_BYTES("GetMaxLUN", temp, sizeof(temp)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 213 | m_MaxLUN = temp[0]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 214 | DBG_ASSERT(m_MaxLUN <= 15); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 215 | return rc; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 216 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 217 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 218 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 219 | int msc::TestUnitReady() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 220 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 221 | const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 222 | m_CBW.dCBWDataTraansferLength = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 223 | m_CBW.bmCBWFlags = 0x00; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 224 | CommandTransport(cdb, sizeof(cdb)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 225 | StatusTransport(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 226 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 227 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 228 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 229 | int msc::GetSenseInfo() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 230 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 231 | const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00}; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 232 | m_CBW.dCBWDataTraansferLength = 18; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 233 | m_CBW.bmCBWFlags = 0x80; // data In |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 234 | CommandTransport(cdb, sizeof(cdb)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 235 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 236 | uint8_t buf[18]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 237 | _bulkRecv(buf, sizeof(buf)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 238 | DBG_HEX(buf, sizeof(buf)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 239 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 240 | StatusTransport(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 241 | DBG_ASSERT(m_CSW.bCSWStatus == 0x00); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 242 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 243 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 244 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 245 | int msc::ReadCapacity() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 246 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 247 | const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00, |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 248 | 0x00, 0x00, 0x00, 0x00, 0x00}; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 249 | m_CBW.dCBWDataTraansferLength = 8; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 250 | m_CBW.bmCBWFlags = 0x80; // data In |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 251 | CommandTransport(cdb, sizeof(cdb)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 252 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 253 | uint8_t buf[8]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 254 | int rc = _bulkRecv(buf, sizeof(buf)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 255 | DBG_ASSERT(rc >= 0); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 256 | DBG_HEX(buf, sizeof(buf)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 257 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 258 | StatusTransport(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 259 | DBG_ASSERT(m_CSW.bCSWStatus == 0x00); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 260 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 261 | m_numBlocks = BE32(buf); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 262 | m_BlockSize = BE32(buf+4); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 263 | DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 264 | DBG_ASSERT(m_BlockSize == 512); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 265 | DBG_ASSERT(m_numBlocks > 0); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 266 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 267 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 268 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 269 | int msc::Inquire() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 270 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 271 | const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00}; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 272 | m_CBW.dCBWDataTraansferLength = 36; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 273 | m_CBW.bmCBWFlags = 0x80; // data In |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 274 | CommandTransport(cdb, sizeof(cdb)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 275 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 276 | uint8_t buf[36]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 277 | _bulkRecv(buf, sizeof(buf)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 278 | DBG_HEX(buf, sizeof(buf)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 279 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 280 | StatusTransport(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 281 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 282 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 283 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 284 | int msc::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 285 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 286 | DBG_ASSERT(m_BlockSize == 512); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 287 | DBG_ASSERT(num_blocks == 1); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 288 | DBG_ASSERT(user_buffer); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 289 | uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00, |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 290 | 0x00, 0x00, 0x00, 0x00, 0x00}; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 291 | BE32(block_number, cdb+2); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 292 | BE16(num_blocks, cdb+7); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 293 | uint32_t len = m_BlockSize * num_blocks; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 294 | DBG_ASSERT(len <= 512); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 295 | m_CBW.dCBWDataTraansferLength = len; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 296 | m_CBW.bmCBWFlags = 0x80; // data In |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 297 | CommandTransport(cdb, sizeof(cdb)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 298 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 299 | int ret = _bulkRecv(user_buffer, len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 300 | //DBG_HEX(user_buffer, len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 301 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 302 | StatusTransport(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 303 | DBG_ASSERT(m_CSW.bCSWStatus == 0x00); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 304 | return ret; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 305 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 306 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 307 | int msc::MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 308 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 309 | #ifdef WRITE_PROTECT |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 310 | return 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 311 | #else |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 312 | DBG_ASSERT(num_blocks == 1); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 313 | DBG_ASSERT(user_buffer); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 314 | uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00, |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 315 | 0x00, 0x00, 0x00, 0x00, 0x00}; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 316 | BE32(block_number, cdb+2); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 317 | BE16(num_blocks, cdb+7); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 318 | uint32_t len = m_BlockSize * num_blocks; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 319 | DBG_ASSERT(len <= 512); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 320 | m_CBW.dCBWDataTraansferLength = len; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 321 | m_CBW.bmCBWFlags = 0x00; // data Out |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 322 | CommandTransport(cdb, sizeof(cdb)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 323 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 324 | int ret = _bulkSend(user_buffer, len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 325 | //DBG_HEX(user_buffer, len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 326 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 327 | StatusTransport(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 328 | DBG_ASSERT(m_CSW.bCSWStatus == 0x00); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 329 | return ret; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 330 | #endif //WRITE_PROTECT |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 331 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 332 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 333 | int msc::CommandTransport(const uint8_t* cdb, int size) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 334 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 335 | DBG_ASSERT(cdb); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 336 | DBG_ASSERT(size >= 6); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 337 | DBG_ASSERT(size <= 16); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 338 | m_CBW.bCBWLUN = m_lun; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 339 | m_CBW.bCBWCBLength = size; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 340 | memcpy(m_CBW.CBWCB, cdb, size); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 341 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 342 | m_CBW.dCBWSignature = 0x43425355; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 343 | m_CBW.dCBWTag = m_tag++; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 344 | m_CBW.bCBWLUN = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 345 | //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 346 | int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 347 | return rc; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 348 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 349 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 350 | int msc::StatusTransport() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 351 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 352 | DBG_ASSERT(sizeof(CSW) == 13); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 353 | int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 354 | //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW)); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 355 | DBG_ASSERT(m_CSW.dCSWSignature == 0x53425355); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 356 | DBG_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 357 | DBG_ASSERT(m_CSW.dCSWDataResidue == 0); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 358 | return rc; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 359 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 360 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 361 | int msc::_bulkRecv(uint8_t* buf, int size) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 362 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 363 | UsbErr rc = m_pEpBulkIn->transfer(buf, size); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 364 | DBG_ASSERT(rc == USBERR_PROCESSING); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 365 | while(m_pEpBulkIn->status() == USBERR_PROCESSING){ |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 366 | wait_us(1); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 367 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 368 | int ret = m_pEpBulkIn->status(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 369 | if (ret >= 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 370 | return ret; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 371 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 372 | DBG("buf=%p size=%d ret=%d\n", buf, size, ret); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 373 | return ret; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 374 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 375 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 376 | int msc::_bulkSend(uint8_t* buf, int size) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 377 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 378 | DBG_ASSERT(m_pEpBulkOut); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 379 | UsbErr rc = m_pEpBulkOut->transfer(buf, size); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 380 | DBG_ASSERT(rc == USBERR_PROCESSING); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 381 | while(m_pEpBulkOut->status() == USBERR_PROCESSING){ |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 382 | wait_us(1); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 383 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 384 | int ret = m_pEpBulkOut->status(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 385 | if (ret >= 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 386 | return ret; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 387 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 388 | DBG("buf=%p size=%d ret=%d\n", buf, size, ret); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 389 | return ret; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 390 | } |