Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of uvchost by
uvc/uvcini.cpp
- Committer:
- va009039
- Date:
- 2012-07-31
- Revision:
- 0:b0f04c137829
- Child:
- 2:812d604caad4
File content as of revision 0:b0f04c137829:
#include "mbed.h" #include "uvc.h" #define __DEBUG #include "mydbg.h" #include "stcamcfg.h" #define UNDEF_VAL (0) const struct stcamcfg stcamcfg_table[] = { /* {0x045e, 0x074a, "Microsoft LifeCam VX-700", 160,120, PAYLOAD_MJPEG, 0x81, 128, 1, 5, 2000000, // 160x120 5.0fps 1, 1, 8, 3, },*/ /* {0x0c45, 0x62c0, "UVCA130AF", 160,120, PAYLOAD_MJPEG, 0x81, 128, 1, 5, 2000000, // 160x120 5.0fps 1, 1, 8, 3, },*/ {0x046d, 0x0994, "Logitech QuickCam Orbit AF", 160,120, PAYLOAD_MJPEG, UNDEF_VAL, UNDEF_VAL, UNDEF_VAL, UNDEF_VAL, 2000000, // 160x120 10.0fps UNDEF_VAL, UNDEF_VAL, UNDEF_VAL, 3, }, {0x0000, 0x0000, "default", 160,120, PAYLOAD_MJPEG, UNDEF_VAL, UNDEF_VAL, UNDEF_VAL, UNDEF_VAL, 2000000, UNDEF_VAL, UNDEF_VAL, UNDEF_VAL, 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 <= 1024); 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.FormatIndex == UNDEF_VAL) { if (cfg.payload == PAYLOAD_MJPEG) { VERBOSE("MJPG(Motion JPEG) FORMAT NOT FOUND\n"); } else if (cfg.payload == PAYLOAD_YUY2) { VERBOSE("YUY2 FORMAT NOT FOUND\n"); } else { VERBOSE("??? FORMAT NOT FOUND\n"); } return -1; } if (cfg.bInterface == UNDEF_VAL) { VERBOSE("PacketSize(%d) CONFIG ERROR\n", cfg.wMaxPacketSize); 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 & 0x80); DBG_ASSERT(cfg.wMaxPacketSize >= 128); DBG_ASSERT(cfg.wMaxPacketSize <= 1020); 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); probe_commit_control(&cfg); DBG("cfg.bInterface = %d, cfg.bAlternate = %d\n", cfg.bInterface, cfg.bAlternate); //USBH_SET_INTERFACE(1, 1); // alt=1 size=128 DBG_ASSERT(cfg.bInterface >= 1); DBG_ASSERT(cfg.bAlternate >= 1); DBG_ASSERT(cfg.bAlternate <= 7); 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; } static void dump_param(uint8_t* buf) { VERBOSE("Hint: %04x\n", LE16(buf+0)); VERBOSE("FormatIndex: %d\n", buf[2]); VERBOSE("FrameIndex: %d\n", buf[3]); VERBOSE("FrameInterval: %d\n", LE32(buf+4)); VERBOSE("KeyFrameRate: %d\n", LE16(buf+8)); VERBOSE("PFrameRate: %d\n", LE16(buf+10)); VERBOSE("CompQuality: %d\n", LE16(buf+12)); VERBOSE("CompWindowSize: %d\n", LE16(buf+14)); VERBOSE("Delay: %d\n", LE16(buf+16)); VERBOSE("MaxVideoFrameSize: %d\n", LE32(buf+18)); VERBOSE("MaxPayloadTransferSize: %d\n", LE32(buf+22)); } void uvc::probe_commit_control(struct stcamcfg* cfg) { DBG_ASSERT(cfg); uint8_t param[34]; uint8_t temp[34]; int param_len = 34; DBG_ASSERT(cfg->bcdUVC >= 0x0100); if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0 param_len = 26; } UsbErr rc; rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, param, 1); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_INFO Probe ", param, 1); rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_DEF Probe ", temp, param_len); dump_param(temp); rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_MIN Probe ", temp, param_len); dump_param(temp); rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_MAX Probe ", temp, param_len); dump_param(temp); rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_CUR Probe ", temp, param_len); dump_param(temp); memset(param, 0x00, param_len); param[2] = cfg->FormatIndex; param[3] = cfg->FrameIndex; // 160x120 LE32(cfg->dwFrameInterval, param+4); // Frame Interval DBG_BYTES("SET_CUR Probe ", param, param_len); rc = Control(SET_CUR, VS_PROBE_CONTROL, 1, param, param_len); DBG_ASSERT(rc == USBERR_OK); rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_CUR Probe ", temp, param_len); rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_INFO Commit", temp, 1); rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_CUR Commit", temp, param_len); dump_param(temp); DBG_BYTES("SET_CUR Commit", param, param_len); dump_param(param); rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, param, param_len); if (rc != USBERR_OK) { VERBOSE("Error SET_CUR VS_COMMIT_CONTROL\n"); } DBG_ASSERT(rc == USBERR_OK); rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, temp, param_len); DBG_ASSERT(rc == USBERR_OK); DBG_BYTES("GET_CUR Commit", temp, param_len); dump_param(temp); }