BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

Committer:
todotani
Date:
Wed Feb 20 14:18:38 2013 +0000
Revision:
6:cf06ba884429
Parent:
0:1ed23ab1345f
Change tick timer to 1ms. Change attribute 0xFFF1 as read of DigitalIn p5

Who changed what in which revision?

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