📄 usbcam.c
字号:
DEBUGMSG(1, (TEXT("Reset: command failed\r\n")));
return bRc;
}
BOOL
InitOVSensor(PDRVCONTEXT pDrv)
{
int i, success;
BOOL bRc;
BYTE tmp, temp;
/* Reset the sensor */
bRc = IICWrite(pDrv, 0x12, 0x80);
if (bRc == FALSE)
return bRc;
/* Wait for it to initialize */
Sleep(1000);
for (i = 0, success = 0; i < OV511IICREADETRIES && !success; i++) {
IICRead(pDrv, OV7610_REG_ID_HIGH, &tmp);
IICRead(pDrv, OV7610_REG_ID_LOW, &temp);
if ((tmp == 0x7F) && (temp == 0xa2)) {
success = 1;
continue;
}
/* Reset the sensor */
bRc = IICWrite(pDrv, 0x12, 0x80);
if (bRc == FALSE)
return bRc;
/* Wait for it to initialize */
Sleep(1000);
/* Dummy read to sync I2C */
bRc = IICRead(pDrv, 0x00, &tmp);
if (bRc == FALSE)
return bRc;
}
if (!success)
return bRc;
DEBUGMSG(1, (TEXT("I2C synced in %d \r\n"), i));
return TRUE;
}
BOOL
OV7XX0Configure(PDRVCONTEXT pDrv)
{
int i, success;
BOOL bRc;
BYTE tmp, temp;
/* Lawrence Glaister <lg@jfm.bc.ca> reports:
*
* Register 0x0f in the 7610 has the following effects:
*
* 0x85 (AEC method 1): Best overall, good contrast range
* 0x45 (AEC method 2): Very overexposed
* 0xa5 (spec sheet default): Ok, but the black level is
* shifted resulting in loss of contrast
* 0x05 (old driver setting): very overexposed, too much
* contrast
*/
OV511REGVALS aRegvalsNorm7610[] = {
{ OV511_I2C_BUS, 0x10, 0xff },
{ OV511_I2C_BUS, 0x16, 0x06 },
{ OV511_I2C_BUS, 0x28, 0x24 },
{ OV511_I2C_BUS, 0x2b, 0xac },
{ OV511_I2C_BUS, 0x12, 0x00 },
{ OV511_I2C_BUS, 0x38, 0x81 },
{ OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */
{ OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */
{ OV511_I2C_BUS, 0x15, 0x01 },
{ OV511_I2C_BUS, 0x20, 0x1c },
{ OV511_I2C_BUS, 0x23, 0x2a },
{ OV511_I2C_BUS, 0x24, 0x10 },
{ OV511_I2C_BUS, 0x25, 0x8a },
{ OV511_I2C_BUS, 0x26, 0xa2 },
{ OV511_I2C_BUS, 0x27, 0xc2 },
{ OV511_I2C_BUS, 0x2a, 0x04 },
{ OV511_I2C_BUS, 0x2c, 0xfe },
{ OV511_I2C_BUS, 0x2d, 0x93 },
{ OV511_I2C_BUS, 0x30, 0x71 },
{ OV511_I2C_BUS, 0x31, 0x60 },
{ OV511_I2C_BUS, 0x32, 0x26 },
{ OV511_I2C_BUS, 0x33, 0x20 },
{ OV511_I2C_BUS, 0x34, 0x48 },
{ OV511_I2C_BUS, 0x12, 0x24 },
{ OV511_I2C_BUS, 0x11, 0x01 },
{ OV511_I2C_BUS, 0x0c, 0x24 },
{ OV511_I2C_BUS, 0x0d, 0x24 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
OV511REGVALS aRegvalsNorm7620[] = {
{ OV511_I2C_BUS, 0x00, 0x00 },
{ OV511_I2C_BUS, 0x01, 0x80 },
{ OV511_I2C_BUS, 0x02, 0x80 },
{ OV511_I2C_BUS, 0x03, 0xc0 },
{ OV511_I2C_BUS, 0x06, 0x60 },
{ OV511_I2C_BUS, 0x07, 0x00 },
{ OV511_I2C_BUS, 0x0c, 0x24 },
{ OV511_I2C_BUS, 0x0c, 0x24 },
{ OV511_I2C_BUS, 0x0d, 0x24 },
{ OV511_I2C_BUS, 0x11, 0x01 },
{ OV511_I2C_BUS, 0x12, 0x24 },
{ OV511_I2C_BUS, 0x13, 0x01 },
{ OV511_I2C_BUS, 0x14, 0x84 },
{ OV511_I2C_BUS, 0x15, 0x01 },
{ OV511_I2C_BUS, 0x16, 0x03 },
{ OV511_I2C_BUS, 0x17, 0x2f },
{ OV511_I2C_BUS, 0x18, 0xcf },
{ OV511_I2C_BUS, 0x19, 0x06 },
{ OV511_I2C_BUS, 0x1a, 0xf5 },
{ OV511_I2C_BUS, 0x1b, 0x00 },
{ OV511_I2C_BUS, 0x20, 0x18 },
{ OV511_I2C_BUS, 0x21, 0x80 },
{ OV511_I2C_BUS, 0x22, 0x80 },
{ OV511_I2C_BUS, 0x23, 0x00 },
{ OV511_I2C_BUS, 0x26, 0xa2 },
{ OV511_I2C_BUS, 0x27, 0xea },
{ OV511_I2C_BUS, 0x28, 0x20 },
{ OV511_I2C_BUS, 0x29, 0x00 },
{ OV511_I2C_BUS, 0x2a, 0x10 },
{ OV511_I2C_BUS, 0x2b, 0x00 },
{ OV511_I2C_BUS, 0x2c, 0x88 },
{ OV511_I2C_BUS, 0x2d, 0x91 },
{ OV511_I2C_BUS, 0x2e, 0x80 },
{ OV511_I2C_BUS, 0x2f, 0x44 },
{ OV511_I2C_BUS, 0x60, 0x27 },
{ OV511_I2C_BUS, 0x61, 0x02 },
{ OV511_I2C_BUS, 0x62, 0x5f },
{ OV511_I2C_BUS, 0x63, 0xd5 },
{ OV511_I2C_BUS, 0x64, 0x57 },
{ OV511_I2C_BUS, 0x65, 0x83 },
{ OV511_I2C_BUS, 0x66, 0x55 },
{ OV511_I2C_BUS, 0x67, 0x92 },
{ OV511_I2C_BUS, 0x68, 0xcf },
{ OV511_I2C_BUS, 0x69, 0x76 },
{ OV511_I2C_BUS, 0x6a, 0x22 },
{ OV511_I2C_BUS, 0x6b, 0x00 },
{ OV511_I2C_BUS, 0x6c, 0x02 },
{ OV511_I2C_BUS, 0x6d, 0x44 },
{ OV511_I2C_BUS, 0x6e, 0x80 },
{ OV511_I2C_BUS, 0x6f, 0x1d },
{ OV511_I2C_BUS, 0x70, 0x8b },
{ OV511_I2C_BUS, 0x71, 0x00 },
{ OV511_I2C_BUS, 0x72, 0x14 },
{ OV511_I2C_BUS, 0x73, 0x54 },
{ OV511_I2C_BUS, 0x74, 0x00 },
{ OV511_I2C_BUS, 0x75, 0x8e },
{ OV511_I2C_BUS, 0x76, 0x00 },
{ OV511_I2C_BUS, 0x77, 0xff },
{ OV511_I2C_BUS, 0x78, 0x80 },
{ OV511_I2C_BUS, 0x79, 0x80 },
{ OV511_I2C_BUS, 0x7a, 0x80 },
{ OV511_I2C_BUS, 0x7b, 0xe2 },
{ OV511_I2C_BUS, 0x7c, 0x00 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
DEBUGMSG(1, (TEXT("starting configuration OV7XX0\r\n")));
/* This looks redundant, but is necessary for WebCam 3 */
ov.primary_i2c_slave = OV7xx0_SID;
bRc = OV511SetSlaveIds(pDrv, OV7xx0_SID);
if (bRc == FALSE)
return bRc;
if (InitOVSensor(pDrv) == TRUE)
{
DEBUGMSG(1, (TEXT("OV7xx0 sensor initalized\r\n")));
}
else
{
/* Reset the 76xx */
if (OV511IICWrite(pDrv, 0x12, 0x80) != TRUE)
return FALSE;
/* Wait for it to initialize */
Sleep(100);
i = 0;
success = 0;
while (i <= OV511IICREADETRIES) {
OV511IICRead(pDrv, OV7610_REG_ID_HIGH, &tmp);
OV511IICRead(pDrv, OV7610_REG_ID_LOW, &temp);
if ((tmp == 0x7F) && (temp== 0xA2))
{
success = 1;
break;
}
else
{
i++;
}
}
// Was (i == i2c_detect_tries) previously. This obviously used to always report
// success. Whether anyone actually depended on that bug is unknown
if ((i >= OV511IICREADETRIES) && (success == 0)) {
DEBUGMSG(1, (TEXT("Failed to read sensor ID. You might not have an\r\n")));
DEBUGMSG(1, (TEXT("OV7610/20, or it may be not responding. Report\r\n")));
// Only issue a warning for now
return FALSE;
} else
{
DEBUGMSG(1, (TEXT("OV7xx0 initialized , %dx\r\n"), i+1));
}
}
/* Detect sensor (sub)type */
bRc = IICRead(pDrv, OV7610_REG_COM_I, &tmp);
if (bRc == FALSE)
{
DEBUGMSG(1, (TEXT("Error detecting sensor type\r\n")));
return bRc;
}
switch(tmp & 3)
{
case 0:
DEBUGMSG(1, (TEXT("Sensor is an OV7620!\r\n")));
ov.sensor = SEN_OV7620;
break;
case 1:
bRc = IICRead(pDrv, 0x15, &temp);
if(temp & 1)
{
DEBUGMSG(1, (TEXT("Sensor is an OV7620AE!\r\n")));
}
else
{
DEBUGMSG(1, (TEXT("Sensor is an OV76BE!\r\n")));
}
if (ov.bridge == BRG_OV511PLUS)
{
DEBUGMSG(1, (TEXT("Enabling 511+/7620AE workaround\r\n")));
ov.sensor = SEN_OV7620;
}
else
{
ov.sensor = SEN_OV76BE;
}
break;
case 3:
DEBUGMSG(1, (TEXT("Sensor is an OV7610!\r\n")));
ov.sensor = SEN_OV7610;
break;
default:
DEBUGMSG(1, (TEXT("Unknown image sensor version: %d\r\n"), tmp & 3));
return FALSE;
}
if (ov.sensor == SEN_OV7620)
{
DEBUGMSG(1, (TEXT("Writing 7620 registers!\r\n")));
bRc = WriteRegisters(pDrv, aRegvalsNorm7620);
if (bRc == FALSE)
return bRc;
}
else
{
DEBUGMSG(1, (TEXT("Writing 7610 registers!\r\n")));
bRc = WriteRegisters(pDrv, aRegvalsNorm7610);
if (bRc == FALSE)
return bRc;
}
/* Set sensor-specific vars */
ov.maxwidth = 640;
ov.maxheight = 480;
ov.minwidth = 64;
ov.minheight = 48;
// FIXME: These do not match the actual settings yet
ov.brightness = 0x80 << 8;
ov.contrast = 0x80 << 8;
ov.colour = 0x80 << 8;
ov.hue = 0x80 << 8;
return TRUE;
}
BOOL
OV6XX0Configure(PDRVCONTEXT pDrv)
{
BOOL bRc;
BYTE tmp;
OV511REGVALS aRegvalsNorm6x20[] = {
{ OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
{ OV511_I2C_BUS, 0x11, 0x01 },
{ OV511_I2C_BUS, 0x03, 0x60 },
{ OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
{ OV511_I2C_BUS, 0x07, 0xa8 },
/* The ratio of 0x0c and 0x0d controls the white point */
{ OV511_I2C_BUS, 0x0c, 0x24 },
{ OV511_I2C_BUS, 0x0d, 0x24 },
{ OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */
{ OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */
{ OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */
{ OV511_I2C_BUS, 0x14, 0x04 },
/* 0x16: 0x06 helps frame stability with moving objects */
{ OV511_I2C_BUS, 0x16, 0x06 },
// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
{ OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
/* 0x28: 0x05 Selects RGB format if RGB on */
{ OV511_I2C_BUS, 0x28, 0x05 },
{ OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
{ OV511_I2C_BUS, 0x2d, 0x99 },
{ OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Procesing Parameter */
{ OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */
{ OV511_I2C_BUS, 0x38, 0x8b },
{ OV511_I2C_BUS, 0x39, 0x40 },
{ OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
{ OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
{ OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
{ OV511_I2C_BUS, 0x3d, 0x80 },
/* These next two registers (0x4a, 0x4b) are undocumented. They
* control the color balance */
{ OV511_I2C_BUS, 0x4a, 0x80 },
{ OV511_I2C_BUS, 0x4b, 0x80 },
{ OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */
{ OV511_I2C_BUS, 0x4e, 0xc1 },
{ OV511_I2C_BUS, 0x4f, 0x04 },
// Do 50-53 have any effect?
// Toggle 0x12[2] off and on here?
{ OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
};
OV511REGVALS aRegvalsNorm6x30[] = {
/*OK*/
{ OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
{ OV511_I2C_BUS, 0x11, 0x00 },
/*OK*/
{ OV511_I2C_BUS, 0x03, 0x60 },
/*0A?*/
{ OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
{ OV511_I2C_BUS, 0x07, 0xa8 },
/* The ratio of 0x0c and 0x0d controls the white point */
/*OK*/
{ OV511_I2C_BUS, 0x0c, 0x24 },
/*OK*/
{ OV511_I2C_BUS, 0x0d, 0x24 },
/*A*/
{ OV511_I2C_BUS, 0x0e, 0x20 },
// /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 },
{ OV511_I2C_BUS, 0x16, 0x03 },
// /*OK*/ { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
// 21 & 22? The suggested values look wrong. Go with default
/*A*/
{ OV511_I2C_BUS, 0x23, 0xc0 },
/*A*/
{ OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default
// /*OK*/ { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
/* 0x28: 0x05 Selects RGB format if RGB on */
// /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 },
// /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus
/*OK*/
{ OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
// /*OK*/ { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
{ OV511_I2C_BUS, 0x2d, 0x99 },
// /*A*/ { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620
// /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */
// /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 },
// /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7
// { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
// { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
// { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
{ OV511_I2C_BUS, 0x3d, 0x80 },
// /*A*/ { OV511_I2C_BUS, 0x3f, 0x0e },
/* These next two registers (0x4a, 0x4b) are undocumented. They
* control the color balance */
// /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these
// /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 },
{ OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
/*c1?*/
{ OV511_I2C_BUS, 0x4e, 0x40 },
/* UV average mode, color killer: strongest */
{ OV511_I2C_BUS, 0x4f, 0x07 },
{ OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */
{ OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */
{ OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */
{ OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */
{ OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */
// { OV511_I2C_BUS, 0x5c, 0x10 },
{ OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
};
DEBUGMSG(1, (TEXT("starting sensor configuration\r\n")));
if (InitOVSensor(pDrv) != TRUE) {
DEBUGMSG(1, (TEXT("Failed to read sensor ID. You might not have an OV6xx0,\r\nor it may be not responding.\r\n")));
return FALSE;
}
else {
DEBUGMSG(1, (TEXT("OV6xx0 sensor detected!\r\n")));
}
/* Detect sensor (sub)type */
bRc = IICRead(pDrv, OV7610_REG_COM_I, &tmp);
if (bRc == FALSE) {
DEBUGMSG(1, (TEXT("Error detecting sensor type\r\n")));
return bRc;
}
switch(tmp & 3)
{
case 0:
ov.sensor = SEN_OV6630;
DEBUGMSG(1, (TEXT("Sensor is an OV6630\r\n")));
break;
case 1:
ov.sensor = SEN_OV6620;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -