BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Revision:
3:6ae9a03a6145
Parent:
1:80205a2de336
Child:
5:495f7536897b
--- a/UsbFlashDrive/UsbFlashDrive.cpp	Tue Dec 11 15:28:00 2012 +0000
+++ b/UsbFlashDrive/UsbFlashDrive.cpp	Sun Jan 06 11:47:51 2013 +0000
@@ -1,4 +1,4 @@
-// UsbFlashDrive.cpp 2012/12/5
+// UsbFlashDrive.cpp 2013/1/5
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -6,15 +6,10 @@
 #include "BaseUsbHostDebug.h"
 #define TEST
 #include "BaseUsbHostTest.h"
-
 #include "UsbFlashDrive.h"
 
 //#define WRITE_PROTECT
 
-int LE16(const uint8_t* d)
-{
-    return d[0] | (d[1] << 8);
-}
 
 uint32_t BE32(uint8_t* d)
 {
@@ -46,6 +41,8 @@
         TEST_ASSERT_TRUE(ctlEp);
     }
 
+    CTASSERT(sizeof(CBW) == 31);
+    CTASSERT(sizeof(CSW) == 13);
     TEST_ASSERT(sizeof(CBW) == 31);
     TEST_ASSERT(sizeof(CSW) == 13);
 
@@ -68,18 +65,48 @@
     if (ctlEp == NULL) {
         return false;
     }
-    uint8_t buf[8];
-    int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, sizeof(buf));
+    CTASSERT(sizeof(StandardDeviceDescriptor) == 18);
+    CTASSERT(sizeof(StandardConfigurationDescriptor) == 9);
+    CTASSERT(sizeof(StandardInterfaceDescriptor) == 9);
+    TEST_ASSERT(sizeof(StandardDeviceDescriptor) == 18);
+    TEST_ASSERT(sizeof(StandardConfigurationDescriptor) == 9);
+    TEST_ASSERT(sizeof(StandardInterfaceDescriptor) == 9);
+
+    StandardDeviceDescriptor desc;
+    int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, reinterpret_cast<uint8_t*>(&desc), sizeof(StandardDeviceDescriptor));
     if (rc != USB_OK) {
         return false;
     }
-    DBG_BYTES("ConfigDescriptor 8bytes", buf, sizeof(buf));
-    TEST_ASSERT(buf[0] == 9);
-    TEST_ASSERT(buf[1] == 0x02);
-    if (buf[4] != 0x01) {
+    if (desc.bDeviceClass == 8) {
+        return true;
+    } else if (desc.bDeviceClass != 0x00) {
+        return false;
+    }
+    uint8_t temp[4];
+    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, temp, sizeof(temp));
+    if (rc != USB_OK) {
         return false;
-    }    
-    return true;
+    }
+    StandardConfigurationDescriptor* cfg = reinterpret_cast<StandardConfigurationDescriptor*>(temp);
+    uint8_t* buf = new uint8_t[cfg->wTotalLength];
+    
+    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, cfg->wTotalLength);
+    if (rc != USB_OK) {
+        return false;
+    }
+    DBG_HEX(buf, cfg->wTotalLength);
+    bool ret = false;
+    for(int pos = 0; pos < cfg->wTotalLength; pos += buf[pos]) {
+        StandardInterfaceDescriptor* desc = reinterpret_cast<StandardInterfaceDescriptor*>(buf+pos);
+        if (desc->bDescriptorType == 4) { // interface ?
+            if (desc->bInterfaceClass == 8 && desc->bInterfaceSubClass == 6 && desc->bInterfaceProtocol == 0x50) {
+                ret = true;
+            }
+            break;
+        }
+    }
+    delete[] buf;
+    return ret;
 }
 
 int UsbFlashDrive::disk_initialize()
@@ -165,64 +192,38 @@
 
 int UsbFlashDrive::ParseConfiguration(ControlEp* ctlEp)
 {
-  TEST_ASSERT(ctlEp);
-  int rc;
-  uint8_t ConfigDesc[9];
-  int index = 0;
-  rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
-  TEST_ASSERT(rc == USB_OK);
-  DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
-  TEST_ASSERT(ConfigDesc[0] == 9);
-  TEST_ASSERT(ConfigDesc[1] == 0x02);
-  int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
-  DBG("TotalLength: %d\n", wTotalLength);
-  int bConfigValue = ConfigDesc[5];
-  TEST_ASSERT(bConfigValue == 1);
-  DBG("ConfigValue: %d\n", bConfigValue);
-  DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);   
-
-  uint8_t* buf = new uint8_t[wTotalLength];
-  TEST_ASSERT(buf);
-  rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
-  TEST_ASSERT(rc == USB_OK);
-  TEST_ASSERT(ConfigDesc[1] == 0x02);
-  for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
-      DBG_BYTES("CFG", buf+pos, buf[pos]);
-      int type = buf[pos+1];
-      if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
-        DBG("InterfaceNumber: %d\n", buf[pos+2]);
-        DBG("AlternateSetting: %d\n", buf[pos+3]);
-        DBG("NumEndpoint: %d\n", buf[pos+4]);
-        DBG("InterfaceClass: %02X\n", buf[pos+5]);
-        DBG("InterfaceSubClass: %02X\n", buf[pos+6]);
-        DBG("InterfaceProtocol: %02X\n", buf[pos+7]);
-        TEST_ASSERT(buf[pos+6] == 0x06); // SCSI
-        TEST_ASSERT(buf[pos+7] == 0x50); // bulk only
-      } 
-      if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
-          TEST_ASSERT(buf[pos] == 7);
-          uint8_t att = buf[pos+3];
-          if (att == 2) { // bulk
-              uint8_t ep = buf[pos+2];
-              bool dir = ep & 0x80; // true=IN
-              uint16_t size = LE16(buf+pos+4);
-              DBG("EndpointAddress: %02X\n", ep);
-              DBG("Attribute: %02X\n", att);
-              DBG("MaxPacketSize: %d\n", size); 
-              BulkEp* pEp = new BulkEp(ctlEp->GetAddr(), ep, size);
-              TEST_ASSERT(pEp);
-              if (dir) {
-                  m_pEpBulkIn = pEp;
-              } else {
-                  m_pEpBulkOut = pEp;
-              } 
-          }
-      }
-  }
-  delete[] buf;
-  TEST_ASSERT(m_pEpBulkIn);
-  TEST_ASSERT(m_pEpBulkOut);
-  return 0;   
+    TEST_ASSERT(ctlEp);
+    TEST_ASSERT(sizeof(StandardEndpointDescriptor) == 7);
+    uint8_t temp[4];
+    int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, temp, sizeof(temp));
+    if (rc != USB_OK) {
+        return rc;
+    }
+    StandardConfigurationDescriptor* cfg = reinterpret_cast<StandardConfigurationDescriptor*>(temp);
+    uint8_t* buf = new uint8_t[cfg->wTotalLength];
+    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, cfg->wTotalLength);
+    if (rc != USB_OK) {
+        return rc;
+    }
+    DBG_HEX(buf, cfg->wTotalLength);
+    for(int pos = 0; pos < cfg->wTotalLength; pos += buf[pos]) {
+        StandardEndpointDescriptor* desc = reinterpret_cast<StandardEndpointDescriptor*>(buf+pos);
+        if (desc->bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT) {
+            if (desc->bmAttributes == 2) { // bulk
+                BulkEp* pEp = new BulkEp(ctlEp->GetAddr(), desc->bEndpointAddress, desc->wMaxPacketSize);
+                if (desc->bEndpointAddress & 0x80) {
+                    m_pEpBulkIn = pEp;
+                } else {
+                    m_pEpBulkOut = pEp;
+                }
+            }
+        }
+    }
+    delete[] buf;
+    if (m_pEpBulkIn && m_pEpBulkOut) {
+        return USB_OK;
+    }
+    return USB_ERROR;    
 }
 
 int UsbFlashDrive::BulkOnlyMassStorageReset(ControlEp* ctlEp)