⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qc-hdcs.c

📁 在Linux下用于webeye的摄像头的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	I2C_SET_CHECK(HDCS_PCTRL, BIT(6)|BIT(5)|BIT(1)|BIT(0));	I2C_SET_CHECK(HDCS_PDRV,  0x00);	I2C_SET_CHECK(HDCS_ICTRL, (sd->subsample ? BIT(7) : 0) | BIT(5));	I2C_SET_CHECK(HDCS_ITMG,  BIT(4)|BIT(1));	/* CONFIG: Bit 3: continous frame capture, bit 2: stop when frame complete */	I2C_SET_CHECK(config, (sd->subsample ? BIT(5) : 0) | BIT(3));	I2C_SET_CHECK(HDCS_ADCCTRL, 10);	/* ADC output resolution to 10 bits */	if ((r = qc_i2c_wait(qc))<0) goto fail;fail:	return r;}/* }}} *//* {{{ [fold] hdcs_start: Start grabbing */static int hdcs_start(struct quickcam *qc){	int r;#if HDCS_COMPRESSr = hdcs_compress_init(qc, 2);qc_i2c_wait(qc);if (r) PDEBUG("hdcs_compress_init(1) = %i", r);return 0;#endif	if ((r = qc_i2c_break(qc))<0) goto fail;	I2C_SET_CHECK(GET_CONTROL, BIT(2));	/* Run enable */	if ((r = qc_i2c_break(qc))<0) goto fail;fail:	return r;}/* }}} *//* {{{ [fold] hdcs_stop: Stop grabbing */static int hdcs_stop(struct quickcam *qc){	int r;	if ((r = qc_i2c_break(qc))<0) goto fail;	I2C_SET_CHECK(GET_CONTROL, BIT(1));	/* Stop and enter sleep mode */	r = qc_i2c_wait(qc);fail:	return r;}/* }}} *//* {{{ [fold] hdcs_set_exposure: Set exposure time, val=0..65535 */static int hdcs_set_exposure(struct quickcam *qc, unsigned int val){	struct qc_sensor_data *sd = &qc->sensor_data;	unsigned char control = GET_CONTROL;	unsigned int rowexp;		/* rowexp,srowexp = 15 bits (0..32767) */	unsigned int srowexp;		/* sub-row exposure (smaller is brighter) */	unsigned int max_srowexp;	/* Maximum srowexp value + 1 */	int r;	/* Absolute black at srowexp=2672,width=360; 2616, width=352; 1896, width=256 for hdcs1000 */	if (val==sd->exposure) return 0;	sd->exposure = val;	val *= 16;		/* 16 seems to be the smallest change that actually affects brightness */	max_srowexp = sd->width*15/2 - 104 + 1;	srowexp = max_srowexp - (val % max_srowexp) - 1;	rowexp  = val / max_srowexp;	if (qcdebug&QC_DEBUGCAMERA) PDEBUG("width=%i height=%i rowexp=%i srowexp=%i",sd->width,sd->height,rowexp,srowexp);	if ((r = qc_i2c_break(qc))<0) goto fail;		/* The following setting must go into same I2C packet */	I2C_SET_CHECK(control, 0);				/* Stop grabbing */	I2C_SET_CHECK(HDCS_ROWEXPL, rowexp & 0xFF);		/* Number of rows to expose */	I2C_SET_CHECK(HDCS_ROWEXPH, rowexp >> 8);	if (IS_1020(qc)) {		srowexp = 0;	//FIXME:need formula to compute srowexp for HDCS1020!		srowexp >>= 2;					/* Bits 0..1 are hardwired to 0 */		I2C_SET_CHECK(HDCS20_SROWEXP, srowexp & 0xFF);	/* Number of pixels to expose */	} else {		I2C_SET_CHECK(HDCS00_SROWEXPL, srowexp & 0xFF);	/* Number of pixels to expose */		I2C_SET_CHECK(HDCS00_SROWEXPH, srowexp >> 8);	}	if (IS_1020(qc)) {		I2C_SET_CHECK(HDCS20_ERROR, BIT(0));		/* Reset exposure error flag */	} else {		I2C_SET_CHECK(HDCS_STATUS, BIT(4));		/* Reset exposure error flag */	}	I2C_SET_CHECK(control, BIT(2));				/* Restart grabbing */	if ((r = qc_i2c_break(qc))<0) goto fail;#if 0	/* Warning: the code below will cause about 0.1 second delay and may cause lost frames */	if (PARANOID) {		/* Check if the new exposure setting is valid */		if ((r = qc_i2c_wait(qc))<0) goto fail;		if (IS_1020(qc)) {			if ((r = qc_get_i2c(qc,qc->sensor_data.sensor, HDCS20_ERROR))<0) goto fail;			if (r & BIT(0)) PDEBUG("exposure error (1020)");		} else {			if ((r = qc_get_i2c(qc,qc->sensor_data.sensor, HDCS_STATUS))<0) goto fail;			if (r & BIT(4)) PDEBUG("exposure error (1000)");		}	}	if ((r = qc_i2c_wait(qc))<0) goto fail;#endif	qc_frame_flush(qc);fail:	return (r<0) ? r : 0;}/* }}} *//* {{{ [fold] hdcs_set_gains: Set gains */static int hdcs_set_gains(struct quickcam *qc, unsigned int hue, unsigned int sat, unsigned int val){	static const unsigned int min_gain = 8;	struct qc_sensor_data *sd = &qc->sensor_data;	unsigned int rgain, bgain, ggain;	int r;	qc_hsv2rgb(hue, sat, val, &rgain, &bgain, &ggain);	rgain >>= 8;					/* After this the values are 0..255 */	ggain >>= 8;	bgain >>= 8;	rgain = MAX(rgain, min_gain);			/* Do not allow very small values, they cause bad (low-contrast) image */	ggain = MAX(ggain, min_gain);	bgain = MAX(bgain, min_gain);	if (rgain==sd->rgain && ggain==sd->ggain && bgain==sd->bgain) return 0;	sd->rgain = rgain;				sd->ggain = ggain;	sd->bgain = bgain;	if (rgain > 127) rgain = rgain/2 | BIT(7);	/* Bit 7 doubles the programmed values */	if (ggain > 127) ggain = ggain/2 | BIT(7);	/* Double programmed value if necessary */	if (bgain > 127) bgain = bgain/2 | BIT(7);	if ((r = qc_i2c_break(qc))<0) goto fail;	I2C_SET_CHECK(HDCS_ERECPGA, ggain);	I2C_SET_CHECK(HDCS_EROCPGA, rgain);	I2C_SET_CHECK(HDCS_ORECPGA, bgain);	I2C_SET_CHECK(HDCS_OROCPGA, ggain);fail:	return r;}/* }}} *//* {{{ [fold] hdcs_set_levels() */static int hdcs_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat){	int r = 0;//#if !HDCS_COMPRESS	if ((r = hdcs_set_exposure(qc, gain))<0) goto fail;//#endif	hdcs_set_gains(qc, hue, sat, exp);fail:	return r;}/* }}} *//* {{{ [fold] hdcs_set_size: Sets the size of the capture window *//* *  Sets the size (scaling) of the capture window. *  If subsample could return the image size we use subsample. */static int hdcs_set_size(struct quickcam *qc, unsigned int width, unsigned int height){	/* The datasheet doesn't seem to say this, but HDCS-1000	 * has visible windows size of 360x296 pixels, the first upper-left	 * visible pixel is at 8,8.	 * From Andrey's test image: looks like HDCS-1020 upper-left	 * visible pixel is at 24,8 (y maybe even smaller?) and lower-right	 * visible pixel at 375,299 (x maybe even larger?)	 */	unsigned int originx   = IS_1020(qc) ? 24 : 8;		/* First visible pixel */	unsigned int maxwidth  = IS_1020(qc) ? 352 : 360;	/* Visible sensor size */	unsigned int originy   = 8;	unsigned int maxheight = IS_1020(qc) ? 292 : 296;	unsigned char control = GET_CONTROL;	struct qc_sensor_data *sd = &qc->sensor_data;	int r;	unsigned int x, y;#if HDCS_COMPRESS	return 0;#endif	if (sd->subsample) {		width *= 2;		height *= 2;		width  = (width + 3)/4*4;		/* Width must be multiple of 4 */		height = (height + 3)/4*4;		/* Height must be multiple of 4 */		sd->width = width / 2;		sd->height = height / 2;		/* The image sent will be subsampled by 2 */	} else {		sd->width  = width  = (width + 3)/4*4;	/* Width must be multiple of 4 */		sd->height = height = (height + 3)/4*4;	/* Height must be multiple of 4 */	}	x = (maxwidth - width)/2;			/* Center image by computing upper-left corner */	y = (maxheight - height)/2;	width /= 4;	height /= 4;	x = (x + originx)/4;				/* Must be multiple of 4 (low bits wired to 0) */	y = (y + originy)/4;	if ((r = qc_i2c_break(qc))<0) goto fail;	I2C_SET_CHECK(control, 0);			/* Stop grabbing */	I2C_SET_CHECK(HDCS_FWROW, y);	I2C_SET_CHECK(HDCS_FWCOL, x);	I2C_SET_CHECK(HDCS_LWROW, y+height-1);	I2C_SET_CHECK(HDCS_LWCOL, x+width-1);	I2C_SET_CHECK(control, BIT(2));			/* Restart grabbing */		/* The exposure timings need to be recomputed when size is changed */	x = sd->exposure;	sd->exposure = -1;	if ((r = hdcs_set_exposure(qc, x))<0) goto fail;fail:	return r;}/* }}} *//* {{{ [fold] struct qc_sensor qc_sensor_hdcs1000 */const struct qc_sensor qc_sensor_hdcs1000 = {	name:		"HDCS-1000/1100",	manufacturer:	"Hewlett Packard",	init:		hdcs_init,	start:		hdcs_start,	stop:		hdcs_stop,	set_size:	hdcs_set_size,	set_levels:	hdcs_set_levels,	/* Exposure and gain control information */	autoexposure:	FALSE,	adapt_gainlow:	20,	adapt_gainhigh:	20000,	/* Information needed to access the sensor via I2C */	reg23: 		0,	i2c_addr: 	HDCS_ADDR,	/* Identification information used for auto-detection */	id_reg:		HDCS_IDENT | 1,	id:		0x08,	length_id:	1,	flag:		0,};/* }}} *//* {{{ [fold] struct qc_sensor qc_sensor_hdcs1020 */const struct qc_sensor qc_sensor_hdcs1020 = {	name:		"HDCS-1020",	manufacturer:	"Agilent Technologies",	init:		hdcs_init,	start:		hdcs_start,	stop:		hdcs_stop,	set_size:	hdcs_set_size,	set_levels:	hdcs_set_levels,	/* Exposure and gain control information */	autoexposure:	FALSE,	adapt_gainlow:	20,	adapt_gainhigh:	20000,	/* Information needed to access the sensor via I2C */	reg23: 		0,	i2c_addr: 	HDCS_ADDR,	/* Identification information used for auto-detection */	id_reg:		HDCS_IDENT | 1,	id:		0x10,	length_id:	1,	flag:		1,};/* }}} *//* End of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -