BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Committer:
va009039
Date:
Fri Jan 25 14:55:08 2013 +0000
Revision:
5:495f7536897b
Parent:
2:c10029b87439
update library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 5:495f7536897b 1 // UvcCam.cpp 2013/1/25
va009039 2:c10029b87439 2 #include "mbed.h"
va009039 2:c10029b87439 3 #include "rtos.h"
va009039 2:c10029b87439 4 #include "BaseUsbHost.h"
va009039 5:495f7536897b 5 //#define DEBUG
va009039 2:c10029b87439 6 #include "BaseUsbHostDebug.h"
va009039 2:c10029b87439 7 #define TEST
va009039 2:c10029b87439 8 #include "BaseUsbHostTest.h"
va009039 2:c10029b87439 9 #include "UvcCam.h"
va009039 2:c10029b87439 10
va009039 2:c10029b87439 11 UvcCam::UvcCam(int formatIndex, int frameIndex, uint32_t interval, ControlEp* ctlEp)
va009039 2:c10029b87439 12 {
va009039 2:c10029b87439 13 uint8_t buf[34];
va009039 2:c10029b87439 14 int rc;
va009039 2:c10029b87439 15 int alt;
va009039 2:c10029b87439 16 int cfg2;
va009039 2:c10029b87439 17
va009039 2:c10029b87439 18 if (ctlEp == NULL) { // root hub
va009039 2:c10029b87439 19 DBG_OHCI(LPC_USB->HcRhPortStatus1);
va009039 2:c10029b87439 20 TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
va009039 2:c10029b87439 21 ctlEp = new ControlEp();
va009039 2:c10029b87439 22 TEST_ASSERT_TRUE(ctlEp);
va009039 2:c10029b87439 23 }
va009039 2:c10029b87439 24 bool r = check(ctlEp);
va009039 2:c10029b87439 25 TEST_ASSERT(r);
va009039 2:c10029b87439 26 m_ctlEp = ctlEp;
va009039 2:c10029b87439 27
va009039 2:c10029b87439 28 UvcCfg* cfg = new UvcCfg(formatIndex, frameIndex, ctlEp);
va009039 2:c10029b87439 29 TEST_ASSERT(cfg);
va009039 2:c10029b87439 30
va009039 2:c10029b87439 31 int param_len = 34;
va009039 2:c10029b87439 32 TEST_ASSERT(cfg->bcdUVC >= 0x0100);
va009039 2:c10029b87439 33 if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0
va009039 2:c10029b87439 34 param_len = 26;
va009039 2:c10029b87439 35 }
va009039 2:c10029b87439 36
va009039 2:c10029b87439 37 int addr = m_ctlEp->GetAddr();
va009039 2:c10029b87439 38 m_isoEp = new IsochronousEp(addr, cfg->bEndpointAddress, cfg->wMaxPacketSize);
va009039 2:c10029b87439 39 TEST_ASSERT_TRUE(m_isoEp);
va009039 2:c10029b87439 40
va009039 2:c10029b87439 41 //#define USE_PROBE
va009039 2:c10029b87439 42
va009039 2:c10029b87439 43 #ifdef USE_PROBE
va009039 2:c10029b87439 44 rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1);
va009039 2:c10029b87439 45 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 46 DBG_BYTES("GET_INFO Prob", buf, 1);
va009039 2:c10029b87439 47
va009039 2:c10029b87439 48 rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 2:c10029b87439 49 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 50 DBG_BYTES("GET_DEF Probe", buf, param_len);
va009039 2:c10029b87439 51
va009039 2:c10029b87439 52 rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 2:c10029b87439 53 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 54 DBG_BYTES("GET_MIN Probe", buf, param_len);
va009039 2:c10029b87439 55
va009039 2:c10029b87439 56 rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 2:c10029b87439 57 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 58 DBG_BYTES("GET_MAX Probe", buf, param_len);
va009039 2:c10029b87439 59
va009039 2:c10029b87439 60 rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 2:c10029b87439 61 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 62 DBG_BYTES("GET_CUR Probe", buf, param_len);
va009039 2:c10029b87439 63 #endif // USE_PROBE
va009039 2:c10029b87439 64
va009039 2:c10029b87439 65 rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, buf, 1);
va009039 2:c10029b87439 66 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 67 DBG_BYTES("GET_INFO Commit", buf, 1);
va009039 2:c10029b87439 68
va009039 2:c10029b87439 69 memset(buf, 0, param_len);
va009039 2:c10029b87439 70 buf[2] = cfg->FormatIndex;
va009039 2:c10029b87439 71 buf[3] = cfg->FrameIndex;
va009039 2:c10029b87439 72 *reinterpret_cast<uint32_t*>(buf+4) = interval;
va009039 2:c10029b87439 73
va009039 2:c10029b87439 74 DBG_BYTES("SET_CUR Commit", buf, param_len);
va009039 2:c10029b87439 75 rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
va009039 2:c10029b87439 76 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 77
va009039 2:c10029b87439 78 rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
va009039 2:c10029b87439 79 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 80 TEST_ASSERT_EQUAL(buf[2], cfg->FormatIndex);
va009039 2:c10029b87439 81 TEST_ASSERT_EQUAL(buf[3], cfg->FrameIndex);
va009039 2:c10029b87439 82 TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval);
va009039 2:c10029b87439 83 DBG_BYTES("GET_CUR Commit", buf, param_len);
va009039 2:c10029b87439 84
va009039 2:c10029b87439 85 rc = m_ctlEp->GetConfiguration(&cfg2);
va009039 2:c10029b87439 86 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 2:c10029b87439 87 DBG("config: %d\n", cfg2);
va009039 2:c10029b87439 88
va009039 2:c10029b87439 89 rc = m_ctlEp->SetConfiguration(1);
va009039 2:c10029b87439 90 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 2:c10029b87439 91
va009039 2:c10029b87439 92 rc = m_ctlEp->GetConfiguration(&cfg2);
va009039 2:c10029b87439 93 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 2:c10029b87439 94 DBG("config: %d\n", cfg2);
va009039 2:c10029b87439 95 TEST_ASSERT_EQUAL(cfg2, 1);
va009039 2:c10029b87439 96
va009039 2:c10029b87439 97 rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
va009039 2:c10029b87439 98 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 2:c10029b87439 99 DBG("alt: %d\n", alt);
va009039 2:c10029b87439 100
va009039 2:c10029b87439 101 rc = m_ctlEp->SetInterfaceAlternate(cfg->bInterface, cfg->bAlternate);
va009039 2:c10029b87439 102 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 2:c10029b87439 103
va009039 2:c10029b87439 104 rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
va009039 2:c10029b87439 105 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 2:c10029b87439 106 DBG("alt: %d\n", alt);
va009039 2:c10029b87439 107 TEST_ASSERT_EQUAL(alt, cfg->bAlternate);
va009039 2:c10029b87439 108 delete cfg;
va009039 2:c10029b87439 109
va009039 2:c10029b87439 110 for(int i = 0; i < 16; i++) {
va009039 2:c10029b87439 111 report_cc_count[i] = 0;
va009039 2:c10029b87439 112 report_ps_cc_count[i] = 0;
va009039 2:c10029b87439 113 }
va009039 2:c10029b87439 114
va009039 2:c10029b87439 115 LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
va009039 2:c10029b87439 116 LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable
va009039 2:c10029b87439 117 }
va009039 2:c10029b87439 118
va009039 2:c10029b87439 119 bool UvcCam::check(ControlEp* ctlEp)
va009039 2:c10029b87439 120 {
va009039 2:c10029b87439 121 if (ctlEp == NULL) {
va009039 2:c10029b87439 122 return false;
va009039 2:c10029b87439 123 }
va009039 2:c10029b87439 124 uint8_t buf[18];
va009039 2:c10029b87439 125 int r = ctlEp->GetDescriptor(1, 0, buf, 8);
va009039 2:c10029b87439 126 if (r != USB_OK) {
va009039 2:c10029b87439 127 return false;
va009039 2:c10029b87439 128 }
va009039 2:c10029b87439 129 DBG_HEX(buf, 8);
va009039 2:c10029b87439 130 const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01};
va009039 2:c10029b87439 131 if (memcmp(buf, desc, sizeof(desc)) != 0) {
va009039 2:c10029b87439 132 return false;
va009039 2:c10029b87439 133 }
va009039 2:c10029b87439 134 r = ctlEp->GetDescriptor(1, 0, buf, 18);
va009039 2:c10029b87439 135 if (r != USB_OK) {
va009039 2:c10029b87439 136 return false;
va009039 2:c10029b87439 137 }
va009039 2:c10029b87439 138 DBG_HEX(buf, 18);
va009039 2:c10029b87439 139 return true;
va009039 2:c10029b87439 140 }
va009039 2:c10029b87439 141
va009039 2:c10029b87439 142 #define DESCRIPTOR_TYPE_DEVICE 1
va009039 2:c10029b87439 143 #define DESCRIPTOR_TYPE_CONFIGURATION 2
va009039 2:c10029b87439 144 #define DESCRIPTOR_TYPE_STRING 3
va009039 2:c10029b87439 145 #define DESCRIPTOR_TYPE_INTERFACE 4
va009039 2:c10029b87439 146 #define DESCRIPTOR_TYPE_ENDPOINT 5
va009039 2:c10029b87439 147
va009039 2:c10029b87439 148 #define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0b
va009039 2:c10029b87439 149
va009039 2:c10029b87439 150 #define DESCRIPTOR_TYPE_HID 0x21
va009039 2:c10029b87439 151 #define DESCRIPTOR_TYPE_REPORT 0x22
va009039 2:c10029b87439 152 #define DESCRIPTOR_TYPE_PHYSICAL 0x23
va009039 2:c10029b87439 153 #define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
va009039 2:c10029b87439 154 #define DESCRIPTOR_TYPE_CS_ENDPOINT 0x25
va009039 2:c10029b87439 155 #define DESCRIPTOR_TYPE_HUB 0x29
va009039 2:c10029b87439 156
va009039 2:c10029b87439 157 #define CLASS_AUDIO 0x02
va009039 2:c10029b87439 158 #define CLASS_HUB 0x09
va009039 2:c10029b87439 159
va009039 2:c10029b87439 160 #define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A);
va009039 2:c10029b87439 161 #define ENDIF }
va009039 2:c10029b87439 162
va009039 2:c10029b87439 163 #define CC_AUDIO 0x01
va009039 2:c10029b87439 164 #define SC_AUDIOCONTROL 0x01
va009039 2:c10029b87439 165 #define SC_AUDIOSTREAMING 0x02
va009039 2:c10029b87439 166
va009039 2:c10029b87439 167 #define AC_HEADER 0x01
va009039 2:c10029b87439 168 #define AC_INPUT_TERMINAL 0x02
va009039 2:c10029b87439 169 #define AC_OUTPUT_TERMINAL 0x03
va009039 2:c10029b87439 170 #define AC_FEATURE_UNIT 0x06
va009039 2:c10029b87439 171
va009039 2:c10029b87439 172 // Input Terminal Types
va009039 2:c10029b87439 173 #define ITT_CAMERA 0x0201
va009039 2:c10029b87439 174
va009039 2:c10029b87439 175 static int LE16(const uint8_t* d)
va009039 2:c10029b87439 176 {
va009039 2:c10029b87439 177 return d[0] | (d[1] << 8);
va009039 2:c10029b87439 178 }
va009039 2:c10029b87439 179
va009039 2:c10029b87439 180 static int LE24(const uint8_t* d) {
va009039 2:c10029b87439 181 return d[0] | (d[1]<<8) | (d[2] << 16);
va009039 2:c10029b87439 182 }
va009039 2:c10029b87439 183
va009039 2:c10029b87439 184 static int LE32(const uint8_t* d) {
va009039 2:c10029b87439 185 return d[0] |(d[1]<<8) | (d[2] << 16) |(d[3] << 24) ;
va009039 2:c10029b87439 186 }
va009039 2:c10029b87439 187
va009039 2:c10029b87439 188 UvcCfg::UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp):wMaxPacketSize(0)
va009039 2:c10029b87439 189 {
va009039 2:c10029b87439 190 TEST_ASSERT(ctlEp);
va009039 2:c10029b87439 191 switch(formatIndex) {
va009039 2:c10029b87439 192 case UVC_MJPEG: _payload = UVC_MJPEG; break;
va009039 2:c10029b87439 193 case UVC_YUY2: _payload = UVC_YUY2; break;
va009039 2:c10029b87439 194 default: _payload = UVC_MJPEG; break;
va009039 2:c10029b87439 195 }
va009039 2:c10029b87439 196
va009039 2:c10029b87439 197 switch(frameIndex) {
va009039 2:c10029b87439 198 case UVC_160x120: _width = 160; _height = 120; break;
va009039 2:c10029b87439 199 case UVC_176x144: _width = 176; _height = 144; break;
va009039 2:c10029b87439 200 case UVC_320x176: _width = 320; _height = 176; break;
va009039 2:c10029b87439 201 case UVC_320x240: _width = 320; _height = 240; break;
va009039 2:c10029b87439 202 case UVC_352x288: _width = 352; _height = 288; break;
va009039 2:c10029b87439 203 case UVC_432x240: _width = 432; _height = 240; break;
va009039 2:c10029b87439 204 case UVC_640x480: _width = 640; _height = 480; break;
va009039 2:c10029b87439 205 case UVC_544x288: _width = 544; _height = 288; break;
va009039 2:c10029b87439 206 case UVC_640x360: _width = 640; _height = 360; break;
va009039 2:c10029b87439 207 case UVC_752x416: _width = 752; _height = 416; break;
va009039 2:c10029b87439 208 case UVC_800x448: _width = 800; _height = 448; break;
va009039 2:c10029b87439 209 case UVC_800x600: _width = 800; _height = 600; break;
va009039 2:c10029b87439 210 default: _width = 160; _height = 120; break;
va009039 2:c10029b87439 211 }
va009039 2:c10029b87439 212 int index = 0;
va009039 2:c10029b87439 213 uint8_t temp[4];
va009039 2:c10029b87439 214 int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp));
va009039 2:c10029b87439 215 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 216 DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp));
va009039 2:c10029b87439 217 TEST_ASSERT(temp[0] == 9);
va009039 2:c10029b87439 218 TEST_ASSERT(temp[1] == 0x02);
va009039 2:c10029b87439 219 int TotalLength = LE16(temp+2);
va009039 2:c10029b87439 220 DBG("TotalLength: %d\n", TotalLength);
va009039 2:c10029b87439 221
va009039 2:c10029b87439 222 uint8_t* buf = new uint8_t[TotalLength];
va009039 2:c10029b87439 223 TEST_ASSERT(buf);
va009039 2:c10029b87439 224 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, TotalLength);
va009039 2:c10029b87439 225 TEST_ASSERT(rc == USB_OK);
va009039 2:c10029b87439 226 if (rc != USB_OK) {
va009039 2:c10029b87439 227 delete[] buf;
va009039 2:c10029b87439 228 return;
va009039 2:c10029b87439 229 }
va009039 2:c10029b87439 230 _parserConfigurationDescriptor(buf, TotalLength);
va009039 2:c10029b87439 231 delete[] buf;
va009039 2:c10029b87439 232 }
va009039 2:c10029b87439 233
va009039 2:c10029b87439 234 void UvcCfg::_parserAudioControl(uint8_t* buf, int len) {
va009039 2:c10029b87439 235 int subtype = buf[2];
va009039 2:c10029b87439 236 IF_EQ_THEN_PRINTF(AC_HEADER, subtype)
va009039 2:c10029b87439 237 VERBOSE("ADC: %04x\n", LE16(buf+3));
va009039 2:c10029b87439 238 VERBOSE("TotalLength: %d\n", LE16(buf+5));
va009039 2:c10029b87439 239 VERBOSE("InCollection: %d\n", buf[7]);
va009039 2:c10029b87439 240 for (int n = 1; n <= buf[7]; n++) {
va009039 2:c10029b87439 241 VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]);
va009039 2:c10029b87439 242 }
va009039 2:c10029b87439 243 ENDIF
va009039 2:c10029b87439 244 IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype)
va009039 2:c10029b87439 245 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 2:c10029b87439 246 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 2:c10029b87439 247 VERBOSE("AssocTermianl: %d\n", buf[6]);
va009039 2:c10029b87439 248 VERBOSE("NrChannels: %d\n", buf[7]);
va009039 2:c10029b87439 249 ENDIF
va009039 2:c10029b87439 250 IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype)
va009039 2:c10029b87439 251 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 2:c10029b87439 252 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 2:c10029b87439 253 VERBOSE("AssocTermianl: %d\n", buf[6]);
va009039 2:c10029b87439 254 ENDIF
va009039 2:c10029b87439 255 IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype)
va009039 2:c10029b87439 256 VERBOSE("UnitID: %d\n", buf[3]);
va009039 2:c10029b87439 257 VERBOSE("SourceID: %d\n", buf[4]);
va009039 2:c10029b87439 258 VERBOSE("ControlSize: %d\n", buf[5]);
va009039 2:c10029b87439 259 ENDIF
va009039 2:c10029b87439 260 }
va009039 2:c10029b87439 261
va009039 2:c10029b87439 262 #define AS_GENERAL 0x01
va009039 2:c10029b87439 263 #define AS_FORMAT_TYPE 0x02
va009039 2:c10029b87439 264
va009039 2:c10029b87439 265 void UvcCfg::_parserAudioStream(uint8_t* buf, int len) {
va009039 2:c10029b87439 266 int subtype = buf[2];
va009039 2:c10029b87439 267 IF_EQ_THEN_PRINTF(AS_GENERAL, subtype)
va009039 2:c10029b87439 268 VERBOSE("TerminalLink: %d\n", buf[3]);
va009039 2:c10029b87439 269 VERBOSE("Delay: %d\n", buf[4]);
va009039 2:c10029b87439 270 VERBOSE("FormatTag: %04x\n", LE16(buf+5));
va009039 2:c10029b87439 271 ENDIF
va009039 2:c10029b87439 272 IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype)
va009039 2:c10029b87439 273 VERBOSE("FormatType: %d\n", buf[3]);
va009039 2:c10029b87439 274 VERBOSE("NrChannels: %d\n", buf[4]);
va009039 2:c10029b87439 275 VERBOSE("SubFrameSize: %d\n", buf[5]);
va009039 2:c10029b87439 276 VERBOSE("BitResolution: %d\n", buf[6]);
va009039 2:c10029b87439 277 VERBOSE("SamFreqType: %d\n", buf[7]);
va009039 2:c10029b87439 278 VERBOSE("SamFreq(1): %d\n", LE24(buf+8));
va009039 2:c10029b87439 279 ENDIF
va009039 2:c10029b87439 280 }
va009039 2:c10029b87439 281
va009039 2:c10029b87439 282 #define CC_VIDEO 0x0e
va009039 2:c10029b87439 283
va009039 2:c10029b87439 284 #define SC_VIDEOCONTROL 0x01
va009039 2:c10029b87439 285 #define SC_VIDEOSTREAMING 0x02
va009039 2:c10029b87439 286
va009039 2:c10029b87439 287 #define VC_HEADER 0x01
va009039 2:c10029b87439 288 #define VC_INPUT_TERMINAL 0x02
va009039 2:c10029b87439 289 #define VC_OUTPUT_TERMINAL 0x03
va009039 2:c10029b87439 290 #define VC_SELECTOR_UNIT 0x04
va009039 2:c10029b87439 291 #define VC_PROCESSING_UNIT 0x05
va009039 2:c10029b87439 292 #define VC_EXTENSION_UNIT 0x06
va009039 2:c10029b87439 293
va009039 2:c10029b87439 294 void UvcCfg::_parserVideoControl(uint8_t* buf, int len) {
va009039 2:c10029b87439 295 int subtype = buf[2];
va009039 2:c10029b87439 296 IF_EQ_THEN_PRINTF(VC_HEADER, subtype)
va009039 2:c10029b87439 297 bcdUVC = LE16(buf+3);
va009039 2:c10029b87439 298 VERBOSE("UVC: %04x\n", bcdUVC);
va009039 2:c10029b87439 299 VERBOSE("TotalLength: %d\n", LE16(buf+5));
va009039 2:c10029b87439 300 VERBOSE("ClockFrequency: %d\n", LE32(buf+7));
va009039 2:c10029b87439 301 VERBOSE("InCollection: %d\n", buf[11]);
va009039 2:c10029b87439 302 VERBOSE("aInterfaceNr(1): %d\n", buf[12]);
va009039 2:c10029b87439 303 ENDIF
va009039 2:c10029b87439 304 IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype)
va009039 2:c10029b87439 305 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 2:c10029b87439 306 uint16_t tt = LE16(buf+4);
va009039 2:c10029b87439 307 VERBOSE("TerminalType: %04X\n", tt);
va009039 2:c10029b87439 308 VERBOSE("AssocTerminal: %d\n", buf[6]);
va009039 2:c10029b87439 309 VERBOSE("Terminal: %d\n", buf[7]);
va009039 2:c10029b87439 310 if (tt == ITT_CAMERA) { // camera
va009039 2:c10029b87439 311 int bControlSize = buf[14];
va009039 2:c10029b87439 312 VERBOSE("ControlSize: %d\n", bControlSize);
va009039 2:c10029b87439 313 for(int i = 0; i < bControlSize; i++) {
va009039 2:c10029b87439 314 uint8_t bControls = buf[15+i];
va009039 2:c10029b87439 315 VERBOSE("Controls(%d): %02X\n", i, bControls);
va009039 2:c10029b87439 316 }
va009039 2:c10029b87439 317 }
va009039 2:c10029b87439 318 ENDIF
va009039 2:c10029b87439 319 IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype)
va009039 2:c10029b87439 320 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 2:c10029b87439 321 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 2:c10029b87439 322 VERBOSE("AssocTerminal: %d\n", buf[6]);
va009039 2:c10029b87439 323 VERBOSE("SourceID: %d\n", buf[7]);
va009039 2:c10029b87439 324 VERBOSE("Terminal: %d\n", buf[8]);
va009039 2:c10029b87439 325 ENDIF
va009039 2:c10029b87439 326 IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype)
va009039 2:c10029b87439 327 VERBOSE("UnitID: %d\n", buf[3]);
va009039 2:c10029b87439 328 ENDIF
va009039 2:c10029b87439 329 IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype)
va009039 2:c10029b87439 330 VERBOSE("UnitID: %d\n", buf[3]);
va009039 2:c10029b87439 331 VERBOSE("SourceID: %d\n", buf[4]);
va009039 2:c10029b87439 332 VERBOSE("MaxMultiplier: %d\n", LE16(buf+5));
va009039 2:c10029b87439 333 VERBOSE("ControlSize: %d\n", buf[7]);
va009039 2:c10029b87439 334 int pos = 8;
va009039 2:c10029b87439 335 for (int n = 1; n <= buf[7]; n++) {
va009039 2:c10029b87439 336 VERBOSE("Controls(%d): %02X\n", n , buf[pos]);
va009039 2:c10029b87439 337 pos++;
va009039 2:c10029b87439 338 }
va009039 2:c10029b87439 339 VERBOSE("Processing: %d\n", buf[pos]);
va009039 2:c10029b87439 340 pos++;
va009039 2:c10029b87439 341 VERBOSE("VideoStanders: %02X\n", buf[pos]);
va009039 2:c10029b87439 342 ENDIF
va009039 2:c10029b87439 343 IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype)
va009039 2:c10029b87439 344 VERBOSE("UnitID: %d\n", buf[3]);
va009039 2:c10029b87439 345 ENDIF
va009039 2:c10029b87439 346 }
va009039 2:c10029b87439 347
va009039 2:c10029b87439 348 #define VS_INPUT_HEADER 0x01
va009039 2:c10029b87439 349 #define VS_STILL_FRAME 0x03
va009039 2:c10029b87439 350 #define VS_FORMAT_UNCOMPRESSED 0x04
va009039 2:c10029b87439 351 #define VS_FRAME_UNCOMPRESSED 0x05
va009039 2:c10029b87439 352 #define VS_FORMAT_MJPEG 0x06
va009039 2:c10029b87439 353 #define VS_FRAME_MJPEG 0x07
va009039 2:c10029b87439 354 #define VS_COLOR_FORMAT 0x0d
va009039 2:c10029b87439 355
va009039 2:c10029b87439 356 void UvcCfg::_parserVideoStream(uint8_t* buf, int len) {
va009039 2:c10029b87439 357 int subtype = buf[2];
va009039 2:c10029b87439 358 IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype)
va009039 2:c10029b87439 359 VERBOSE("NumFormats: %d\n", buf[3]);
va009039 2:c10029b87439 360 VERBOSE("TotalLength: %d\n", LE16(buf+4));
va009039 2:c10029b87439 361 VERBOSE("EndpointAddress: %02X\n", buf[6]);
va009039 2:c10029b87439 362 VERBOSE("Info: %02X\n", buf[7]);
va009039 2:c10029b87439 363 VERBOSE("TerminalLink: %d\n", buf[8]);
va009039 2:c10029b87439 364 VERBOSE("StillCaptureMethod: %d\n", buf[9]);
va009039 2:c10029b87439 365 VERBOSE("TriggerSupport: %d\n", buf[10]);
va009039 2:c10029b87439 366 VERBOSE("TriggerUsage: %d\n", buf[11]);
va009039 2:c10029b87439 367 VERBOSE("ControlSize: %d\n", buf[12]);
va009039 2:c10029b87439 368 int pos = 13;
va009039 2:c10029b87439 369 for (int n = 1; n <= buf[12]; n++) {
va009039 2:c10029b87439 370 VERBOSE("Controls(%d): %02X\n", n, buf[pos]);
va009039 2:c10029b87439 371 pos++;
va009039 2:c10029b87439 372 }
va009039 2:c10029b87439 373 bEndpointAddress = buf[6];
va009039 2:c10029b87439 374 ENDIF
va009039 2:c10029b87439 375 IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype)
va009039 2:c10029b87439 376 VERBOSE("EndpointAdress: %02X\n", buf[3]);
va009039 2:c10029b87439 377 VERBOSE("NumImageSizePatterns: %d\n", buf[4]);
va009039 2:c10029b87439 378 int ptn = buf[4];
va009039 2:c10029b87439 379 int pos = 5;
va009039 2:c10029b87439 380 for (int n = 1; n <= ptn; n++) {
va009039 2:c10029b87439 381 VERBOSE("Width(%d): %d\n", n, LE16(buf+pos));
va009039 2:c10029b87439 382 VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2));
va009039 2:c10029b87439 383 pos += 4;
va009039 2:c10029b87439 384 }
va009039 2:c10029b87439 385 VERBOSE("NumCompressPtn: %d\n", buf[pos]);
va009039 2:c10029b87439 386 ptn = buf[pos++];
va009039 2:c10029b87439 387 for (int n = 1; n <= ptn; n++) {
va009039 2:c10029b87439 388 VERBOSE("Compress(%d): %d\n", n, buf[pos]);
va009039 2:c10029b87439 389 pos++;
va009039 2:c10029b87439 390 }
va009039 2:c10029b87439 391 ENDIF
va009039 2:c10029b87439 392 IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype)
va009039 2:c10029b87439 393 VERBOSE("FormatIndex: %d\n", buf[3]);
va009039 2:c10029b87439 394 VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
va009039 2:c10029b87439 395 uint32_t guid = LE32(buf+5);
va009039 2:c10029b87439 396 if (guid == 0x32595559) {
va009039 2:c10029b87439 397 VERBOSE("GUID: YUY2\n");
va009039 2:c10029b87439 398 } else if (guid == 0x3231564e) {
va009039 2:c10029b87439 399 VERBOSE("GUID: NV12\n");
va009039 2:c10029b87439 400 } else {
va009039 2:c10029b87439 401 VERBOSE("GUID: %08x\n", guid);
va009039 2:c10029b87439 402 }
va009039 2:c10029b87439 403 VERBOSE("DefaultFrameIndex: %d\n", buf[22]);
va009039 2:c10029b87439 404 if (_payload == UVC_YUY2) {
va009039 2:c10029b87439 405 FormatIndex = buf[3];
va009039 2:c10029b87439 406 }
va009039 2:c10029b87439 407 ENDIF
va009039 2:c10029b87439 408 IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype)
va009039 2:c10029b87439 409 VERBOSE("FrameIndex: %d\n", buf[3]);
va009039 2:c10029b87439 410 VERBOSE("Capabilites: %d\n", buf[4]);
va009039 2:c10029b87439 411 VERBOSE("Width: %d\n", LE16(buf+5));
va009039 2:c10029b87439 412 VERBOSE("Height: %d\n", LE16(buf+7));
va009039 2:c10029b87439 413 VERBOSE("MinBitRate: %d\n", LE32(buf+9));
va009039 2:c10029b87439 414 VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
va009039 2:c10029b87439 415 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
va009039 2:c10029b87439 416 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
va009039 2:c10029b87439 417 VERBOSE("FrameIntervalType: %d\n", buf[25]);
va009039 2:c10029b87439 418 int it = buf[25];
va009039 2:c10029b87439 419 uint32_t max_fi = 333333; // 30.0fps
va009039 2:c10029b87439 420 if (it == 0) {
va009039 2:c10029b87439 421 VERBOSE("FrameMinInterval: %d\n", buf[26]);
va009039 2:c10029b87439 422 VERBOSE("FrameMaxInterval: %d\n", buf[30]);
va009039 2:c10029b87439 423 VERBOSE("FrameIntervalStep: %d\n", buf[34]);
va009039 2:c10029b87439 424 } else {
va009039 2:c10029b87439 425 int pos = 26;
va009039 2:c10029b87439 426 for (int n = 1; n <= it; n++) {
va009039 2:c10029b87439 427 uint32_t fi = LE32(buf+pos);
va009039 2:c10029b87439 428 if (fi >= max_fi) {
va009039 2:c10029b87439 429 max_fi = fi;
va009039 2:c10029b87439 430 }
va009039 2:c10029b87439 431 float fps = 1e+7 / fi;
va009039 2:c10029b87439 432 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
va009039 2:c10029b87439 433 pos += 4;
va009039 2:c10029b87439 434 }
va009039 2:c10029b87439 435 }
va009039 2:c10029b87439 436 if (_payload == UVC_YUY2) {
va009039 2:c10029b87439 437 if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
va009039 2:c10029b87439 438 FrameIndex = buf[3];
va009039 2:c10029b87439 439 }
va009039 2:c10029b87439 440 if (dwFrameInterval == 0) {
va009039 2:c10029b87439 441 dwFrameInterval = max_fi;
va009039 2:c10029b87439 442 }
va009039 2:c10029b87439 443 }
va009039 2:c10029b87439 444 ENDIF
va009039 2:c10029b87439 445 IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype)
va009039 2:c10029b87439 446 VERBOSE("FormatIndex: %d\n", buf[3]);
va009039 2:c10029b87439 447 VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
va009039 2:c10029b87439 448 VERBOSE("Flags: %d\n", buf[5]);
va009039 2:c10029b87439 449 VERBOSE("DefaultFrameIndex: %d\n", buf[6]);
va009039 2:c10029b87439 450 if (_payload == UVC_MJPEG) {
va009039 2:c10029b87439 451 FormatIndex = buf[3];
va009039 2:c10029b87439 452 }
va009039 2:c10029b87439 453 ENDIF
va009039 2:c10029b87439 454 IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype)
va009039 2:c10029b87439 455 VERBOSE("FrameIndex: %d\n", buf[3]);
va009039 2:c10029b87439 456 VERBOSE("Capabilites: %d\n", buf[4]);
va009039 2:c10029b87439 457 VERBOSE("Width: %d\n", LE16(buf+5));
va009039 2:c10029b87439 458 VERBOSE("Height: %d\n", LE16(buf+7));
va009039 2:c10029b87439 459 VERBOSE("MinBitRate: %d\n", LE32(buf+9));
va009039 2:c10029b87439 460 VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
va009039 2:c10029b87439 461 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
va009039 2:c10029b87439 462 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
va009039 2:c10029b87439 463 VERBOSE("FrameIntervalType: %d\n", buf[25]);
va009039 2:c10029b87439 464 int it = buf[25];
va009039 2:c10029b87439 465 uint32_t max_fi = 333333; // 30.0fps
va009039 2:c10029b87439 466 if (it == 0) {
va009039 2:c10029b87439 467 VERBOSE("FrameMinInterval: %d\n", buf[26]);
va009039 2:c10029b87439 468 VERBOSE("FrameMaxInterval: %d\n", buf[30]);
va009039 2:c10029b87439 469 VERBOSE("FrameIntervalStep: %d\n", buf[34]);
va009039 2:c10029b87439 470 } else {
va009039 2:c10029b87439 471 int pos = 26;
va009039 2:c10029b87439 472 for (int n = 1; n <= it; n++) {
va009039 2:c10029b87439 473 uint32_t fi = LE32(buf+pos);
va009039 2:c10029b87439 474 if (fi >= max_fi) {
va009039 2:c10029b87439 475 max_fi = fi;
va009039 2:c10029b87439 476 }
va009039 2:c10029b87439 477 float fps = 1e+7 / fi;
va009039 2:c10029b87439 478 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
va009039 2:c10029b87439 479 pos += 4;
va009039 2:c10029b87439 480 }
va009039 2:c10029b87439 481 }
va009039 2:c10029b87439 482 if (_payload == UVC_MJPEG) {
va009039 2:c10029b87439 483 if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
va009039 2:c10029b87439 484 FrameIndex = buf[3];
va009039 2:c10029b87439 485 }
va009039 2:c10029b87439 486 if (dwFrameInterval == 0) {
va009039 2:c10029b87439 487 dwFrameInterval = max_fi;
va009039 2:c10029b87439 488 }
va009039 2:c10029b87439 489 }
va009039 2:c10029b87439 490 ENDIF
va009039 2:c10029b87439 491 IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype)
va009039 2:c10029b87439 492 ENDIF
va009039 2:c10029b87439 493 }
va009039 2:c10029b87439 494
va009039 2:c10029b87439 495 void UvcCfg::_parserConfigurationDescriptor(uint8_t* buf, int len) {
va009039 2:c10029b87439 496 int pos = 0;
va009039 2:c10029b87439 497 _IfClass = 0;
va009039 2:c10029b87439 498 _IfSubClass = 0;
va009039 2:c10029b87439 499 while (pos < len) {
va009039 2:c10029b87439 500 int type = buf[pos+1];
va009039 2:c10029b87439 501 //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]);
va009039 2:c10029b87439 502 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type)
va009039 2:c10029b87439 503 VERBOSE("NumInterfaces: %d\n", buf[pos+4]);
va009039 2:c10029b87439 504 ENDIF
va009039 2:c10029b87439 505 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type)
va009039 2:c10029b87439 506 VERBOSE("FirstInterface: %d\n", buf[pos+2]);
va009039 2:c10029b87439 507 VERBOSE("InterfaceCount: %d\n", buf[pos+3]);
va009039 2:c10029b87439 508 VERBOSE("FunctionClass: %02X\n", buf[pos+4]);
va009039 2:c10029b87439 509 VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]);
va009039 2:c10029b87439 510 VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]);
va009039 2:c10029b87439 511 VERBOSE("Function: %d\n", buf[pos+7]);
va009039 2:c10029b87439 512 ENDIF
va009039 2:c10029b87439 513 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type)
va009039 2:c10029b87439 514 VERBOSE("InterfaceNumber: %d\n", buf[pos+2]);
va009039 2:c10029b87439 515 VERBOSE("AlternateSetting: %d\n", buf[pos+3]);
va009039 2:c10029b87439 516 VERBOSE("NumEndpoint: %d\n", buf[pos+4]);
va009039 2:c10029b87439 517 VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
va009039 2:c10029b87439 518 VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
va009039 2:c10029b87439 519 VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
va009039 2:c10029b87439 520 VERBOSE("Interface: %d\n", buf[pos+8]);
va009039 2:c10029b87439 521 _If = buf[pos+2];
va009039 2:c10029b87439 522 _Ifalt = buf[pos+3];
va009039 2:c10029b87439 523 _IfClass = buf[pos+5];
va009039 2:c10029b87439 524 _IfSubClass = buf[pos+6];
va009039 2:c10029b87439 525 ENDIF
va009039 2:c10029b87439 526 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type)
va009039 2:c10029b87439 527 VERBOSE("EndpointAddress: %02X\n", buf[pos+2]);
va009039 2:c10029b87439 528 VERBOSE("Attributes: %02X\n", buf[pos+3]);
va009039 2:c10029b87439 529 VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4));
va009039 2:c10029b87439 530 VERBOSE("Interval: %d\n", buf[pos+6]);
va009039 2:c10029b87439 531 if (_IfClass == CC_VIDEO && _IfSubClass == SC_VIDEOSTREAMING) {
va009039 2:c10029b87439 532 if (bEndpointAddress == buf[pos+2]) {
va009039 2:c10029b87439 533 if (wMaxPacketSize == 0) {
va009039 2:c10029b87439 534 wMaxPacketSize = LE16(buf+pos+4);
va009039 2:c10029b87439 535 }
va009039 2:c10029b87439 536 if (wMaxPacketSize == LE16(buf+pos+4)) {
va009039 2:c10029b87439 537 bInterface = _If;
va009039 2:c10029b87439 538 bAlternate = _Ifalt;
va009039 2:c10029b87439 539 }
va009039 2:c10029b87439 540 }
va009039 2:c10029b87439 541 }
va009039 2:c10029b87439 542 ENDIF
va009039 2:c10029b87439 543 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type)
va009039 2:c10029b87439 544 IF_EQ_THEN_PRINTF(CC_VIDEO, _IfClass)
va009039 2:c10029b87439 545 IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, _IfSubClass)
va009039 2:c10029b87439 546 _parserVideoControl(buf+pos, buf[pos]);
va009039 2:c10029b87439 547 ENDIF
va009039 2:c10029b87439 548 IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, _IfSubClass)
va009039 2:c10029b87439 549 _parserVideoStream(buf+pos, buf[pos]);
va009039 2:c10029b87439 550 ENDIF
va009039 2:c10029b87439 551 ENDIF
va009039 2:c10029b87439 552 IF_EQ_THEN_PRINTF(CC_AUDIO, _IfClass)
va009039 2:c10029b87439 553 IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, _IfSubClass)
va009039 2:c10029b87439 554 _parserAudioControl(buf+pos, buf[pos]);
va009039 2:c10029b87439 555 ENDIF
va009039 2:c10029b87439 556 IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, _IfSubClass)
va009039 2:c10029b87439 557 _parserAudioStream(buf+pos, buf[pos]);
va009039 2:c10029b87439 558 ENDIF
va009039 2:c10029b87439 559 ENDIF
va009039 2:c10029b87439 560 ENDIF
va009039 2:c10029b87439 561 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type)
va009039 2:c10029b87439 562 ENDIF
va009039 2:c10029b87439 563 pos += buf[pos];
va009039 2:c10029b87439 564 }
va009039 2:c10029b87439 565 }
va009039 2:c10029b87439 566