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
uvcini.cpp
00001 #include "mbed.h" 00002 #include "uvc.h" 00003 #define __DEBUG 00004 #include "mydbg.h" 00005 #include "stcamcfg.h" 00006 00007 #define UNDEF_VAL (0) 00008 const struct stcamcfg stcamcfg_table[] = { 00009 /* 00010 {0x045e, 0x074a, "Microsoft LifeCam VX-700", 00011 160,120, PAYLOAD_MJPEG, 00012 0x81, 128, 00013 1, 5, 2000000, // 160x120 5.0fps 00014 1, 1, 00015 8, 3, 00016 },*/ 00017 /* 00018 {0x0c45, 0x62c0, "UVCA130AF", 00019 160,120, PAYLOAD_MJPEG, 00020 0x81, 128, 00021 1, 5, 2000000, // 160x120 5.0fps 00022 1, 1, 00023 8, 3, 00024 },*/ 00025 00026 {0x046d, 0x0994, "Logitech QuickCam Orbit AF", 00027 160,120, PAYLOAD_MJPEG, 00028 UNDEF_VAL, UNDEF_VAL, 00029 UNDEF_VAL, UNDEF_VAL, 2000000, // 160x120 10.0fps 00030 UNDEF_VAL, UNDEF_VAL, 00031 UNDEF_VAL, 3, 00032 }, 00033 {0x0000, 0x0000, "default", 00034 160,120, PAYLOAD_MJPEG, 00035 UNDEF_VAL, UNDEF_VAL, 00036 UNDEF_VAL, UNDEF_VAL, 2000000, 00037 UNDEF_VAL, UNDEF_VAL, 00038 UNDEF_VAL, 3, 00039 }, 00040 }; 00041 00042 inline void LE32(uint32_t n, uint8_t* d) 00043 { 00044 d[0] = (uint8_t)n; 00045 d[1] = (uint8_t)(n >> 8); 00046 d[2] = (uint8_t)(n >> 16); 00047 d[3] = (uint8_t)(n >> 24); 00048 } 00049 00050 void uvc::SetFormatIndex(int index) 00051 { 00052 DBG_ASSERT(index >= 1); 00053 DBG_ASSERT(index <= 2); 00054 m_FormatIndex = index; 00055 } 00056 00057 void uvc::SetFrameIndex(int index) 00058 { 00059 DBG_ASSERT(index >= 1); 00060 DBG_ASSERT(index <= 8); 00061 m_FrameIndex = index; 00062 } 00063 00064 void uvc::SetFrameInterval(int val) 00065 { 00066 DBG_ASSERT(val >= 333333); 00067 DBG_ASSERT(val <= 10000000); 00068 m_FrameInterval = val; 00069 } 00070 00071 void uvc::SetPacketSize(int size) 00072 { 00073 DBG_ASSERT(size >= 128); 00074 DBG_ASSERT(size <= 1024); 00075 m_PacketSize = size; 00076 } 00077 00078 void uvc::SetImageSize(int width, int height) 00079 { 00080 DBG_ASSERT(width >= 160); 00081 DBG_ASSERT(width <= 800); 00082 DBG_ASSERT(height >= 120); 00083 DBG_ASSERT(height <= 600); 00084 m_width = width; 00085 m_height = height; 00086 } 00087 00088 void uvc::SetPayload(int payload) 00089 { 00090 DBG_ASSERT(payload == PAYLOAD_MJPEG || payload == PAYLOAD_YUY2); 00091 m_payload = payload; 00092 } 00093 00094 void uvc::poll() 00095 { 00096 isochronous(); 00097 } 00098 00099 int uvc::_init() 00100 { 00101 m_init = true; 00102 UsbErr rc; 00103 for(int i = 0; i < 2; i++) { 00104 m_pDev = m_pHost->getDeviceByClass(CLASS_VIDEO, m_cam); // UVC 00105 if (m_pDev || i > 0) { 00106 break; 00107 } 00108 rc = Usb_poll(); 00109 if (rc == USBERR_PROCESSING) { 00110 VERBOSE("%p USBERR_PROCESSING\n", this); 00111 return -1; 00112 } 00113 } 00114 DBG("m_pDev=%p\n", m_pDev); 00115 if (!m_pDev) { 00116 VERBOSE("%p UVC CAMERA(%d) NOT FOUND\n", this, m_cam); 00117 return -1; 00118 } 00119 DBG_ASSERT(m_pDev); 00120 00121 struct stcamcfg cfg; 00122 for(int i = 0; ; i++) { 00123 cfg = stcamcfg_table[i]; 00124 if (cfg.idVender == 0x0000) { 00125 DBG("not cam config\n"); 00126 DBG("vid: %04X\n", m_pDev->getVid()); 00127 DBG("pid: %04X\n", m_pDev->getPid()); 00128 break; 00129 } 00130 if (cfg.idVender == m_pDev->getVid() && cfg.idProduct == m_pDev->getPid()) { 00131 DBG_ASSERT(cfg.name); 00132 DBG("found %s\n", cfg.name); 00133 break; 00134 } 00135 } 00136 00137 if (m_width) { 00138 cfg.width = m_width; 00139 } 00140 if (m_height) { 00141 cfg.height = m_height; 00142 } 00143 if (m_payload != PAYLOAD_UNDEF) { 00144 cfg.payload = m_payload; 00145 } 00146 if (m_FormatIndex) { 00147 cfg.FormatIndex = m_FormatIndex; 00148 } 00149 if (m_FrameIndex) { 00150 cfg.FrameIndex = m_FrameIndex; 00151 } 00152 if (m_FrameInterval) { 00153 cfg.dwFrameInterval = m_FrameInterval; 00154 } 00155 if (m_PacketSize) { 00156 cfg.wMaxPacketSize = m_PacketSize; 00157 } 00158 00159 _config(&cfg); 00160 00161 if (cfg.FormatIndex == UNDEF_VAL) { 00162 if (cfg.payload == PAYLOAD_MJPEG) { 00163 VERBOSE("MJPG(Motion JPEG) FORMAT NOT FOUND\n"); 00164 } else if (cfg.payload == PAYLOAD_YUY2) { 00165 VERBOSE("YUY2 FORMAT NOT FOUND\n"); 00166 } else { 00167 VERBOSE("??? FORMAT NOT FOUND\n"); 00168 } 00169 return -1; 00170 } 00171 00172 if (cfg.bInterface == UNDEF_VAL) { 00173 VERBOSE("PacketSize(%d) CONFIG ERROR\n", cfg.wMaxPacketSize); 00174 return -1; 00175 } 00176 00177 if (cfg.iso_FrameCount == 0) { 00178 int c = usb_bp_size() / cfg.wMaxPacketSize; 00179 if (c > 8) { 00180 c = 8; 00181 } 00182 cfg.iso_FrameCount = c; 00183 } 00184 DBG_ASSERT(cfg.iso_FrameCount >= 1); 00185 DBG_ASSERT(cfg.iso_FrameCount <= 8); 00186 DBG_ASSERT((cfg.iso_FrameCount * cfg.wMaxPacketSize) <= usb_bp_size()); 00187 if (cfg.iso_itdCount == 0) { 00188 cfg.iso_itdCount = 3; 00189 } 00190 DBG_ASSERT(cfg.iso_itdCount >= 1); 00191 DBG("cfg.wMaxPacketSize=%d\n", cfg.wMaxPacketSize); 00192 DBG("cfg.iso_FrameCount=%d\n", cfg.iso_FrameCount); 00193 DBG("cfg.iso_itdCount=%d\n", cfg.iso_itdCount); 00194 DBG_ASSERT(cfg.iso_FrameCount >= 1 && cfg.iso_FrameCount <= 8); 00195 //m_pEpIntIn = new UsbEndpoint(m_pDev, 0x83, true, USB_INT, 16); 00196 //DBG_ASSERT(m_pEpIntIn); 00197 00198 DBG_ASSERT(cfg.bEndpointAddress & 0x80); 00199 DBG_ASSERT(cfg.wMaxPacketSize >= 128); 00200 DBG_ASSERT(cfg.wMaxPacketSize <= 1020); 00201 m_PacketSize = cfg.wMaxPacketSize; 00202 00203 DBG_ASSERT(m_PacketSize); 00204 m_pEpIsoIn = new UsbEndpoint(m_pDev, cfg.bEndpointAddress, true, USB_ISO, m_PacketSize); 00205 DBG_ASSERT(m_pEpIsoIn); 00206 00207 DBG_ASSERT(cfg.FormatIndex >= 1); 00208 DBG_ASSERT(cfg.FormatIndex <= 2); 00209 DBG_ASSERT(cfg.FrameIndex >= 1); 00210 DBG_ASSERT(cfg.FrameIndex <= 8); 00211 DBG_ASSERT(cfg.dwFrameInterval <= 10000000); 00212 DBG_ASSERT(cfg.dwFrameInterval >= 333333); 00213 00214 probe_commit_control(&cfg); 00215 00216 DBG("cfg.bInterface = %d, cfg.bAlternate = %d\n", cfg.bInterface, cfg.bAlternate); 00217 //USBH_SET_INTERFACE(1, 1); // alt=1 size=128 00218 DBG_ASSERT(cfg.bInterface >= 1); 00219 DBG_ASSERT(cfg.bAlternate >= 1); 00220 DBG_ASSERT(cfg.bAlternate <= 7); 00221 rc = m_pDev->SetInterfaceAlternate(cfg.bInterface, cfg.bAlternate); 00222 DBG_ASSERT(rc == USBERR_OK); 00223 00224 DBG_ASSERT(cfg.iso_FrameCount >= 1); 00225 DBG_ASSERT(cfg.iso_FrameCount <= 8); 00226 m_FrameCount = cfg.iso_FrameCount; 00227 00228 DBG_ASSERT(cfg.iso_itdCount >= 1); 00229 DBG_ASSERT(cfg.iso_itdCount <= 8); 00230 m_itdCount = cfg.iso_itdCount; 00231 00232 LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable 00233 LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable 00234 00235 m_connect = true; 00236 return 0; 00237 } 00238 00239 static void dump_param(uint8_t* buf) 00240 { 00241 VERBOSE("Hint: %04x\n", LE16(buf+0)); 00242 VERBOSE("FormatIndex: %d\n", buf[2]); 00243 VERBOSE("FrameIndex: %d\n", buf[3]); 00244 VERBOSE("FrameInterval: %d\n", LE32(buf+4)); 00245 VERBOSE("KeyFrameRate: %d\n", LE16(buf+8)); 00246 VERBOSE("PFrameRate: %d\n", LE16(buf+10)); 00247 VERBOSE("CompQuality: %d\n", LE16(buf+12)); 00248 VERBOSE("CompWindowSize: %d\n", LE16(buf+14)); 00249 VERBOSE("Delay: %d\n", LE16(buf+16)); 00250 VERBOSE("MaxVideoFrameSize: %d\n", LE32(buf+18)); 00251 VERBOSE("MaxPayloadTransferSize: %d\n", LE32(buf+22)); 00252 } 00253 00254 void uvc::probe_commit_control(struct stcamcfg* cfg) 00255 { 00256 DBG_ASSERT(cfg); 00257 uint8_t param[34]; 00258 uint8_t temp[34]; 00259 00260 int param_len = 34; 00261 DBG_ASSERT(cfg->bcdUVC >= 0x0100); 00262 if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0 00263 param_len = 26; 00264 } 00265 00266 UsbErr rc; 00267 rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, param, 1); 00268 DBG_ASSERT(rc == USBERR_OK); 00269 DBG_BYTES("GET_INFO Probe ", param, 1); 00270 00271 rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, temp, param_len); 00272 DBG_ASSERT(rc == USBERR_OK); 00273 DBG_BYTES("GET_DEF Probe ", temp, param_len); 00274 dump_param(temp); 00275 00276 rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, temp, param_len); 00277 DBG_ASSERT(rc == USBERR_OK); 00278 DBG_BYTES("GET_MIN Probe ", temp, param_len); 00279 dump_param(temp); 00280 00281 rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, temp, param_len); 00282 DBG_ASSERT(rc == USBERR_OK); 00283 DBG_BYTES("GET_MAX Probe ", temp, param_len); 00284 dump_param(temp); 00285 00286 rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, temp, param_len); 00287 DBG_ASSERT(rc == USBERR_OK); 00288 DBG_BYTES("GET_CUR Probe ", temp, param_len); 00289 dump_param(temp); 00290 00291 memset(param, 0x00, param_len); 00292 param[2] = cfg->FormatIndex; 00293 param[3] = cfg->FrameIndex; // 160x120 00294 LE32(cfg->dwFrameInterval, param+4); // Frame Interval 00295 00296 DBG_BYTES("SET_CUR Probe ", param, param_len); 00297 rc = Control(SET_CUR, VS_PROBE_CONTROL, 1, param, param_len); 00298 DBG_ASSERT(rc == USBERR_OK); 00299 00300 rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, temp, param_len); 00301 DBG_ASSERT(rc == USBERR_OK); 00302 DBG_BYTES("GET_CUR Probe ", temp, param_len); 00303 00304 rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, temp, param_len); 00305 DBG_ASSERT(rc == USBERR_OK); 00306 DBG_BYTES("GET_INFO Commit", temp, 1); 00307 00308 rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, temp, param_len); 00309 DBG_ASSERT(rc == USBERR_OK); 00310 DBG_BYTES("GET_CUR Commit", temp, param_len); 00311 dump_param(temp); 00312 00313 DBG_BYTES("SET_CUR Commit", param, param_len); 00314 dump_param(param); 00315 rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, param, param_len); 00316 if (rc != USBERR_OK) { 00317 VERBOSE("Error SET_CUR VS_COMMIT_CONTROL\n"); 00318 } 00319 DBG_ASSERT(rc == USBERR_OK); 00320 00321 rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, temp, param_len); 00322 DBG_ASSERT(rc == USBERR_OK); 00323 DBG_BYTES("GET_CUR Commit", temp, param_len); 00324 dump_param(temp); 00325 }
Generated on Wed Jul 13 2022 01:34:55 by
1.7.2
