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

📄 cpia.c

📁 cpia usb摄像头的驱动程序源码。需要video4linux和i2c-core支持
💻 C
📖 第 1 页 / 共 5 页
字号:
static int free_frame_buf(struct cam_data *cam){	int i;		rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE);	cam->frame_buf = 0;	for (i=0; i < FRAME_NUM; i++)		cam->frame[i].data = NULL;	return 0;}static inline void free_frames(struct cpia_frame frame[FRAME_NUM]){	int i;	for (i=0; i < FRAME_NUM; i++)		frame[i].state = FRAME_UNUSED;	return;}/********************************************************************** * * General functions * **********************************************************************//* send an arbitrary command to the camera */static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d){	int retval, datasize;	u8 cmd[8], data[8];	switch(command) {	case CPIA_COMMAND_GetCPIAVersion:	case CPIA_COMMAND_GetPnPID:	case CPIA_COMMAND_GetCameraStatus:	case CPIA_COMMAND_GetVPVersion:		datasize=8;		break;	case CPIA_COMMAND_GetColourParams:	case CPIA_COMMAND_GetColourBalance:	case CPIA_COMMAND_GetExposure:		down(&cam->param_lock);		datasize=8;		break;	case CPIA_COMMAND_ReadMCPorts: 	case CPIA_COMMAND_ReadVCRegs:		datasize = 4;		break;	default:		datasize=0;		break;	}	cmd[0] = command>>8;	cmd[1] = command&0xff;	cmd[2] = a;	cmd[3] = b;	cmd[4] = c;	cmd[5] = d;	cmd[6] = datasize;	cmd[7] = 0;	retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);	if (retval) {		DBG("%x - failed, retval=%d\n", command, retval);		if (command == CPIA_COMMAND_GetColourParams ||		    command == CPIA_COMMAND_GetColourBalance ||		    command == CPIA_COMMAND_GetExposure)			up(&cam->param_lock);	} else {		switch(command) {		case CPIA_COMMAND_GetCPIAVersion:			cam->params.version.firmwareVersion = data[0];			cam->params.version.firmwareRevision = data[1];			cam->params.version.vcVersion = data[2];			cam->params.version.vcRevision = data[3];			break;		case CPIA_COMMAND_GetPnPID:			cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8);			cam->params.pnpID.product = data[2]+(((u16)data[3])<<8);			cam->params.pnpID.deviceRevision =				data[4]+(((u16)data[5])<<8);			break;		case CPIA_COMMAND_GetCameraStatus:			cam->params.status.systemState = data[0];			cam->params.status.grabState = data[1];			cam->params.status.streamState = data[2];			cam->params.status.fatalError = data[3];			cam->params.status.cmdError = data[4];			cam->params.status.debugFlags = data[5];			cam->params.status.vpStatus = data[6];			cam->params.status.errorCode = data[7];			break;		case CPIA_COMMAND_GetVPVersion:			cam->params.vpVersion.vpVersion = data[0];			cam->params.vpVersion.vpRevision = data[1];			cam->params.vpVersion.cameraHeadID =				data[2]+(((u16)data[3])<<8);			break;		case CPIA_COMMAND_GetColourParams:			cam->params.colourParams.brightness = data[0];			cam->params.colourParams.contrast = data[1];			cam->params.colourParams.saturation = data[2];			up(&cam->param_lock);			break;		case CPIA_COMMAND_GetColourBalance:			cam->params.colourBalance.redGain = data[0];			cam->params.colourBalance.greenGain = data[1];			cam->params.colourBalance.blueGain = data[2];			up(&cam->param_lock);			break;		case CPIA_COMMAND_GetExposure:			cam->params.exposure.gain = data[0];			cam->params.exposure.fineExp = data[1];			cam->params.exposure.coarseExpLo = data[2];			cam->params.exposure.coarseExpHi = data[3];			cam->params.exposure.redComp = data[4];			cam->params.exposure.green1Comp = data[5];			cam->params.exposure.green2Comp = data[6];			cam->params.exposure.blueComp = data[7];			up(&cam->param_lock);			break;		case CPIA_COMMAND_ReadMCPorts: 			if (!cam->params.qx3.qx3_detected) 				break;			/* test button press */ 			cam->params.qx3.button = ((data[1] & 0x02) == 0);			if (cam->params.qx3.button) {				/* button pressed - unlock the latch */				do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0);				do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0);			}			/* test whether microscope is cradled */			cam->params.qx3.cradled = ((data[2] & 0x40) == 0);			break;		default:			break;		}	}	return retval;}/* send a command  to the camera with an additional data transaction */static int do_command_extended(struct cam_data *cam, u16 command,                               u8 a, u8 b, u8 c, u8 d,                               u8 e, u8 f, u8 g, u8 h,                               u8 i, u8 j, u8 k, u8 l){	int retval;	u8 cmd[8], data[8];	cmd[0] = command>>8;	cmd[1] = command&0xff;	cmd[2] = a;	cmd[3] = b;	cmd[4] = c;	cmd[5] = d;	cmd[6] = 8;	cmd[7] = 0;	data[0] = e;	data[1] = f;	data[2] = g;	data[3] = h;	data[4] = i;	data[5] = j;	data[6] = k;	data[7] = l;	retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);	if (retval)		DBG("%x - failed\n", command);	return retval;}/********************************************************************** * * Colorspace conversion * **********************************************************************/#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt,                      int linesize, int mmap_kludge){	int y, u, v, r, g, b, y1;		/* Odd lines use the same u and v as the previous line.	 * Because of compression, it is necessary to get this	 * information from the decoded image. */	switch(out_fmt) {	case VIDEO_PALETTE_RGB555:		y = (*yuv++ - 16) * 76310;		y1 = (*yuv - 16) * 76310;		r = ((*(rgb+1-linesize)) & 0x7c) << 1;		g = ((*(rgb-linesize)) & 0xe0) >> 4 |		    ((*(rgb+1-linesize)) & 0x03) << 6;		b = ((*(rgb-linesize)) & 0x1f) << 3;		u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;		v = (157968 * r - 132278 * g - 25690 * b) / 5366159;		r = 104635 * v;		g = -25690 * u - 53294 * v;		b = 132278 * u;		*rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);		*rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);		*rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);		*rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);		return 4;	case VIDEO_PALETTE_RGB565:		y = (*yuv++ - 16) * 76310;		y1 = (*yuv - 16) * 76310;		r = (*(rgb+1-linesize)) & 0xf8;		g = ((*(rgb-linesize)) & 0xe0) >> 3 |		    ((*(rgb+1-linesize)) & 0x07) << 5;		b = ((*(rgb-linesize)) & 0x1f) << 3;		u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;		v = (157968 * r - 132278 * g - 25690 * b) / 5366159;		r = 104635 * v;		g = -25690 * u - 53294 * v;		b = 132278 * u;		*rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);		*rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);		*rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);		*rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);		return 4;		break;	case VIDEO_PALETTE_RGB24:	case VIDEO_PALETTE_RGB32:		y = (*yuv++ - 16) * 76310;		y1 = (*yuv - 16) * 76310;		if (mmap_kludge) {			r = *(rgb+2-linesize);			g = *(rgb+1-linesize);			b = *(rgb-linesize);		} else {			r = *(rgb-linesize);			g = *(rgb+1-linesize);			b = *(rgb+2-linesize);		}		u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;		v = (157968 * r - 132278 * g - 25690 * b) / 5366159;		r = 104635 * v;		g = -25690 * u + -53294 * v;		b = 132278 * u;		if (mmap_kludge) {			*rgb++ = LIMIT(b+y);			*rgb++ = LIMIT(g+y);			*rgb++ = LIMIT(r+y);			if(out_fmt == VIDEO_PALETTE_RGB32)				rgb++;			*rgb++ = LIMIT(b+y1);			*rgb++ = LIMIT(g+y1);			*rgb = LIMIT(r+y1);		} else {			*rgb++ = LIMIT(r+y);			*rgb++ = LIMIT(g+y);			*rgb++ = LIMIT(b+y);			if(out_fmt == VIDEO_PALETTE_RGB32)				rgb++;			*rgb++ = LIMIT(r+y1);			*rgb++ = LIMIT(g+y1);			*rgb = LIMIT(b+y1);		}		if(out_fmt == VIDEO_PALETTE_RGB32)			return 8;		return 6;	case VIDEO_PALETTE_YUV422:	case VIDEO_PALETTE_YUYV:		y = *yuv++;		u = *(rgb+1-linesize);		y1 = *yuv;		v = *(rgb+3-linesize);		*rgb++ = y;		*rgb++ = u;		*rgb++ = y1;		*rgb = v;		return 4;	case VIDEO_PALETTE_UYVY:		u = *(rgb-linesize);		y = *yuv++;		v = *(rgb+2-linesize);		y1 = *yuv;		*rgb++ = u;		*rgb++ = y;		*rgb++ = v;		*rgb = y1;		return 4;	case VIDEO_PALETTE_GREY:		*rgb++ = *yuv++;		*rgb = *yuv;		return 2;	default:		DBG("Empty: %d\n", out_fmt);		return 0;	}}static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt,                      int in_uyvy, int mmap_kludge){	int y, u, v, r, g, b, y1;	switch(out_fmt) {	case VIDEO_PALETTE_RGB555:	case VIDEO_PALETTE_RGB565:	case VIDEO_PALETTE_RGB24:	case VIDEO_PALETTE_RGB32:		if (in_uyvy) {			u = *yuv++ - 128;			y = (*yuv++ - 16) * 76310;			v = *yuv++ - 128;			y1 = (*yuv - 16) * 76310;		} else {			y = (*yuv++ - 16) * 76310;			u = *yuv++ - 128;			y1 = (*yuv++ - 16) * 76310;			v = *yuv - 128;		}		r = 104635 * v;		g = -25690 * u + -53294 * v;		b = 132278 * u;		break;	default:		y = *yuv++;		u = *yuv++;		y1 = *yuv++;		v = *yuv;		/* Just to avoid compiler warnings */		r = 0;		g = 0;		b = 0;		break;	}	switch(out_fmt) {	case VIDEO_PALETTE_RGB555:		*rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);		*rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);		*rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);		*rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);		return 4;	case VIDEO_PALETTE_RGB565:		*rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);		*rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);		*rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);		*rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);		return 4;	case VIDEO_PALETTE_RGB24:		if (mmap_kludge) {			*rgb++ = LIMIT(b+y);			*rgb++ = LIMIT(g+y);			*rgb++ = LIMIT(r+y);			*rgb++ = LIMIT(b+y1);			*rgb++ = LIMIT(g+y1);			*rgb = LIMIT(r+y1);		} else {			*rgb++ = LIMIT(r+y);			*rgb++ = LIMIT(g+y);			*rgb++ = LIMIT(b+y);			*rgb++ = LIMIT(r+y1);			*rgb++ = LIMIT(g+y1);			*rgb = LIMIT(b+y1);		}		return 6;	case VIDEO_PALETTE_RGB32:		if (mmap_kludge) {			*rgb++ = LIMIT(b+y);			*rgb++ = LIMIT(g+y);			*rgb++ = LIMIT(r+y);			rgb++;			*rgb++ = LIMIT(b+y1);			*rgb++ = LIMIT(g+y1);			*rgb = LIMIT(r+y1);		} else {			*rgb++ = LIMIT(r+y);			*rgb++ = LIMIT(g+y);			*rgb++ = LIMIT(b+y);			rgb++;			*rgb++ = LIMIT(r+y1);			*rgb++ = LIMIT(g+y1);			*rgb = LIMIT(b+y1);		}		return 8;	case VIDEO_PALETTE_GREY:		*rgb++ = y;		*rgb = y1;		return 2;	case VIDEO_PALETTE_YUV422:	case VIDEO_PALETTE_YUYV:		*rgb++ = y;		*rgb++ = u;		*rgb++ = y1;		*rgb = v;		return 4;	case VIDEO_PALETTE_UYVY:		*rgb++ = u;		*rgb++ = y;		*rgb++ = v;		*rgb = y1;		return 4;	default:		DBG("Empty: %d\n", out_fmt);		return 0;	}}static int skipcount(int count, int fmt){	switch(fmt) {	case VIDEO_PALETTE_GREY:		return count;	case VIDEO_PALETTE_RGB555:	case VIDEO_PALETTE_RGB565:	case VIDEO_PALETTE_YUV422:	case VIDEO_PALETTE_YUYV:	case VIDEO_PALETTE_UYVY:		return 2*count;	case VIDEO_PALETTE_RGB24:		return 3*count;	case VIDEO_PALETTE_RGB32:		return 4*count;	default:		return 0;	}}static int parse_picture(struct cam_data *cam, int size){	u8 *obuf, *ibuf, *end_obuf;	int ll, in_uyvy, compressed, decimation, even_line, origsize, out_fmt;	int rows, cols, linesize, subsample_422;	/* make sure params don't change while we are decoding */	down(&cam->param_lock);	obuf = cam->decompressed_frame.data;	end_obuf = obuf+CPIA_MAX_FRAME_SIZE;	ibuf = cam->raw_image;	origsize = size;	out_fmt = cam->vp.pal

⌨️ 快捷键说明

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