BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Committer:
va009039
Date:
Wed Dec 05 13:25:18 2012 +0000
Revision:
1:80205a2de336
Parent:
0:2a9734a95d55
Child:
3:6ae9a03a6145
add LifeCamVX700

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 1:80205a2de336 1 // UsbFlashDrive.cpp 2012/12/5
va009039 0:2a9734a95d55 2 #include "mbed.h"
va009039 0:2a9734a95d55 3 #include "rtos.h"
va009039 0:2a9734a95d55 4 #include "BaseUsbHost.h"
va009039 0:2a9734a95d55 5 #define DEBUG
va009039 0:2a9734a95d55 6 #include "BaseUsbHostDebug.h"
va009039 0:2a9734a95d55 7 #define TEST
va009039 0:2a9734a95d55 8 #include "BaseUsbHostTest.h"
va009039 0:2a9734a95d55 9
va009039 0:2a9734a95d55 10 #include "UsbFlashDrive.h"
va009039 0:2a9734a95d55 11
va009039 0:2a9734a95d55 12 //#define WRITE_PROTECT
va009039 0:2a9734a95d55 13
va009039 0:2a9734a95d55 14 int LE16(const uint8_t* d)
va009039 0:2a9734a95d55 15 {
va009039 0:2a9734a95d55 16 return d[0] | (d[1] << 8);
va009039 0:2a9734a95d55 17 }
va009039 0:2a9734a95d55 18
va009039 0:2a9734a95d55 19 uint32_t BE32(uint8_t* d)
va009039 0:2a9734a95d55 20 {
va009039 0:2a9734a95d55 21 return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
va009039 0:2a9734a95d55 22 }
va009039 0:2a9734a95d55 23
va009039 0:2a9734a95d55 24 void BE16(uint32_t n, uint8_t* d)
va009039 0:2a9734a95d55 25 {
va009039 0:2a9734a95d55 26 d[0] = (uint8_t)(n >> 8);
va009039 0:2a9734a95d55 27 d[1] = (uint8_t)n;
va009039 0:2a9734a95d55 28 }
va009039 0:2a9734a95d55 29
va009039 0:2a9734a95d55 30 void BE32(uint32_t n, uint8_t* d)
va009039 0:2a9734a95d55 31 {
va009039 0:2a9734a95d55 32 d[0] = (uint8_t)(n >> 24);
va009039 0:2a9734a95d55 33 d[1] = (uint8_t)(n >> 16);
va009039 0:2a9734a95d55 34 d[2] = (uint8_t)(n >> 8);
va009039 0:2a9734a95d55 35 d[3] = (uint8_t)n;
va009039 0:2a9734a95d55 36 }
va009039 0:2a9734a95d55 37
va009039 0:2a9734a95d55 38 UsbFlashDrive::UsbFlashDrive(const char* name, ControlEp* ctlEp): FATFileSystem(name)
va009039 0:2a9734a95d55 39 {
va009039 0:2a9734a95d55 40 m_name = name;
va009039 0:2a9734a95d55 41
va009039 0:2a9734a95d55 42 if (ctlEp == NULL) { // root hub
va009039 0:2a9734a95d55 43 DBG_OHCI(LPC_USB->HcRhPortStatus1);
va009039 0:2a9734a95d55 44 TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
va009039 1:80205a2de336 45 ctlEp = new ControlEp();
va009039 1:80205a2de336 46 TEST_ASSERT_TRUE(ctlEp);
va009039 0:2a9734a95d55 47 }
va009039 0:2a9734a95d55 48
va009039 0:2a9734a95d55 49 TEST_ASSERT(sizeof(CBW) == 31);
va009039 0:2a9734a95d55 50 TEST_ASSERT(sizeof(CSW) == 13);
va009039 0:2a9734a95d55 51
va009039 0:2a9734a95d55 52 m_numBlocks = 0;
va009039 0:2a9734a95d55 53 m_BlockSize = 0;
va009039 0:2a9734a95d55 54 m_lun = 0;
va009039 0:2a9734a95d55 55 m_interface = 0;
va009039 0:2a9734a95d55 56 m_pEpBulkIn = NULL;
va009039 0:2a9734a95d55 57 m_pEpBulkOut = NULL;
va009039 0:2a9734a95d55 58
va009039 1:80205a2de336 59 ParseConfiguration(ctlEp);
va009039 1:80205a2de336 60 int rc = ctlEp->SetConfiguration(1);
va009039 0:2a9734a95d55 61 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 1:80205a2de336 62 GetMaxLUN(ctlEp);
va009039 1:80205a2de336 63 setup(ctlEp);
va009039 1:80205a2de336 64 }
va009039 1:80205a2de336 65
va009039 1:80205a2de336 66 bool UsbFlashDrive::check(ControlEp* ctlEp)
va009039 1:80205a2de336 67 {
va009039 1:80205a2de336 68 if (ctlEp == NULL) {
va009039 1:80205a2de336 69 return false;
va009039 1:80205a2de336 70 }
va009039 1:80205a2de336 71 uint8_t buf[8];
va009039 1:80205a2de336 72 int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, sizeof(buf));
va009039 1:80205a2de336 73 if (rc != USB_OK) {
va009039 1:80205a2de336 74 return false;
va009039 1:80205a2de336 75 }
va009039 1:80205a2de336 76 DBG_BYTES("ConfigDescriptor 8bytes", buf, sizeof(buf));
va009039 1:80205a2de336 77 TEST_ASSERT(buf[0] == 9);
va009039 1:80205a2de336 78 TEST_ASSERT(buf[1] == 0x02);
va009039 1:80205a2de336 79 if (buf[4] != 0x01) {
va009039 1:80205a2de336 80 return false;
va009039 1:80205a2de336 81 }
va009039 1:80205a2de336 82 return true;
va009039 0:2a9734a95d55 83 }
va009039 0:2a9734a95d55 84
va009039 0:2a9734a95d55 85 int UsbFlashDrive::disk_initialize()
va009039 0:2a9734a95d55 86 {
va009039 0:2a9734a95d55 87 //DBG("m_BlockSize=%d\n", m_BlockSize);
va009039 0:2a9734a95d55 88 if (m_BlockSize != 512) {
va009039 0:2a9734a95d55 89 return 1;
va009039 0:2a9734a95d55 90 }
va009039 0:2a9734a95d55 91 return 0;
va009039 0:2a9734a95d55 92 }
va009039 0:2a9734a95d55 93
va009039 0:2a9734a95d55 94 int UsbFlashDrive::disk_write(const uint8_t* buffer, uint64_t sector)
va009039 0:2a9734a95d55 95 {
va009039 0:2a9734a95d55 96 m_report_disk_write++;
va009039 0:2a9734a95d55 97 //DBG("buffer=%p block_number=%d\n", buffer, sector);
va009039 0:2a9734a95d55 98 int ret = MS_BulkSend(sector, 1, buffer);
va009039 0:2a9734a95d55 99 if (ret >= 0) {
va009039 0:2a9734a95d55 100 return 0;
va009039 0:2a9734a95d55 101 }
va009039 0:2a9734a95d55 102 return 1;
va009039 0:2a9734a95d55 103 }
va009039 0:2a9734a95d55 104
va009039 0:2a9734a95d55 105 int UsbFlashDrive::disk_read(uint8_t* buffer, uint64_t sector)
va009039 0:2a9734a95d55 106 {
va009039 0:2a9734a95d55 107 m_report_disk_read++;
va009039 0:2a9734a95d55 108 //DBG("buffer=%p block_number=%d\n", buffer, sector);
va009039 0:2a9734a95d55 109 int ret = MS_BulkRecv(sector, 1, buffer);
va009039 0:2a9734a95d55 110 if (ret >= 0) {
va009039 0:2a9734a95d55 111 return 0;
va009039 0:2a9734a95d55 112 }
va009039 0:2a9734a95d55 113 return 1;
va009039 0:2a9734a95d55 114 }
va009039 0:2a9734a95d55 115
va009039 0:2a9734a95d55 116 int UsbFlashDrive::disk_status()
va009039 0:2a9734a95d55 117 {
va009039 0:2a9734a95d55 118 m_report_disk_status++;
va009039 0:2a9734a95d55 119 return 0;
va009039 0:2a9734a95d55 120 }
va009039 0:2a9734a95d55 121
va009039 0:2a9734a95d55 122 int UsbFlashDrive::disk_sync()
va009039 0:2a9734a95d55 123 {
va009039 0:2a9734a95d55 124 m_report_disk_sync++;
va009039 0:2a9734a95d55 125 return 0;
va009039 0:2a9734a95d55 126 }
va009039 0:2a9734a95d55 127
va009039 0:2a9734a95d55 128 uint64_t UsbFlashDrive::disk_sectors()
va009039 0:2a9734a95d55 129 {
va009039 0:2a9734a95d55 130 DBG("m_numBlocks=%d\n", m_numBlocks);
va009039 0:2a9734a95d55 131 return m_numBlocks;
va009039 0:2a9734a95d55 132 }
va009039 0:2a9734a95d55 133
va009039 1:80205a2de336 134 int UsbFlashDrive::setup(ControlEp* ctlEp, int timeout)
va009039 0:2a9734a95d55 135 {
va009039 0:2a9734a95d55 136
va009039 0:2a9734a95d55 137 int retry = 0;
va009039 0:2a9734a95d55 138 Timer t;
va009039 0:2a9734a95d55 139 t.start();
va009039 0:2a9734a95d55 140 t.reset();
va009039 0:2a9734a95d55 141 while(t.read_ms() < timeout) {
va009039 0:2a9734a95d55 142 DBG("retry=%d t=%d\n", retry, t.read_ms());
va009039 0:2a9734a95d55 143 if (retry > 80) {
va009039 0:2a9734a95d55 144 return -1;
va009039 0:2a9734a95d55 145 }
va009039 0:2a9734a95d55 146 int rc = TestUnitReady();
va009039 0:2a9734a95d55 147 DBG("TestUnitReady(): %d\n", rc);
va009039 0:2a9734a95d55 148 if (rc == USB_OK) {
va009039 0:2a9734a95d55 149 DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus);
va009039 0:2a9734a95d55 150 if (m_CSW.bCSWStatus == 0x00) {
va009039 0:2a9734a95d55 151 break;
va009039 0:2a9734a95d55 152 }
va009039 0:2a9734a95d55 153 }
va009039 0:2a9734a95d55 154 GetSenseInfo();
va009039 0:2a9734a95d55 155 retry++;
va009039 0:2a9734a95d55 156 wait_ms(50);
va009039 0:2a9734a95d55 157 }
va009039 0:2a9734a95d55 158 if (t.read_ms() >= timeout) {
va009039 0:2a9734a95d55 159 return -1;
va009039 0:2a9734a95d55 160 }
va009039 0:2a9734a95d55 161 ReadCapacity();
va009039 0:2a9734a95d55 162 Inquire();
va009039 0:2a9734a95d55 163 return 0;
va009039 0:2a9734a95d55 164 }
va009039 0:2a9734a95d55 165
va009039 1:80205a2de336 166 int UsbFlashDrive::ParseConfiguration(ControlEp* ctlEp)
va009039 0:2a9734a95d55 167 {
va009039 1:80205a2de336 168 TEST_ASSERT(ctlEp);
va009039 0:2a9734a95d55 169 int rc;
va009039 0:2a9734a95d55 170 uint8_t ConfigDesc[9];
va009039 0:2a9734a95d55 171 int index = 0;
va009039 1:80205a2de336 172 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
va009039 0:2a9734a95d55 173 TEST_ASSERT(rc == USB_OK);
va009039 0:2a9734a95d55 174 DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
va009039 0:2a9734a95d55 175 TEST_ASSERT(ConfigDesc[0] == 9);
va009039 0:2a9734a95d55 176 TEST_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:2a9734a95d55 177 int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
va009039 0:2a9734a95d55 178 DBG("TotalLength: %d\n", wTotalLength);
va009039 0:2a9734a95d55 179 int bConfigValue = ConfigDesc[5];
va009039 0:2a9734a95d55 180 TEST_ASSERT(bConfigValue == 1);
va009039 0:2a9734a95d55 181 DBG("ConfigValue: %d\n", bConfigValue);
va009039 0:2a9734a95d55 182 DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);
va009039 0:2a9734a95d55 183
va009039 0:2a9734a95d55 184 uint8_t* buf = new uint8_t[wTotalLength];
va009039 0:2a9734a95d55 185 TEST_ASSERT(buf);
va009039 1:80205a2de336 186 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
va009039 0:2a9734a95d55 187 TEST_ASSERT(rc == USB_OK);
va009039 0:2a9734a95d55 188 TEST_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:2a9734a95d55 189 for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
va009039 0:2a9734a95d55 190 DBG_BYTES("CFG", buf+pos, buf[pos]);
va009039 0:2a9734a95d55 191 int type = buf[pos+1];
va009039 0:2a9734a95d55 192 if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
va009039 0:2a9734a95d55 193 DBG("InterfaceNumber: %d\n", buf[pos+2]);
va009039 0:2a9734a95d55 194 DBG("AlternateSetting: %d\n", buf[pos+3]);
va009039 0:2a9734a95d55 195 DBG("NumEndpoint: %d\n", buf[pos+4]);
va009039 0:2a9734a95d55 196 DBG("InterfaceClass: %02X\n", buf[pos+5]);
va009039 0:2a9734a95d55 197 DBG("InterfaceSubClass: %02X\n", buf[pos+6]);
va009039 0:2a9734a95d55 198 DBG("InterfaceProtocol: %02X\n", buf[pos+7]);
va009039 0:2a9734a95d55 199 TEST_ASSERT(buf[pos+6] == 0x06); // SCSI
va009039 0:2a9734a95d55 200 TEST_ASSERT(buf[pos+7] == 0x50); // bulk only
va009039 0:2a9734a95d55 201 }
va009039 0:2a9734a95d55 202 if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
va009039 0:2a9734a95d55 203 TEST_ASSERT(buf[pos] == 7);
va009039 0:2a9734a95d55 204 uint8_t att = buf[pos+3];
va009039 0:2a9734a95d55 205 if (att == 2) { // bulk
va009039 0:2a9734a95d55 206 uint8_t ep = buf[pos+2];
va009039 0:2a9734a95d55 207 bool dir = ep & 0x80; // true=IN
va009039 0:2a9734a95d55 208 uint16_t size = LE16(buf+pos+4);
va009039 0:2a9734a95d55 209 DBG("EndpointAddress: %02X\n", ep);
va009039 0:2a9734a95d55 210 DBG("Attribute: %02X\n", att);
va009039 0:2a9734a95d55 211 DBG("MaxPacketSize: %d\n", size);
va009039 1:80205a2de336 212 BulkEp* pEp = new BulkEp(ctlEp->GetAddr(), ep, size);
va009039 0:2a9734a95d55 213 TEST_ASSERT(pEp);
va009039 0:2a9734a95d55 214 if (dir) {
va009039 0:2a9734a95d55 215 m_pEpBulkIn = pEp;
va009039 0:2a9734a95d55 216 } else {
va009039 0:2a9734a95d55 217 m_pEpBulkOut = pEp;
va009039 0:2a9734a95d55 218 }
va009039 0:2a9734a95d55 219 }
va009039 0:2a9734a95d55 220 }
va009039 0:2a9734a95d55 221 }
va009039 0:2a9734a95d55 222 delete[] buf;
va009039 0:2a9734a95d55 223 TEST_ASSERT(m_pEpBulkIn);
va009039 0:2a9734a95d55 224 TEST_ASSERT(m_pEpBulkOut);
va009039 0:2a9734a95d55 225 return 0;
va009039 0:2a9734a95d55 226 }
va009039 0:2a9734a95d55 227
va009039 1:80205a2de336 228 int UsbFlashDrive::BulkOnlyMassStorageReset(ControlEp* ctlEp)
va009039 0:2a9734a95d55 229 {
va009039 1:80205a2de336 230 TEST_ASSERT(ctlEp);
va009039 1:80205a2de336 231 int rc = ctlEp->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0);
va009039 0:2a9734a95d55 232 TEST_ASSERT(rc == USB_OK);
va009039 0:2a9734a95d55 233 return rc;
va009039 0:2a9734a95d55 234 }
va009039 0:2a9734a95d55 235
va009039 1:80205a2de336 236 int UsbFlashDrive::GetMaxLUN(ControlEp* ctlEp)
va009039 0:2a9734a95d55 237 {
va009039 1:80205a2de336 238 TEST_ASSERT(ctlEp);
va009039 0:2a9734a95d55 239 TEST_ASSERT(m_interface == 0);
va009039 0:2a9734a95d55 240 uint8_t temp[1];
va009039 1:80205a2de336 241 int rc = ctlEp->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp));
va009039 0:2a9734a95d55 242 TEST_ASSERT(rc == USB_OK);
va009039 0:2a9734a95d55 243 DBG_BYTES("GetMaxLUN", temp, sizeof(temp));
va009039 0:2a9734a95d55 244 m_MaxLUN = temp[0];
va009039 0:2a9734a95d55 245 TEST_ASSERT(m_MaxLUN <= 15);
va009039 0:2a9734a95d55 246 return rc;
va009039 0:2a9734a95d55 247 }
va009039 0:2a9734a95d55 248
va009039 0:2a9734a95d55 249
va009039 0:2a9734a95d55 250 int UsbFlashDrive::TestUnitReady()
va009039 0:2a9734a95d55 251 {
va009039 0:2a9734a95d55 252 const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:2a9734a95d55 253 m_CBW.dCBWDataTraansferLength = 0;
va009039 0:2a9734a95d55 254 m_CBW.bmCBWFlags = 0x00;
va009039 0:2a9734a95d55 255 CommandTransport(cdb, sizeof(cdb));
va009039 0:2a9734a95d55 256 StatusTransport();
va009039 0:2a9734a95d55 257 return 0;
va009039 0:2a9734a95d55 258 }
va009039 0:2a9734a95d55 259
va009039 0:2a9734a95d55 260 int UsbFlashDrive::GetSenseInfo()
va009039 0:2a9734a95d55 261 {
va009039 0:2a9734a95d55 262 const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00};
va009039 0:2a9734a95d55 263 m_CBW.dCBWDataTraansferLength = 18;
va009039 0:2a9734a95d55 264 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:2a9734a95d55 265 CommandTransport(cdb, sizeof(cdb));
va009039 0:2a9734a95d55 266
va009039 0:2a9734a95d55 267 uint8_t buf[18];
va009039 0:2a9734a95d55 268 _bulkRecv(buf, sizeof(buf));
va009039 0:2a9734a95d55 269 DBG_HEX(buf, sizeof(buf));
va009039 0:2a9734a95d55 270
va009039 0:2a9734a95d55 271 StatusTransport();
va009039 0:2a9734a95d55 272 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:2a9734a95d55 273 return 0;
va009039 0:2a9734a95d55 274 }
va009039 0:2a9734a95d55 275
va009039 0:2a9734a95d55 276 int UsbFlashDrive::ReadCapacity()
va009039 0:2a9734a95d55 277 {
va009039 0:2a9734a95d55 278 const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00,
va009039 0:2a9734a95d55 279 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:2a9734a95d55 280 m_CBW.dCBWDataTraansferLength = 8;
va009039 0:2a9734a95d55 281 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:2a9734a95d55 282 CommandTransport(cdb, sizeof(cdb));
va009039 0:2a9734a95d55 283
va009039 0:2a9734a95d55 284 uint8_t buf[8];
va009039 0:2a9734a95d55 285 int rc = _bulkRecv(buf, sizeof(buf));
va009039 0:2a9734a95d55 286 TEST_ASSERT(rc >= 0);
va009039 0:2a9734a95d55 287 DBG_HEX(buf, sizeof(buf));
va009039 0:2a9734a95d55 288
va009039 0:2a9734a95d55 289 StatusTransport();
va009039 0:2a9734a95d55 290 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:2a9734a95d55 291
va009039 0:2a9734a95d55 292 m_numBlocks = BE32(buf);
va009039 0:2a9734a95d55 293 m_BlockSize = BE32(buf+4);
va009039 0:2a9734a95d55 294 DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize);
va009039 0:2a9734a95d55 295 TEST_ASSERT(m_BlockSize == 512);
va009039 0:2a9734a95d55 296 TEST_ASSERT(m_numBlocks > 0);
va009039 0:2a9734a95d55 297 return 0;
va009039 0:2a9734a95d55 298 }
va009039 0:2a9734a95d55 299
va009039 0:2a9734a95d55 300 int UsbFlashDrive::Inquire()
va009039 0:2a9734a95d55 301 {
va009039 0:2a9734a95d55 302 const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00};
va009039 0:2a9734a95d55 303 m_CBW.dCBWDataTraansferLength = 36;
va009039 0:2a9734a95d55 304 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:2a9734a95d55 305 CommandTransport(cdb, sizeof(cdb));
va009039 0:2a9734a95d55 306
va009039 0:2a9734a95d55 307 uint8_t buf[36];
va009039 0:2a9734a95d55 308 int rc = _bulkRecv(buf, sizeof(buf));
va009039 0:2a9734a95d55 309 TEST_ASSERT(rc >= 0);
va009039 0:2a9734a95d55 310 DBG_HEX(buf, sizeof(buf));
va009039 0:2a9734a95d55 311
va009039 0:2a9734a95d55 312 StatusTransport();
va009039 0:2a9734a95d55 313 return 0;
va009039 0:2a9734a95d55 314 }
va009039 0:2a9734a95d55 315
va009039 0:2a9734a95d55 316 int UsbFlashDrive::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer)
va009039 0:2a9734a95d55 317 {
va009039 0:2a9734a95d55 318 TEST_ASSERT(m_BlockSize == 512);
va009039 0:2a9734a95d55 319 TEST_ASSERT(num_blocks == 1);
va009039 0:2a9734a95d55 320 TEST_ASSERT(user_buffer);
va009039 0:2a9734a95d55 321 uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00,
va009039 0:2a9734a95d55 322 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:2a9734a95d55 323 BE32(block_number, cdb+2);
va009039 0:2a9734a95d55 324 BE16(num_blocks, cdb+7);
va009039 0:2a9734a95d55 325 uint32_t len = m_BlockSize * num_blocks;
va009039 0:2a9734a95d55 326 TEST_ASSERT(len <= 512);
va009039 0:2a9734a95d55 327 m_CBW.dCBWDataTraansferLength = len;
va009039 0:2a9734a95d55 328 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:2a9734a95d55 329 CommandTransport(cdb, sizeof(cdb));
va009039 0:2a9734a95d55 330
va009039 0:2a9734a95d55 331 int ret = _bulkRecv(user_buffer, len);
va009039 0:2a9734a95d55 332 //DBG_HEX(user_buffer, len);
va009039 0:2a9734a95d55 333
va009039 0:2a9734a95d55 334 StatusTransport();
va009039 0:2a9734a95d55 335 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:2a9734a95d55 336 return ret;
va009039 0:2a9734a95d55 337 }
va009039 0:2a9734a95d55 338
va009039 0:2a9734a95d55 339 int UsbFlashDrive::MS_BulkSend(uint32_t block_number, int num_blocks, const uint8_t* user_buffer)
va009039 0:2a9734a95d55 340 {
va009039 0:2a9734a95d55 341 #ifdef WRITE_PROTECT
va009039 0:2a9734a95d55 342 return 0;
va009039 0:2a9734a95d55 343 #else
va009039 0:2a9734a95d55 344 TEST_ASSERT(num_blocks == 1);
va009039 0:2a9734a95d55 345 TEST_ASSERT(user_buffer);
va009039 0:2a9734a95d55 346 uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00,
va009039 0:2a9734a95d55 347 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:2a9734a95d55 348 BE32(block_number, cdb+2);
va009039 0:2a9734a95d55 349 BE16(num_blocks, cdb+7);
va009039 0:2a9734a95d55 350 uint32_t len = m_BlockSize * num_blocks;
va009039 0:2a9734a95d55 351 TEST_ASSERT(len <= 512);
va009039 0:2a9734a95d55 352 m_CBW.dCBWDataTraansferLength = len;
va009039 0:2a9734a95d55 353 m_CBW.bmCBWFlags = 0x00; // data Out
va009039 0:2a9734a95d55 354 CommandTransport(cdb, sizeof(cdb));
va009039 0:2a9734a95d55 355
va009039 0:2a9734a95d55 356 int ret = _bulkSend(user_buffer, len);
va009039 0:2a9734a95d55 357 //DBG_HEX(user_buffer, len);
va009039 0:2a9734a95d55 358
va009039 0:2a9734a95d55 359 StatusTransport();
va009039 0:2a9734a95d55 360 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:2a9734a95d55 361 return ret;
va009039 0:2a9734a95d55 362 #endif //WRITE_PROTECT
va009039 0:2a9734a95d55 363 }
va009039 0:2a9734a95d55 364
va009039 0:2a9734a95d55 365 int UsbFlashDrive::CommandTransport(const uint8_t* cdb, int size)
va009039 0:2a9734a95d55 366 {
va009039 0:2a9734a95d55 367 TEST_ASSERT(cdb);
va009039 0:2a9734a95d55 368 TEST_ASSERT(size >= 6);
va009039 0:2a9734a95d55 369 TEST_ASSERT(size <= 16);
va009039 0:2a9734a95d55 370 m_CBW.bCBWLUN = m_lun;
va009039 0:2a9734a95d55 371 m_CBW.bCBWCBLength = size;
va009039 0:2a9734a95d55 372 memcpy(m_CBW.CBWCB, cdb, size);
va009039 0:2a9734a95d55 373
va009039 0:2a9734a95d55 374 m_CBW.dCBWSignature = 0x43425355;
va009039 0:2a9734a95d55 375 m_CBW.dCBWTag = m_tag++;
va009039 0:2a9734a95d55 376 m_CBW.bCBWLUN = 0;
va009039 0:2a9734a95d55 377 //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW));
va009039 0:2a9734a95d55 378 int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW));
va009039 0:2a9734a95d55 379 return rc;
va009039 0:2a9734a95d55 380 }
va009039 0:2a9734a95d55 381
va009039 0:2a9734a95d55 382 int UsbFlashDrive::StatusTransport()
va009039 0:2a9734a95d55 383 {
va009039 0:2a9734a95d55 384 TEST_ASSERT(sizeof(CSW) == 13);
va009039 0:2a9734a95d55 385 int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW));
va009039 0:2a9734a95d55 386 //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW));
va009039 0:2a9734a95d55 387 TEST_ASSERT(m_CSW.dCSWSignature == 0x53425355);
va009039 0:2a9734a95d55 388 TEST_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag);
va009039 0:2a9734a95d55 389 TEST_ASSERT(m_CSW.dCSWDataResidue == 0);
va009039 0:2a9734a95d55 390 return rc;
va009039 0:2a9734a95d55 391 }
va009039 0:2a9734a95d55 392
va009039 0:2a9734a95d55 393 int UsbFlashDrive::_bulkRecv(uint8_t* buf, int size)
va009039 0:2a9734a95d55 394 {
va009039 0:2a9734a95d55 395 TEST_ASSERT(m_pEpBulkIn);
va009039 1:80205a2de336 396 int ret = m_pEpBulkIn->bulkReceive(buf, size);
va009039 0:2a9734a95d55 397 return ret;
va009039 0:2a9734a95d55 398 }
va009039 0:2a9734a95d55 399
va009039 0:2a9734a95d55 400 int UsbFlashDrive::_bulkSend(const uint8_t* buf, int size)
va009039 0:2a9734a95d55 401 {
va009039 0:2a9734a95d55 402 TEST_ASSERT(m_pEpBulkOut);
va009039 1:80205a2de336 403 int ret = m_pEpBulkOut->bulkSend(buf, size);
va009039 0:2a9734a95d55 404 return ret;
va009039 0:2a9734a95d55 405 }