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

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Tue Dec 11 15:26:54 2012 +0000
Parent:
1:3b7bc4f87a61
Child:
3:ae77d63a1eda
Commit message:
bug fix

Changed in this revision

BaseUsbHost.h Show annotated file Show diff for this revision Revisions of this file
BaseUsbHostBlkEp.cpp Show annotated file Show diff for this revision Revisions of this file
BaseUsbHostHub.cpp Show annotated file Show diff for this revision Revisions of this file
BaseUsbHostIntEp.cpp Show annotated file Show diff for this revision Revisions of this file
BaseUsbHostIsoEp.cpp Show annotated file Show diff for this revision Revisions of this file
BaseUsbHostUvc.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/BaseUsbHost.h	Wed Dec 05 13:23:06 2012 +0000
+++ b/BaseUsbHost.h	Tue Dec 11 15:26:54 2012 +0000
@@ -1,11 +1,11 @@
-// BaseUsbHost.h 2012/12/5
+// BaseUsbHost.h 2012/12/11
 #ifndef BASE_USB_HOST_H
 #define BASE_USB_HOST_H
 
-#define USB_OK       0
-#define USB_ERROR   -1
-#define USB_TIMEOUT -2
-#define USB_ERROR2  -3
+#define USB_OK            0
+#define USB_PROCESSING   -1
+#define USB_ERROR        -2
+#define USB_ERROR_MEMORY -3
 
 // USB STANDARD REQUEST DEFINITIONS
 #define  USB_DESCRIPTOR_TYPE_DEVICE         1
@@ -188,10 +188,10 @@
     IsochronousEp(int addr, uint8_t ep, uint16_t size);
     virtual void irqWdhHandler(HCTD* td);
     void reset();
-    HCITD* isochronousReveive();
-    int isochronousSend(uint8_t* buf, int len);
+    HCITD* isochronousReveive(int millisec=osWaitForever);
+    int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever);
     HCITD* new_HCITD();
-    HCITD* get_queue_HCITD(uint32_t millisec);
+    HCITD* get_queue_HCITD(int millisec);
     int m_itd_queue_count;
     uint16_t m_FrameNumber;
     int m_PacketSize; // 128,192
@@ -204,12 +204,14 @@
 class UsbHub {
 public:
     UsbHub(ControlEp* ctlEp = NULL);
+    ControlEp* GetPortEp(int port); // port: 1-4
+    int SetPortPower(int port);
+    int ClearPortPower(int port);
+protected:
     void DeviceConnected(int port, int low_speed);
     int PortReset(int port);
-    //
     int SetPortFeature(int feature, int index);
     int ClearPortFeature(int feature, int index);
-    int SetPortPower(int port);
     int SetPortReset(int port);
     int GetPortStatus(int port, uint32_t* status);
     ControlEp* m_ctlEp;
@@ -239,7 +241,7 @@
 
 class BaseUvc {
 public:
-    void poll();
+    void poll(int millisec=osWaitForever);
     int Control(int req, int cs, int index, uint8_t* buf, int size);
     ControlEp* m_ctlEp;
     IsochronousEp* m_isoEp;
--- a/BaseUsbHostBlkEp.cpp	Wed Dec 05 13:23:06 2012 +0000
+++ b/BaseUsbHostBlkEp.cpp	Tue Dec 11 15:26:54 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostBlkEp.cpp 2012/12/5
+// BaseUsbHostBlkEp.cpp 2012/12/11
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -10,10 +10,12 @@
 BulkEp::BulkEp(int addr, uint8_t ep, uint16_t size): BaseEp(addr, ep, size)
 {
     HCTD* td = new_HCTD();
-    TEST_ASSERT(td);
     m_pED->TailTd = td;
     m_pED->HeadTd = td; 
-
+    TEST_ASSERT(td);
+    if (td == NULL) {
+        return;
+    }
     m_pED->Next = LPC_USB->HcBulkHeadED;
     LPC_USB->HcBulkHeadED = reinterpret_cast<uint32_t>(m_pED);
     
@@ -26,44 +28,57 @@
 
 int BulkEp::bulkReceive(uint8_t* buf, int len, int millisec)
 {
-    HCTD* data_td = m_pED->TailTd;
-    TEST_ASSERT(data_td);
-    data_td->Control |= TD_IN;
-    data_td->CurrBufPtr = buf;
-    data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1;
-    HCTD* blank_td = new_HCTD();
-    TEST_ASSERT(blank_td);
-    data_td->Next = reinterpret_cast<uint32_t>(blank_td);
-    m_pED->TailTd = blank_td;
-    m_td_queue_count++;
-    DBG_ED(m_pED);
-
-    LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF;
-    LPC_USB->HcControl |= OR_CONTROL_BLE;
- 
+    if (m_td_queue_count == 0) {
+        HCTD* data_td = m_pED->TailTd;
+        TEST_ASSERT(data_td);
+        if (data_td == NULL) {
+            return USB_ERROR;
+        }
+        data_td->Control |= TD_IN;
+        data_td->CurrBufPtr = buf;
+        data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1;
+        HCTD* blank_td = new_HCTD();
+        TEST_ASSERT(blank_td);
+        if (blank_td == NULL) {
+            return USB_ERROR_MEMORY;
+        }
+        data_td->Next = reinterpret_cast<uint32_t>(blank_td);
+        m_pED->TailTd = blank_td;
+        m_td_queue_count++;
+        DBG_ED(m_pED);
+        LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF;
+        LPC_USB->HcControl |= OR_CONTROL_BLE;
+    }
+    
     HCTD* td = get_queue_HCTD(millisec);
-    if (td) {
-        DBG_TD(td);
-        int ret = len;
-        if (td->CurrBufPtr) {
-            ret = td->CurrBufPtr - buf;
-        }
-        delete_HCTD(td); 
-        m_td_queue_count--;
-        return ret;
+    if (td == NULL) {
+        return USB_PROCESSING;
     }
-    return USB_ERROR;
+    DBG_TD(td);
+    int ret = len;
+    if (td->CurrBufPtr) {
+        ret = td->CurrBufPtr - buf;
+    }
+    delete_HCTD(td); 
+    m_td_queue_count--;
+    return ret;
 }
 
 int BulkEp::bulkSend(const uint8_t* buf, int len, int millisec)
 {
     HCTD* data_td = m_pED->TailTd;
     TEST_ASSERT(data_td);
+    if (data_td == NULL) {
+        return USB_ERROR;
+    }
     data_td->Control |= TD_OUT;
     data_td->CurrBufPtr = const_cast<uint8_t*>(buf);
     data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1;
     HCTD* blank_td = new_HCTD();
     TEST_ASSERT(blank_td);
+    if (blank_td == NULL) {
+        return USB_ERROR_MEMORY;
+    }
     data_td->Next = reinterpret_cast<uint32_t>(blank_td);
     m_pED->TailTd = blank_td;
     m_td_queue_count++;
@@ -85,4 +100,3 @@
     }
     return USB_ERROR;
 }
-
--- a/BaseUsbHostHub.cpp	Wed Dec 05 13:23:06 2012 +0000
+++ b/BaseUsbHostHub.cpp	Tue Dec 11 15:26:54 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostHub.cpp 2012/12/4
+// BaseUsbHostHub.cpp 2012/12/11
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -21,31 +21,6 @@
 #define C_PORT_OVER_CURRENT 19
 #define C_PORT_RESET 20
 
-int UsbHub::SetPortFeature(int feature, int index)
-{
-    return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0);
-}
-
-int UsbHub::ClearPortFeature(int feature, int index)
-{
-    return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0);
-}
-
-int UsbHub::SetPortPower(int port)
-{
-    return SetPortFeature(PORT_POWER, port);
-}
-
-int UsbHub::SetPortReset(int port)
-{
-    return SetPortFeature(PORT_RESET, port);
-}
-
-int UsbHub::GetPortStatus(int port, uint32_t* status)
-{
-    return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4);
-}
-
 UsbHub::UsbHub(ControlEp* ctlEp)
 {
     for(int i = 0; i < MAX_HUB_PORT; i++) {
@@ -86,10 +61,7 @@
     DBG("HUB STATUS: %08X\n", status);
 
     for(int i = 1; i <= bNbrPorts; i++) {
-        SetPortFeature(PORT_POWER, i); // power on
-    }
-
-    for(int i = 1; i <= bNbrPorts; i++) {
+        SetPortPower(i); // power on
         uint32_t status;
         GetPortStatus(i, &status);
         DBG("port: %d status: %08X\n", i, status);
@@ -101,10 +73,50 @@
                 low_speed = true;
             }
             DeviceConnected(i, low_speed);
+        } else {
+            ClearPortPower(i); // power on
         }
     }
 }
 
+ControlEp* UsbHub::GetPortEp(int port)
+{
+    if (port >= 1 && port <= MAX_HUB_PORT) {
+        return PortEp[port-1];
+    }
+    return NULL;
+}
+
+int UsbHub::SetPortPower(int port)
+{
+    return SetPortFeature(PORT_POWER, port);
+}
+
+int UsbHub::ClearPortPower(int port)
+{
+    return ClearPortFeature(PORT_POWER, port);
+}
+
+int UsbHub::SetPortFeature(int feature, int index)
+{
+    return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0);
+}
+
+int UsbHub::ClearPortFeature(int feature, int index)
+{
+    return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0);
+}
+
+int UsbHub::SetPortReset(int port)
+{
+    return SetPortFeature(PORT_RESET, port);
+}
+
+int UsbHub::GetPortStatus(int port, uint32_t* status)
+{
+    return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4);
+}
+
 void UsbHub::DeviceConnected(int port, int low_speed)
 {
     DBG("port=%d low_speed=%d\n", port, low_speed);
--- a/BaseUsbHostIntEp.cpp	Wed Dec 05 13:23:06 2012 +0000
+++ b/BaseUsbHostIntEp.cpp	Tue Dec 11 15:26:54 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostIntEp.cpp 2012/12/5
+// BaseUsbHostIntEp.cpp 2012/12/11
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -11,12 +11,17 @@
     :BaseEp(addr, ep, size, lowSpeed)
 {
     HCTD* td = new_HCTD();
-    TEST_ASSERT(td);
     m_pED->TailTd = td;
     m_pED->HeadTd = td; 
-
+    TEST_ASSERT(td);
+    if (td == NULL) {
+        return;
+    }
     HCCA* pHcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
     TEST_ASSERT(pHcca);
+    if (pHcca == NULL) {
+        return;
+    }
     int n = 0;
     m_pED->Next = pHcca->InterruptTable[n];
     pHcca->InterruptTable[n] = reinterpret_cast<uint32_t>(m_pED);
@@ -28,11 +33,17 @@
     if (m_td_queue_count == 0) {
         HCTD* data_td = m_pED->TailTd;
         TEST_ASSERT(data_td);
+        if (data_td == NULL) {
+            return USB_ERROR;
+        }
         data_td->Control |= TD_IN;
         data_td->CurrBufPtr = buf;
         data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1;
         HCTD* blank_td = new_HCTD();
         TEST_ASSERT(blank_td);
+        if (blank_td == NULL) {
+            return USB_ERROR_MEMORY;
+        }
         data_td->Next = reinterpret_cast<uint32_t>(blank_td);
         m_pED->TailTd = blank_td;
         m_td_queue_count++;
@@ -41,15 +52,15 @@
     }
         
     HCTD* td = get_queue_HCTD(millisec);
-    if (td) {
-        DBG_TD(td);
-        int ret = len;
-        if (td->CurrBufPtr) {
-            ret = td->CurrBufPtr - buf;
-        }
-        delete_HCTD(td); 
-        m_td_queue_count--;
-        return ret;
+    if (td == NULL) {
+        return USB_PROCESSING;
     }
-    return USB_TIMEOUT;
+    DBG_TD(td);
+    int ret = len;
+    if (td->CurrBufPtr) {
+        ret = td->CurrBufPtr - buf;
+    }
+    delete_HCTD(td); 
+    m_td_queue_count--;
+    return ret;
 }
--- a/BaseUsbHostIsoEp.cpp	Wed Dec 05 13:23:06 2012 +0000
+++ b/BaseUsbHostIsoEp.cpp	Tue Dec 11 15:26:54 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostIsoEp.cpp 2012/12/5
+// BaseUsbHostIsoEp.cpp 2012/12/11
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -16,16 +16,22 @@
 
     TEST_ASSERT(size >= 128 && size <= 1023);
     m_PacketSize = size;
-    m_FrameCount = 8;
+    m_FrameCount = 4; // 1-8
+    TEST_ASSERT(m_FrameCount >= 1 && m_FrameCount <= 8);
     m_itd_queue_count = 0;
     reset();
     HCITD* itd = new_HCITD();
-    TEST_ASSERT(itd);
     m_pED->TailTd = reinterpret_cast<HCTD*>(itd);
     m_pED->HeadTd = reinterpret_cast<HCTD*>(itd); 
-
+    TEST_ASSERT(itd);
+    if (itd == NULL) {
+        return;
+    }
     HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
     TEST_ASSERT(hcca);
+    if (hcca == NULL) {
+        return;
+    }
     for(int i = 0; i < 32; i++) {
         if (hcca->InterruptTable[i] == 0) {
             hcca->InterruptTable[i] = reinterpret_cast<uint32_t>(m_pED);
@@ -84,15 +90,20 @@
 }
 
 
-HCITD* IsochronousEp::isochronousReveive()
+HCITD* IsochronousEp::isochronousReveive(int millisec)
 {
     TEST_ASSERT(m_itd_queue_count >= 0);
-    while(m_itd_queue_count < HCTD_QUEUE_SIZE) {
+    while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) {
         HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd);
         TEST_ASSERT(itd);
-        //DBG_ITD(itd);
+        if (itd == NULL) {
+            return NULL;
+        }
         HCITD* blank_itd = new_HCITD();
         TEST_ASSERT(blank_itd);
+        if (blank_itd == NULL) {
+            return NULL;
+        }
         itd->Next = reinterpret_cast<uint32_t>(blank_itd);
         m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd);
         m_itd_queue_count++;
@@ -100,21 +111,23 @@
         LPC_USB->HcControl |= OR_CONTROL_PLE; // Enable Periodic
     }
     
-    HCITD* itd = get_queue_HCITD(1);
+    HCITD* itd = get_queue_HCITD(millisec);
     if (itd) {
         m_itd_queue_count--;
     }
     return itd;
 }
 
-HCITD* IsochronousEp::get_queue_HCITD(uint32_t millisec)
+HCITD* IsochronousEp::get_queue_HCITD(int millisec)
 {
     for(int i = 0; i < 16; i++) {
         osEvent evt = m_queue.get(millisec);
         if (evt.status == osEventMessage) {
             HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p);
             TEST_ASSERT(itd);
-            //led3 = !led3;
+            if (itd == NULL) {
+                return NULL;
+            }
             uint8_t cc = itd->Control>>28;
             if (cc != 0) {
                 m_ConditionCode = cc;
@@ -127,8 +140,8 @@
         } else {
             DBG("evt.status: %02x\n", evt.status);
             TEST_ASSERT(evt.status == osEventMessage);
+            return NULL;
         }
     }
     return NULL;
 }
-
--- a/BaseUsbHostUvc.cpp	Wed Dec 05 13:23:06 2012 +0000
+++ b/BaseUsbHostUvc.cpp	Tue Dec 11 15:26:54 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostUvc.cpp 2012/12/5
+// BaseUsbHostUvc.cpp 2012/12/11
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -7,18 +7,20 @@
 #define TEST
 #include "BaseUsbHostTest.h"
 
-void BaseUvc::poll()
+void BaseUvc::poll(int millisec)
 {
-    HCITD* itd = m_isoEp->isochronousReveive();
+    HCITD* itd = m_isoEp->isochronousReveive(millisec);
     if (itd) {
         uint8_t cc = itd->Control>>28;
         report_cc_count[cc]++;
         if (cc == 0) { // ConditionCode
             //DBG_ITD(itd);
             uint16_t frame = itd->Control & 0xffff;
+            int fc = ((itd->Control>>24)&7)+1;
+            TEST_ASSERT(fc == m_isoEp->m_FrameCount);
             uint8_t* buf = const_cast<uint8_t*>(itd->buf); 
             int mps = m_isoEp->m_PacketSize;
-            for(int i = 0; i < m_isoEp->m_FrameCount; i++) {
+            for(int i = 0; i < fc; i++) {
                 uint16_t pswn = itd->OffsetPSW[i];
                 cc = pswn>>12;
                 if (cc == 0 || cc == 9) {