BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

uvc/uvcini.cpp

Committer:
todotani
Date:
2013-02-20
Revision:
6:cf06ba884429
Parent:
0:1ed23ab1345f

File content as of revision 6:cf06ba884429:

#include "mbed.h"
#include "uvc.h"
#define __DEBUG
#include "mydbg.h"
#include "stcamcfg.h"

const struct stcamcfg stcamcfg_table[] = {
/*
{0x045e, 0x074a,
160,120,
PAYLOAD_MJPEG,
0x81, 128,
1, 5, 2000000, // 160x120 5.0fps
1, 1, "Microsoft LifeCam VX-700",
8, 3,
},*/
/*
{0x0c45, 0x62c0,
160,120,
PAYLOAD_MJPEG,
0x81, 128,
1, 5, 2000000, // 160x120 5.0fps
1, 1, "UVCA130AF",
8, 3,
},*/

{0x046d, 0x0994,
160,120,
PAYLOAD_MJPEG,
0, 0,
0, 0, 2000000, // 160x120 10.0fps
0, 0, "Logitech QuickCam Orbit AF",
0, 3,
},
{0x0000, 0x0000,
160,120,
PAYLOAD_MJPEG,
0x00, 0,
0, 0, 2000000,
0, 0, "default",
0, 3,
},
};

inline void LE32(uint32_t n, uint8_t* d)
{
    d[0] = (uint8_t)n;
    d[1] = (uint8_t)(n >> 8);
    d[2] = (uint8_t)(n >> 16);
    d[3] = (uint8_t)(n >> 24);
}

void uvc::SetFormatIndex(int index)
{
    DBG_ASSERT(index >= 1);
    DBG_ASSERT(index <= 2);
    m_FormatIndex = index;
}

void uvc::SetFrameIndex(int index)
{
    DBG_ASSERT(index >= 1);
    DBG_ASSERT(index <= 8);
    m_FrameIndex = index;
}

void uvc::SetFrameInterval(int val)
{
    DBG_ASSERT(val >= 333333);
    DBG_ASSERT(val <= 10000000);
    m_FrameInterval = val;
}

void uvc::SetPacketSize(int size)
{
    DBG_ASSERT(size >= 128);
    DBG_ASSERT(size <= 956);
    m_PacketSize = size;
}

void uvc::SetImageSize(int width, int height)
{
    DBG_ASSERT(width >= 160);
    DBG_ASSERT(width <= 800);
    DBG_ASSERT(height >= 120);
    DBG_ASSERT(height <= 600);
    m_width = width;
    m_height = height;
}

void uvc::SetPayload(int payload)
{
    DBG_ASSERT(payload == PAYLOAD_MJPEG || payload == PAYLOAD_YUY2);
    m_payload = payload;
}

void uvc::poll()
{
    isochronous();
}

int uvc::_init()
{
    m_init = true;
    UsbErr rc;
    for(int i = 0; i < 2; i++) {
        m_pDev = m_pHost->getDeviceByClass(CLASS_VIDEO, m_cam); // UVC
        if (m_pDev || i > 0) {
            break;
        }
        rc = Usb_poll();
        if (rc == USBERR_PROCESSING) {
            VERBOSE("%p USBERR_PROCESSING\n", this);
            return -1;
        }
    }
    DBG("m_pDev=%p\n", m_pDev);
    if (!m_pDev) {
        VERBOSE("%p UVC CAMERA(%d) NOT FOUND\n", this, m_cam);
        return -1;
    }
    DBG_ASSERT(m_pDev);
    
    struct stcamcfg cfg;
    for(int i = 0; ; i++) {
        cfg = stcamcfg_table[i];
        if (cfg.idVender == 0x0000) {
            DBG("not cam config\n");
            DBG("vid: %04X\n", m_pDev->getVid());
            DBG("pid: %04X\n", m_pDev->getPid());
            break;
        }
        if (cfg.idVender == m_pDev->getVid() && cfg.idProduct ==  m_pDev->getPid()) {
            DBG_ASSERT(cfg.name);
            DBG("found %s\n", cfg.name);
            break;
        }
    }

    if (m_width) {
        cfg.width = m_width;
    }
    if (m_height) {
        cfg.height = m_height;
    }
    if (m_payload != PAYLOAD_UNDEF) {
        cfg.payload = m_payload;
    }
    if (m_FormatIndex) {
        cfg.FormatIndex = m_FormatIndex;
    }
    if (m_FrameIndex) {
        cfg.FrameIndex = m_FrameIndex;
    }
    if (m_FrameInterval) {
        cfg.dwFrameInterval = m_FrameInterval;
    }
    if (m_PacketSize) {
        cfg.wMaxPacketSize = m_PacketSize;
    }

    _config(&cfg);

    if (cfg.payload == PAYLOAD_YUY2) {
        if (cfg.FormatIndex == 0) {
            VERBOSE("YUY2 FORMAT NOT FOUND\n");
            return -1;
        }
    }
    
    if (cfg.iso_FrameCount == 0) {
        int c = usb_bp_size() / cfg.wMaxPacketSize;
        if (c > 8) {
            c = 8;
        }
        cfg.iso_FrameCount = c; 
    }
    DBG_ASSERT(cfg.iso_FrameCount >= 1);
    DBG_ASSERT(cfg.iso_FrameCount <= 8);
    DBG_ASSERT((cfg.iso_FrameCount * cfg.wMaxPacketSize) <= usb_bp_size());
    if (cfg.iso_itdCount == 0) {
        cfg.iso_itdCount = 3;
    }
    DBG_ASSERT(cfg.iso_itdCount >= 1);
    DBG("cfg.wMaxPacketSize=%d\n", cfg.wMaxPacketSize);
    DBG("cfg.iso_FrameCount=%d\n", cfg.iso_FrameCount);
    DBG("cfg.iso_itdCount=%d\n", cfg.iso_itdCount);
    DBG_ASSERT(cfg.iso_FrameCount >= 1 && cfg.iso_FrameCount <= 8);
    //m_pEpIntIn = new UsbEndpoint(m_pDev, 0x83, true, USB_INT, 16);
    //DBG_ASSERT(m_pEpIntIn);
    
    DBG_ASSERT(cfg.bEndpointAddress == 0x81);
    DBG_ASSERT(cfg.wMaxPacketSize >= 128);
    DBG_ASSERT(cfg.wMaxPacketSize <= 956);
    m_PacketSize = cfg.wMaxPacketSize;
    DBG_ASSERT(m_PacketSize); 
    m_pEpIsoIn = new UsbEndpoint(m_pDev, cfg.bEndpointAddress, true, USB_ISO, m_PacketSize);
    DBG_ASSERT(m_pEpIsoIn);

    DBG_ASSERT(cfg.FormatIndex >= 1);
    DBG_ASSERT(cfg.FormatIndex <= 2);
    DBG_ASSERT(cfg.FrameIndex >= 1);
    DBG_ASSERT(cfg.FrameIndex <= 8);
    DBG_ASSERT(cfg.dwFrameInterval <= 10000000);
    DBG_ASSERT(cfg.dwFrameInterval >= 333333);

    uint8_t temp1[1];
    temp1[0] = 0x00;
    rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, temp1, sizeof(temp1));
    DBG_ASSERT(rc == USBERR_OK);
    DBG_BYTES("GET_INFO Probe ", temp1, sizeof(temp1));

    uint8_t temp[34];
    rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, temp, sizeof(temp));
    DBG_ASSERT(rc == USBERR_OK);
    DBG_BYTES("GET_CUR Probe ", temp, sizeof(temp));

    uint8_t param[34];
    memset(param, 0x00, sizeof(param));
    param[0] = 0x00;
    param[2] = cfg.FormatIndex;
    param[3] = cfg.FrameIndex; // 160x120
    LE32(cfg.dwFrameInterval, param+4); // Frame Interval

    DBG_BYTES("SET_CUR Probe ", param, sizeof(param));
    rc = Control(SET_CUR, VS_PROBE_CONTROL, 1, param, sizeof(param));
    DBG_ASSERT(rc == USBERR_OK);

    rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, temp, sizeof(temp));
    DBG_ASSERT(rc == USBERR_OK);
    DBG_BYTES("GET_CUR Probe ", temp, sizeof(temp));

    rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, temp, sizeof(temp));
    DBG_ASSERT(rc == USBERR_OK);
    DBG_BYTES("GET_CUR Commit", temp, sizeof(temp));

    DBG_BYTES("SET_CUR Commit", param, sizeof(param));
    rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, param, sizeof(param));
    DBG_ASSERT(rc == USBERR_OK);

    //USBH_SET_INTERFACE(1, 1); // alt=1 size=128
    DBG_ASSERT(cfg.bInterface >= 1); 
    DBG_ASSERT(cfg.bAlternate >= 1);
    DBG_ASSERT(cfg.bAlternate <= 6);
    //rc = m_pDev->controlSend(
    //              USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, 
    //              SET_INTERFACE, cfg.bAlternate, cfg.bInterface, NULL, 0);
    rc = m_pDev->SetInterfaceAlternate(cfg.bInterface, cfg.bAlternate);
    DBG_ASSERT(rc == USBERR_OK);

    DBG_ASSERT(cfg.iso_FrameCount >= 1);
    DBG_ASSERT(cfg.iso_FrameCount <= 8);
    m_FrameCount = cfg.iso_FrameCount;
    DBG_ASSERT(cfg.iso_itdCount >= 1);
    DBG_ASSERT(cfg.iso_itdCount <= 8);
    m_itdCount = cfg.iso_itdCount;
    
    LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
    LPC_USB->HcControl |= OR_CONTROL_IE;  // IsochronousEnable

    m_connect = true;
    return 0;
}