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:
Wed Dec 05 13:23:06 2012 +0000
Parent:
0:b7d6879637a8
Child:
2:fe1e62051d88
Commit message:
add uvc class

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
BaseUsbHostCtlEp.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	Tue Dec 04 13:29:41 2012 +0000
+++ b/BaseUsbHost.h	Wed Dec 05 13:23:06 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHost.h 2012/12/4
+// BaseUsbHost.h 2012/12/5
 #ifndef BASE_USB_HOST_H
 #define BASE_USB_HOST_H
 
@@ -164,10 +164,6 @@
     int controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, const uint8_t* data=NULL, int length=0);
     int controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length);
     //
-    uint8_t DeviceClass;
-    uint8_t DeviceSubClass;
-    uint8_t DeviceProtocol;
-    //
     int open(int addr);
     void setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, uint16_t wLength=0);
 };
@@ -176,15 +172,15 @@
 public:
     BulkEp(int addr, uint8_t ep, uint16_t size);
     virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
-    int read(uint8_t* buf, int len, int millisec=osWaitForever);
-    int write(const uint8_t* buf, int len, int millisec=osWaitForever);
+    int bulkSend(const uint8_t* buf, int len, int millisec=osWaitForever);
+    int bulkReceive(uint8_t* buf, int len, int millisec=osWaitForever);
 };
 
 class InterruptEp : public BaseEp {
 public:
     InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0);
+    int interruptReceive(uint8_t* buf, int len, int millisec=osWaitForever);
     virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
-    int read(uint8_t* buf, int len, int millisec=osWaitForever);
 };
 
 class IsochronousEp : public BaseEp {
@@ -192,7 +188,8 @@
     IsochronousEp(int addr, uint8_t ep, uint16_t size);
     virtual void irqWdhHandler(HCTD* td);
     void reset();
-    HCITD* read();
+    HCITD* isochronousReveive();
+    int isochronousSend(uint8_t* buf, int len);
     HCITD* new_HCITD();
     HCITD* get_queue_HCITD(uint32_t millisec);
     int m_itd_queue_count;
@@ -201,6 +198,7 @@
     int m_FrameCount; // 1-8
 };
 
+// --- HUB --------------------------------------------------
 #define MAX_HUB_PORT 4
 
 class UsbHub {
@@ -218,5 +216,50 @@
     ControlEp* PortEp[MAX_HUB_PORT]; // port endpoint(control) 
 };
 
+// --- UVC --------------------------------------------------
+#define _30FPS  333333
+#define _25FPS  400000
+#define _20FPS  500000
+#define _15FPS  666666
+#define _10FPS 1000000
+#define _5FPS  2000000
+#define _1FPS 10000000
+
+#define SET_CUR  0x01
+#define GET_CUR  0x81
+#define GET_MIN  0x82
+#define GET_MAX  0x83
+#define GET_RES  0x84
+#define GET_LEN  0x85
+#define GET_INFO 0x86
+#define GET_DEF  0x87
+
+#define VS_PROBE_CONTROL  0x01
+#define VS_COMMIT_CONTROL 0x02
+
+class BaseUvc {
+public:
+    void poll();
+    int Control(int req, int cs, int index, uint8_t* buf, int size);
+    ControlEp* m_ctlEp;
+    IsochronousEp* m_isoEp;
+    uint32_t report_cc_count[16];  // ConditionCode
+    uint32_t report_ps_cc_count[16]; // Packt Status ConditionCode
+    // callback
+    void onResult(uint16_t frame, uint8_t* buf, int len);
+    void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) );
+    class CDummy;
+    template<class T> 
+    void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) )
+    {
+        m_pCb = NULL;
+        m_pCbItem = (CDummy*) pItem;
+        m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod;
+    }
+    void clearOnResult();
+    CDummy* m_pCbItem;
+    void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int);
+    void (*m_pCb)(uint16_t, uint8_t*, int);
+};
 
 #endif //BASE_USB_HOST_H
--- a/BaseUsbHostBlkEp.cpp	Tue Dec 04 13:29:41 2012 +0000
+++ b/BaseUsbHostBlkEp.cpp	Wed Dec 05 13:23:06 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostBlkEp.cpp 2012/12/3
+// BaseUsbHostBlkEp.cpp 2012/12/5
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -24,7 +24,7 @@
     LPC_USB->HcControl |= OR_CONTROL_BLE;
 }
 
-int BulkEp::read(uint8_t* buf, int len, int millisec)
+int BulkEp::bulkReceive(uint8_t* buf, int len, int millisec)
 {
     HCTD* data_td = m_pED->TailTd;
     TEST_ASSERT(data_td);
@@ -55,7 +55,7 @@
     return USB_ERROR;
 }
 
-int BulkEp::write(const uint8_t* buf, int len, int millisec)
+int BulkEp::bulkSend(const uint8_t* buf, int len, int millisec)
 {
     HCTD* data_td = m_pED->TailTd;
     TEST_ASSERT(data_td);
--- a/BaseUsbHostCtlEp.cpp	Tue Dec 04 13:29:41 2012 +0000
+++ b/BaseUsbHostCtlEp.cpp	Wed Dec 05 13:23:06 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostCtlEp.cpp 2012/12/4
+// BaseUsbHostCtlEp.cpp 2012/12/5
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -78,12 +78,6 @@
     TEST_ASSERT(buf[0] == 0x12);
     TEST_ASSERT(buf[1] == 0x01);
     TEST_ASSERT(buf[7] >= 8);
-    DeviceClass = buf[3];
-    DeviceSubClass = buf[4];
-    DeviceProtocol = buf[5];
-    DBG("DeviceClass: %02X\n", DeviceClass);
-    DBG("DeviceSubClass: %02X\n", DeviceSubClass);
-    DBG("DeviceProtocol: %02X\n", DeviceProtocol);
     update_MaxPacketSize(buf[7]);
     r = SetAddress(addr);    
     TEST_ASSERT(r == USB_OK);
--- a/BaseUsbHostIntEp.cpp	Tue Dec 04 13:29:41 2012 +0000
+++ b/BaseUsbHostIntEp.cpp	Wed Dec 05 13:23:06 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostIntEp.cpp 2012/12/4
+// BaseUsbHostIntEp.cpp 2012/12/5
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -23,7 +23,7 @@
     LPC_USB->HcControl |= OR_CONTROL_PLE;
 }
     
-int InterruptEp::read(uint8_t* buf, int len, int millisec)
+int InterruptEp::interruptReceive(uint8_t* buf, int len, int millisec)
 {
     if (m_td_queue_count == 0) {
         HCTD* data_td = m_pED->TailTd;
--- a/BaseUsbHostIsoEp.cpp	Tue Dec 04 13:29:41 2012 +0000
+++ b/BaseUsbHostIsoEp.cpp	Wed Dec 05 13:23:06 2012 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHostIsoEp.cpp 2012/12/4
+// BaseUsbHostIsoEp.cpp 2012/12/5
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -84,7 +84,7 @@
 }
 
 
-HCITD* IsochronousEp::read()
+HCITD* IsochronousEp::isochronousReveive()
 {
     TEST_ASSERT(m_itd_queue_count >= 0);
     while(m_itd_queue_count < HCTD_QUEUE_SIZE) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BaseUsbHostUvc.cpp	Wed Dec 05 13:23:06 2012 +0000
@@ -0,0 +1,74 @@
+// BaseUsbHostUvc.cpp 2012/12/5
+#include "mbed.h"
+#include "rtos.h"
+#include "BaseUsbHost.h"
+#define DEBUG
+#include "BaseUsbHostDebug.h"
+#define TEST
+#include "BaseUsbHostTest.h"
+
+void BaseUvc::poll()
+{
+    HCITD* itd = m_isoEp->isochronousReveive();
+    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;
+            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++) {
+                uint16_t pswn = itd->OffsetPSW[i];
+                cc = pswn>>12;
+                if (cc == 0 || cc == 9) {
+                    int len = pswn & 0x7ff;
+                    onResult(frame, buf, len);
+               }
+               report_ps_cc_count[cc]++;
+               buf += mps;
+               frame++;
+            }
+        }
+        m_isoEp->delete_HCTD(reinterpret_cast<HCTD*>(itd));
+    }
+}
+
+int BaseUvc::Control(int req, int cs, int index, uint8_t* buf, int size)
+{
+    TEST_ASSERT(m_ctlEp);
+    int rc;
+    if (req == SET_CUR) {    
+        rc = m_ctlEp->controlSend(
+                    USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
+                    req, cs<<8, index, buf, size);
+        return rc;
+    }
+    rc = m_ctlEp->controlReceive(
+                USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
+                req, cs<<8, index, buf, size);
+    return rc;
+}
+
+void BaseUvc::onResult(uint16_t frame, uint8_t* buf, int len)
+{
+  if(m_pCbItem && m_pCbMeth)
+    (m_pCbItem->*m_pCbMeth)(frame, buf, len);
+  else if(m_pCb)
+    m_pCb(frame, buf, len);
+}
+
+void BaseUvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) )
+{
+    m_pCb = pMethod;
+    m_pCbItem = NULL;
+    m_pCbMeth = NULL;
+}
+    
+void BaseUvc::clearOnResult()
+{
+    m_pCb = NULL;
+    m_pCbItem = NULL;
+    m_pCbMeth = NULL;
+}
+