BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Committer:
va009039
Date:
Tue Dec 04 13:39:57 2012 +0000
Revision:
0:2a9734a95d55
Child:
1:80205a2de336
first commit

Who changed what in which revision?

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