BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Committer:
va009039
Date:
Fri Jan 25 14:55:08 2013 +0000
Revision:
5:495f7536897b
Parent:
3:6ae9a03a6145
update library

Who changed what in which revision?

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