BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS
Dependencies: FatFileSystem mbed
Fork of BTstack by
msc.cpp
00001 #include "msc.h" 00002 //#define __DEBUG 00003 #include "mydbg.h" 00004 #include "Utils.h" 00005 00006 //#define WRITE_PROTECT 00007 00008 msc::msc(const char* name, int drive): FATFileSystem(name) 00009 { 00010 DBG("drive=%d\n", drive); 00011 m_name = name; 00012 m_drive = drive; 00013 DBG_ASSERT(sizeof(CBW) == 31); 00014 DBG_ASSERT(sizeof(CSW) == 13); 00015 m_numBlocks = 0; 00016 m_BlockSize = 0; 00017 m_lun = 0; 00018 m_interface = 0; 00019 m_pDev = NULL; 00020 m_pEpBulkIn = NULL; 00021 m_pEpBulkOut = NULL; 00022 } 00023 00024 int msc::disk_initialize() 00025 { 00026 DBG("m_BlockSize=%d\n", m_BlockSize); 00027 if (m_BlockSize != 512) { 00028 return 1; 00029 } 00030 return 0; 00031 } 00032 00033 int msc::disk_write(const char *buffer, int block_number) 00034 { 00035 DBG("buffer=%p block_number=%d\n", buffer, block_number); 00036 int ret = MS_BulkSend(block_number, 1, (uint8_t*)buffer); 00037 if (ret >= 0) { 00038 return 0; 00039 } 00040 return 1; 00041 } 00042 00043 int msc::disk_read(char *buffer, int block_number) 00044 { 00045 DBG("buffer=%p block_number=%d\n", buffer, block_number); 00046 int ret = MS_BulkRecv(block_number, 1, (uint8_t*)buffer); 00047 if (ret >= 0) { 00048 return 0; 00049 } 00050 return 1; 00051 } 00052 00053 int msc::disk_status() 00054 { 00055 DBG("\n"); 00056 return 0; 00057 } 00058 00059 int msc::disk_sync() 00060 { 00061 DBG("\n"); 00062 return 0; 00063 } 00064 00065 int msc::disk_sectors() 00066 { 00067 DBG("m_numBlocks=%d\n", m_numBlocks); 00068 return m_numBlocks; 00069 } 00070 00071 int msc::setup(int timeout) 00072 { 00073 for(int i = 0; i < 2; i++) { 00074 m_pDev = m_pHost->getDeviceByClass(0x08, m_drive); // USB Mass Storage Class 00075 if (m_pDev || i > 0) { 00076 break; 00077 } 00078 UsbErr rc = Usb_poll(); 00079 if (rc == USBERR_PROCESSING) { 00080 VERBOSE("%p USBERR_PROCESSING\n", this); 00081 return -1; 00082 } 00083 } 00084 DBG("m_pDev=%p\n", m_pDev); 00085 if (m_pDev == NULL) { 00086 VERBOSE("%p MSC DISK(%d) NOT FOUND\n", this, m_drive); 00087 return -1; 00088 } 00089 DBG_ASSERT(m_pDev); 00090 00091 ParseConfiguration(); 00092 00093 GetMaxLUN(); 00094 00095 int retry = 0; 00096 Timer t; 00097 t.start(); 00098 t.reset(); 00099 while(t.read_ms() < timeout) { 00100 DBG("retry=%d t=%d\n", retry, t.read_ms()); 00101 if (retry > 80) { 00102 return -1; 00103 } 00104 int rc = TestUnitReady(); 00105 DBG("TestUnitReady(): %d\n", rc); 00106 if (rc == USBERR_OK) { 00107 DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus); 00108 if (m_CSW.bCSWStatus == 0x00) { 00109 break; 00110 } 00111 } 00112 GetSenseInfo(); 00113 retry++; 00114 wait_ms(50); 00115 } 00116 if (t.read_ms() >= timeout) { 00117 return -1; 00118 } 00119 ReadCapacity(); 00120 Inquire(); 00121 return 0; 00122 } 00123 void msc::_test() 00124 { 00125 ReadCapacity(); 00126 00127 char buf[512]; 00128 for(int block = 0; block < m_numBlocks; block++) { 00129 DBG("block=%d\n", block); 00130 disk_read(buf, block); 00131 } 00132 exit(1); 00133 } 00134 00135 int msc::ParseConfiguration() 00136 { 00137 UsbErr rc; 00138 uint8_t ConfigDesc[9]; 00139 int index = 0; 00140 DBG_ASSERT(m_pDev); 00141 rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); 00142 DBG_ASSERT(rc == USBERR_OK); 00143 DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); 00144 DBG_ASSERT(ConfigDesc[0] == 9); 00145 DBG_ASSERT(ConfigDesc[1] == 0x02); 00146 int wTotalLength = *((uint16_t*)&ConfigDesc[2]); 00147 DBG("TotalLength: %d\n", wTotalLength); 00148 int bConfigValue = ConfigDesc[5]; 00149 DBG_ASSERT(bConfigValue == 1); 00150 DBG("ConfigValue: %d\n", bConfigValue); 00151 DBG("MaxPower: %d mA\n", ConfigDesc[8]*2); 00152 00153 uint8_t* buf = new uint8_t[wTotalLength]; 00154 DBG_ASSERT(buf); 00155 rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); 00156 DBG_ASSERT(rc == USBERR_OK); 00157 DBG_ASSERT(ConfigDesc[1] == 0x02); 00158 for (int pos = 0; pos < wTotalLength; pos += buf[pos]) { 00159 DBG_BYTES("CFG", buf+pos, buf[pos]); 00160 int type = buf[pos+1]; 00161 if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04 00162 DBG("InterfaceNumber: %d\n", buf[pos+2]); 00163 DBG("AlternateSetting: %d\n", buf[pos+3]); 00164 DBG("NumEndpoint: %d\n", buf[pos+4]); 00165 DBG("InterfaceClass: %02X\n", buf[pos+5]); 00166 DBG("InterfaceSubClass: %02X\n", buf[pos+6]); 00167 DBG("InterfaceProtocol: %02X\n", buf[pos+7]); 00168 DBG_ASSERT(buf[pos+6] == 0x06); // SCSI 00169 DBG_ASSERT(buf[pos+7] == 0x50); // bulk only 00170 } 00171 if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) { 00172 DBG_ASSERT(buf[pos] == 7); 00173 uint8_t att = buf[pos+3]; 00174 if (att == 2) { // bulk 00175 uint8_t ep = buf[pos+2]; 00176 bool dir = ep & 0x80; // true=IN 00177 uint16_t size = LE16(buf+pos+4); 00178 DBG("EndpointAddress: %02X\n", ep); 00179 DBG("Attribute: %02X\n", att); 00180 DBG("MaxPacketSize: %d\n", size); 00181 UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, USB_BULK, size); 00182 DBG_ASSERT(pEp); 00183 if (dir) { 00184 m_pEpBulkIn = pEp; 00185 } else { 00186 m_pEpBulkOut = pEp; 00187 } 00188 } 00189 } 00190 } 00191 delete[] buf; 00192 DBG_ASSERT(m_pEpBulkIn); 00193 DBG_ASSERT(m_pEpBulkOut); 00194 return 0; 00195 } 00196 00197 int msc::BulkOnlyMassStorageReset() 00198 { 00199 DBG_ASSERT(m_pDev); 00200 UsbErr rc = m_pDev->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); 00201 DBG_ASSERT(rc == USBERR_OK); 00202 return rc; 00203 } 00204 00205 int msc::GetMaxLUN() 00206 { 00207 DBG_ASSERT(m_interface == 0); 00208 uint8_t temp[1]; 00209 DBG_ASSERT(m_pDev); 00210 UsbErr rc = m_pDev->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); 00211 DBG_ASSERT(rc == USBERR_OK); 00212 DBG_BYTES("GetMaxLUN", temp, sizeof(temp)); 00213 m_MaxLUN = temp[0]; 00214 DBG_ASSERT(m_MaxLUN <= 15); 00215 return rc; 00216 } 00217 00218 00219 int msc::TestUnitReady() 00220 { 00221 const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00}; 00222 m_CBW.dCBWDataTraansferLength = 0; 00223 m_CBW.bmCBWFlags = 0x00; 00224 CommandTransport(cdb, sizeof(cdb)); 00225 StatusTransport(); 00226 return 0; 00227 } 00228 00229 int msc::GetSenseInfo() 00230 { 00231 const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00}; 00232 m_CBW.dCBWDataTraansferLength = 18; 00233 m_CBW.bmCBWFlags = 0x80; // data In 00234 CommandTransport(cdb, sizeof(cdb)); 00235 00236 uint8_t buf[18]; 00237 _bulkRecv(buf, sizeof(buf)); 00238 DBG_HEX(buf, sizeof(buf)); 00239 00240 StatusTransport(); 00241 DBG_ASSERT(m_CSW.bCSWStatus == 0x00); 00242 return 0; 00243 } 00244 00245 int msc::ReadCapacity() 00246 { 00247 const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00, 00248 0x00, 0x00, 0x00, 0x00, 0x00}; 00249 m_CBW.dCBWDataTraansferLength = 8; 00250 m_CBW.bmCBWFlags = 0x80; // data In 00251 CommandTransport(cdb, sizeof(cdb)); 00252 00253 uint8_t buf[8]; 00254 int rc = _bulkRecv(buf, sizeof(buf)); 00255 DBG_ASSERT(rc >= 0); 00256 DBG_HEX(buf, sizeof(buf)); 00257 00258 StatusTransport(); 00259 DBG_ASSERT(m_CSW.bCSWStatus == 0x00); 00260 00261 m_numBlocks = BE32(buf); 00262 m_BlockSize = BE32(buf+4); 00263 DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize); 00264 DBG_ASSERT(m_BlockSize == 512); 00265 DBG_ASSERT(m_numBlocks > 0); 00266 return 0; 00267 } 00268 00269 int msc::Inquire() 00270 { 00271 const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00}; 00272 m_CBW.dCBWDataTraansferLength = 36; 00273 m_CBW.bmCBWFlags = 0x80; // data In 00274 CommandTransport(cdb, sizeof(cdb)); 00275 00276 uint8_t buf[36]; 00277 _bulkRecv(buf, sizeof(buf)); 00278 DBG_HEX(buf, sizeof(buf)); 00279 00280 StatusTransport(); 00281 return 0; 00282 } 00283 00284 int msc::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer) 00285 { 00286 DBG_ASSERT(m_BlockSize == 512); 00287 DBG_ASSERT(num_blocks == 1); 00288 DBG_ASSERT(user_buffer); 00289 uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00, 00290 0x00, 0x00, 0x00, 0x00, 0x00}; 00291 BE32(block_number, cdb+2); 00292 BE16(num_blocks, cdb+7); 00293 uint32_t len = m_BlockSize * num_blocks; 00294 DBG_ASSERT(len <= 512); 00295 m_CBW.dCBWDataTraansferLength = len; 00296 m_CBW.bmCBWFlags = 0x80; // data In 00297 CommandTransport(cdb, sizeof(cdb)); 00298 00299 int ret = _bulkRecv(user_buffer, len); 00300 //DBG_HEX(user_buffer, len); 00301 00302 StatusTransport(); 00303 DBG_ASSERT(m_CSW.bCSWStatus == 0x00); 00304 return ret; 00305 } 00306 00307 int msc::MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer) 00308 { 00309 #ifdef WRITE_PROTECT 00310 return 0; 00311 #else 00312 DBG_ASSERT(num_blocks == 1); 00313 DBG_ASSERT(user_buffer); 00314 uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00, 00315 0x00, 0x00, 0x00, 0x00, 0x00}; 00316 BE32(block_number, cdb+2); 00317 BE16(num_blocks, cdb+7); 00318 uint32_t len = m_BlockSize * num_blocks; 00319 DBG_ASSERT(len <= 512); 00320 m_CBW.dCBWDataTraansferLength = len; 00321 m_CBW.bmCBWFlags = 0x00; // data Out 00322 CommandTransport(cdb, sizeof(cdb)); 00323 00324 int ret = _bulkSend(user_buffer, len); 00325 //DBG_HEX(user_buffer, len); 00326 00327 StatusTransport(); 00328 DBG_ASSERT(m_CSW.bCSWStatus == 0x00); 00329 return ret; 00330 #endif //WRITE_PROTECT 00331 } 00332 00333 int msc::CommandTransport(const uint8_t* cdb, int size) 00334 { 00335 DBG_ASSERT(cdb); 00336 DBG_ASSERT(size >= 6); 00337 DBG_ASSERT(size <= 16); 00338 m_CBW.bCBWLUN = m_lun; 00339 m_CBW.bCBWCBLength = size; 00340 memcpy(m_CBW.CBWCB, cdb, size); 00341 00342 m_CBW.dCBWSignature = 0x43425355; 00343 m_CBW.dCBWTag = m_tag++; 00344 m_CBW.bCBWLUN = 0; 00345 //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW)); 00346 int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW)); 00347 return rc; 00348 } 00349 00350 int msc::StatusTransport() 00351 { 00352 DBG_ASSERT(sizeof(CSW) == 13); 00353 int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW)); 00354 //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW)); 00355 DBG_ASSERT(m_CSW.dCSWSignature == 0x53425355); 00356 DBG_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag); 00357 DBG_ASSERT(m_CSW.dCSWDataResidue == 0); 00358 return rc; 00359 } 00360 00361 int msc::_bulkRecv(uint8_t* buf, int size) 00362 { 00363 UsbErr rc = m_pEpBulkIn->transfer(buf, size); 00364 DBG_ASSERT(rc == USBERR_PROCESSING); 00365 while(m_pEpBulkIn->status() == USBERR_PROCESSING){ 00366 wait_us(1); 00367 } 00368 int ret = m_pEpBulkIn->status(); 00369 if (ret >= 0) { 00370 return ret; 00371 } 00372 DBG("buf=%p size=%d ret=%d\n", buf, size, ret); 00373 return ret; 00374 } 00375 00376 int msc::_bulkSend(uint8_t* buf, int size) 00377 { 00378 DBG_ASSERT(m_pEpBulkOut); 00379 UsbErr rc = m_pEpBulkOut->transfer(buf, size); 00380 DBG_ASSERT(rc == USBERR_PROCESSING); 00381 while(m_pEpBulkOut->status() == USBERR_PROCESSING){ 00382 wait_us(1); 00383 } 00384 int ret = m_pEpBulkOut->status(); 00385 if (ret >= 0) { 00386 return ret; 00387 } 00388 DBG("buf=%p size=%d ret=%d\n", buf, size, ret); 00389 return ret; 00390 }
Generated on Thu Jul 14 2022 15:03:49 by 1.7.2