BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

LogitechC270/LogitechC270.cpp

Committer:
va009039
Date:
2012-12-04
Revision:
0:2a9734a95d55
Child:
1:80205a2de336

File content as of revision 0:2a9734a95d55:

// 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);
}