USB host library, support isochronous,bulk,interrupt and control.

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BaseUsbHostHub.cpp Source File

BaseUsbHostHub.cpp

00001 // BaseUsbHostHub.cpp 2013/1/25
00002 #include "mbed.h"
00003 #include "rtos.h"
00004 #include "BaseUsbHost.h"
00005 //#define DEBUG
00006 #include "BaseUsbHostDebug.h"
00007 #define TEST
00008 #include "BaseUsbHostTest.h"
00009 
00010 #define PORT_CONNECTION   0
00011 #define PORT_ENABLE       1
00012 #define PORT_SUSPEND      2
00013 #define PORT_OVER_CURRENT 3
00014 #define PORT_RESET        4
00015 #define PORT_POWER        8
00016 #define PORT_LOW_SPEED    9
00017 
00018 #define C_PORT_CONNECTION   16
00019 #define C_PORT_ENABLE       17
00020 #define C_PORT_SUSPEND      18
00021 #define C_PORT_OVER_CURRENT 19
00022 #define C_PORT_RESET        20
00023 
00024 UsbHub::UsbHub(ControlEp* ctlEp)
00025 {
00026     if (ctlEp == NULL) {
00027         DBG_OHCI(LPC_USB->HcRhPortStatus1);
00028         int lowSpeed = 0;
00029         if (LPC_USB->HcRhPortStatus1 & 0x200) {
00030             lowSpeed = 1;
00031         }
00032         m_ctlEp = new ControlEp(lowSpeed);
00033         TEST_ASSERT_TRUE(m_ctlEp);
00034     } else {
00035         m_ctlEp = ctlEp;
00036     }
00037     CTASSERT(sizeof(StandardDeviceDescriptor) == 18);
00038     StandardDeviceDescriptor devdesc;
00039     int rc = m_ctlEp->GetDescriptor(1, 0, reinterpret_cast<uint8_t*>(&devdesc), sizeof(StandardDeviceDescriptor));
00040     TEST_ASSERT(rc == USB_OK);
00041     if (rc != USB_OK) {
00042         return;
00043     }
00044     TEST_ASSERT_TRUE(devdesc.bLength == 0x12);
00045     TEST_ASSERT_TRUE(devdesc.bDescriptorType == 0x01);
00046     TEST_ASSERT_TRUE(devdesc.bDeviceClass == 0x09); // hub
00047     if (devdesc.bDeviceClass != 0x09) { // hub ?
00048         return;
00049     }
00050     CTASSERT(sizeof(HubDescriptor) == 9);
00051     TEST_ASSERT(sizeof(HubDescriptor) == 9);
00052     HubDescriptor hubdesc;
00053     rc = m_ctlEp->controlReceive(0xa0, 6, 0x29<<8, 0, reinterpret_cast<uint8_t*>(&hubdesc), sizeof(HubDescriptor));
00054     TEST_ASSERT(rc == USB_OK);
00055     if (rc != USB_OK) {
00056         return;
00057     }
00058     TEST_ASSERT(hubdesc.bDescLength == 9); // length
00059     TEST_ASSERT(hubdesc.bDescriptorType == 0x29); // hub
00060     TEST_ASSERT(hubdesc.bNbrPorts >= 1);
00061     TEST_ASSERT(hubdesc.bNbrPorts <= 16);
00062 
00063     m_ctlEp->SetConfiguration(1);
00064 
00065     uint32_t status;
00066     rc = m_ctlEp->controlReceive(0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4);
00067     TEST_ASSERT(rc == USB_OK);
00068     if (rc != USB_OK) {
00069         return;
00070     }
00071     DBG("HUB STATUS: %08X\n", status);
00072 
00073     for(int i = 1; i <= hubdesc.bNbrPorts; i++) {
00074         SetPortPower(i); // power on
00075         wait_ms(hubdesc.bPwrOn2PwrGood*2);
00076         uint32_t status;
00077         GetPortStatus(i, &status);
00078         DBG("port: %d status: %08X\n", i, status);
00079         if (status & 0x010000) { // Connect Status Change, has changed
00080             TEST_ASSERT(status & 0x000001);
00081             ClearPortFeature(C_PORT_CONNECTION, i);
00082             int lowSpeed = 0;
00083             if (status & 0x0200) {
00084                 lowSpeed = 1;
00085             }
00086             PortReset(i);
00087             ControlEp* ctlEp = new ControlEp(lowSpeed);
00088             PortEp.push_back(ctlEp);
00089         } else {
00090             ClearPortPower(i); // power off
00091         }
00092     }
00093 }
00094 
00095 bool UsbHub::check(ControlEp* ctlEp)
00096 {
00097     if (ctlEp == NULL) {
00098         return false;
00099     }
00100     StandardDeviceDescriptor desc;
00101     int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, reinterpret_cast<uint8_t*>(&desc), sizeof(StandardDeviceDescriptor));
00102     if (rc != USB_OK) {
00103         return false;
00104     }
00105     if (desc.bDeviceClass == 9) { // hub?
00106         return true;
00107     }
00108     return false;
00109 }
00110 
00111 int UsbHub::SetPortPower(int port)
00112 {
00113     return SetPortFeature(PORT_POWER, port);
00114 }
00115 
00116 int UsbHub::ClearPortPower(int port)
00117 {
00118     return ClearPortFeature(PORT_POWER, port);
00119 }
00120 
00121 int UsbHub::SetPortFeature(int feature, int index)
00122 {
00123     return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0);
00124 }
00125 
00126 int UsbHub::ClearPortFeature(int feature, int index)
00127 {
00128     return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0);
00129 }
00130 
00131 int UsbHub::SetPortReset(int port)
00132 {
00133     return SetPortFeature(PORT_RESET, port);
00134 }
00135 
00136 int UsbHub::GetPortStatus(int port, uint32_t* status)
00137 {
00138     return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4);
00139 }
00140 
00141 int UsbHub::PortReset(int port)
00142 {
00143     DBG("%p port=%d\n", this, port);
00144     TEST_ASSERT(port >= 1);
00145     SetPortReset(port);
00146     // wait reset
00147     for(int i = 0; i < 100; i++) {
00148         uint32_t status;    
00149         GetPortStatus(port, &status);
00150         DBG("RESET port: %d status: %08X\n", port, status);
00151         if (status & 0x100000) { // Reset change , Reset complete
00152             return USB_OK;
00153         }
00154         wait_ms(5);
00155      }
00156      return USB_ERROR;
00157 }