BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Revision:
0:2a9734a95d55
Child:
1:80205a2de336
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LogitechC270/LogitechC270.cpp	Tue Dec 04 13:39:57 2012 +0000
@@ -0,0 +1,157 @@
+// LogitechC270.cpp 2012/12/4
+#include "mbed.h"
+#include "rtos.h"
+#include "BaseUsbHost.h"
+#define DEBUG
+#include "BaseUsbHostDebug.h"
+#define TEST
+#include "BaseUsbHostTest.h"
+#include "LogitechC270.h"
+
+LogitechC270::LogitechC270(int frame, uint32_t interval, ControlEp* ctlEp)
+{
+    uint8_t buf[26];
+    
+    if (ctlEp == NULL) { // root hub
+        DBG_OHCI(LPC_USB->HcRhPortStatus1);
+        TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
+        m_ctlEp = new ControlEp();
+        TEST_ASSERT_TRUE(m_ctlEp);
+    } else {
+        m_ctlEp = ctlEp;
+    }
+
+    int r = m_ctlEp->GetDescriptor(1, 0, buf, 18);
+    TEST_ASSERT(r == USB_OK);
+    DBG_HEX(buf, 18);
+    vid = *reinterpret_cast<uint16_t*>(buf+8);
+    pid = *reinterpret_cast<uint16_t*>(buf+10);
+    DBG("VID PID: %04X %04X\n", vid, pid);
+    TEST_ASSERT(vid == 0x046d && pid == 0x0825);
+    int addr = m_ctlEp->GetAddr();
+    DBG("addr: %d\n", addr);
+
+    m_isoEp = new IsochronousEp(addr, 0x81, 192);
+    TEST_ASSERT_TRUE(m_isoEp);
+
+    int rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_INFO Prob", buf, 1);
+
+    rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, 26);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_DEF Probe", buf, 26);
+
+    rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, 26);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_MIN Probe", buf, 26);
+
+    rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, 26);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_MAX Probe", buf, 26);
+
+    rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, 26);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_CUR Probe", buf, 26);
+
+    memset(buf, 0, 26);
+    buf[2] = C270_MJPEG;
+    buf[3] = frame;
+    *reinterpret_cast<uint32_t*>(buf+4) = interval;
+    
+    DBG_BYTES("SET_CUR Commit", buf, 26);
+    rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, 26);
+    TEST_ASSERT(rc == USB_OK);
+
+    rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, 26);
+    TEST_ASSERT(rc == USB_OK);
+    TEST_ASSERT_EQUAL(buf[2], C270_MJPEG);
+    TEST_ASSERT_EQUAL(buf[3], frame);
+    TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval);
+    DBG_BYTES("GET_CUR Commit", buf, 26);
+
+    int cfg;
+    rc = m_ctlEp->GetConfiguration(&cfg);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("config: %d\n", cfg);
+
+    rc = m_ctlEp->SetConfiguration(1);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+
+    rc = m_ctlEp->GetConfiguration(&cfg);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("config: %d\n", cfg);
+    TEST_ASSERT_EQUAL(cfg, 1);
+
+    int alt;
+    rc = m_ctlEp->GetInterface(1, &alt);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("alt: %d\n", alt);
+
+    rc = m_ctlEp->SetInterfaceAlternate(1, 1); // alt=1 packet size = 192
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+
+    rc = m_ctlEp->GetInterface(1, &alt);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("alt: %d\n", alt);
+    TEST_ASSERT_EQUAL(alt, 1);
+
+    for(int i = 0; i < 16; i++) {
+        report_cc_count[i] = 0;
+        report_ps_cc_count[i] = 0;
+    }
+  
+    LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
+    LPC_USB->HcControl |= OR_CONTROL_IE;  // IsochronousEnable
+}
+
+void LogitechC270::poll()
+{
+    HCITD* itd = m_isoEp->read();
+    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 LogitechC270::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 LogitechC270::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);
+}