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

📄 h3600_backpaq_camera.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
		case VIDEO_PALETTE_GREY:			buf += 352 * (288 - 1);			break;		case VIDEO_PALETTE_YUV422:			buf += 352 * (288 - 1) * 2;			break;		}		WRITE_CIF_IMAGE(REVERSE);	}	else {		WRITE_CIF_IMAGE(FORWARD);	}	return result;}static unsigned long write_qcif( struct frame *frame, unsigned char *buf, 				int streaming, int flipped, int palette ){	unsigned char *source    = frame->data;	register int row_width   = frame->width;	unsigned char temp_buf[176 * 3];	register unsigned char *to;	register unsigned char *from;	unsigned long           result = 0;	int                     source_row = 0;	if ( flipped ) {		switch (palette) {		case VIDEO_PALETTE_RGB24:			buf += 176 * (144 - 1) * 3;			break;		case VIDEO_PALETTE_GREY:			buf += 176 * (144 - 1);			break;		case VIDEO_PALETTE_YUV422:			buf += 176 * (144 - 1) * 2;			break;		}		WRITE_QCIF_IMAGE(REVERSE);	}	else {		WRITE_QCIF_IMAGE(FORWARD);	}	return result;}/* Write the state out into a buffer *//* We've already checked that the buffer is of the required size and has been verified *//* There are a couple of possible states:   1. The frame has already written into shared memory and no processing is required   2. The frame needs to be written to shared memory (buf == NULL)   3. The frame needs to be copied into buf.*/static long process_frame( struct h3600_camera_struct *cam, unsigned char *dest, int index ){	struct frame *frame = &(cam->frame[index]);	unsigned long result = 0;	int           streaming;	unsigned char *buf;	if ( frame->state == FRAME_DONE ) {		CAMERROR("Trying to process DONE frame\n");		return -EINVAL;	}	if ( dest ) {		buf = dest;		streaming = 0;	} else {		buf = cam->frame[index].shared_data;		streaming = 1;	}	switch (cam->mode) {	case HC_MODE_RAW:		if ( !streaming )			__copy_to_user( buf, frame->data, HC_RAW_BUFFER_SIZE );		result = HC_RAW_BUFFER_SIZE; 		break;	case HC_MODE_RAW_DECIMATED:		if ( !streaming )			__copy_to_user( buf, frame->data, HC_DECIMATED_BUFFER_SIZE );		result = HC_DECIMATED_BUFFER_SIZE; 		break;	case HC_MODE_DECIMATION_1:		result = write_vga(frame,buf,streaming,cam->params.flip,cam->vpic.palette);		break;	case HC_MODE_DECIMATION_4:		decimate( frame );		/* Intentional fall through */	case HC_MODE_DECIMATION_2:		if ( !decimate_mode ) decimate( frame );		result = write_qvga(frame,buf,streaming,cam->params.flip,cam->vpic.palette);		break;	case HC_MODE_CIF:		result = write_cif(frame,buf,streaming,cam->params.flip,cam->vpic.palette);		break;	case HC_MODE_QCIF:		if ( !decimate_mode ) decimate(frame);		result = write_qcif(frame,buf,streaming,cam->params.flip,cam->vpic.palette);		break;	}	frame->state = FRAME_DONE;	return result;}/****************************************************************************** * * Read data from the camera.  This may be run at interrupt time or  * from a polling routine.  Return "-1" if the FIFO goes over its maximum * depth.  Otherwise, return "N" where "N" is the number of bytes left to read. * ******************************************************************************/#define MAXIMUM_FIFO_DEPTH 255static int get_fpga_data( struct h3600_camera_struct *cam ){	struct frame *frame = cam->active;	unsigned int         *lbuf = (unsigned int *) (frame->data + frame->bytes_read);	unsigned short        data_avail;	int i, count;	unsigned short        fifo_info = BackpaqSocketCameraFifoInfo;	int bytes_per_unit = (fifo_info & BACKPAQ_CAMERA_FIFO_INFO_BPC) >> 8;	int fifo_width     = (fifo_info & BACKPAQ_CAMERA_FIFO_INFO_WIDTH);	unsigned short       *sbuf = (unsigned short *) lbuf;	volatile unsigned short *fifo_data = (unsigned short *) &(BackpaqSocketCameraFifoData);	while (frame->bytes_read < frame->bytes_to_read) {		data_avail = BackpaqSocketCameraFifoDataAvail;		if ( data_avail >= MAXIMUM_FIFO_DEPTH )			return -1;		if ( data_avail > cam->capture_stats.fifo_high )			cam->capture_stats.fifo_high = data_avail;		if ( data_avail < cam->capture_stats.fifo_low )			cam->capture_stats.fifo_low = data_avail;		if ( data_avail <= 0 )			return frame->bytes_to_read - frame->bytes_read;		count = data_avail * bytes_per_unit;		if ( count + frame->bytes_read > frame->bytes_to_read )			count = frame->bytes_to_read - frame->bytes_read;			if ( fifo_width == 16 ) 			for ( i = 0 ; i < count ; i+=2 )  /* We read 2 bytes at a time */				*sbuf++ = *fifo_data;		else			for ( i = 0 ; i < count ; i+=4 )				*lbuf++ = BackpaqSocketCameraFifoData;				frame->bytes_read += i;	}		return frame->bytes_to_read - frame->bytes_read;}/****************************************************************************** * * Interrupt routines * ******************************************************************************/#define ENABLE_OPT_INT(x) \		BackpaqSocketFPGAInterruptMask &= ~(x)#define DISABLE_OPT_INT(x) \		BackpaqSocketFPGAInterruptMask |= (x)#define READ_OPT_INT(x) \		BackpaqSocketFPGAInterruptStatus & (x) \                & ~BackpaqSocketFPGAInterruptMask#define ENABLE_VBLANK_INT   ENABLE_OPT_INT(BACKPAQ_SOCKET_INT_VBLANK)#define DISABLE_VBLANK_INT  DISABLE_OPT_INT(BACKPAQ_SOCKET_INT_VBLANK)#define READ_VBLANK_INT     READ_OPT_INT(BACKPAQ_SOCKET_INT_VBLANK)#define ENABLE_FIFO_INT     ENABLE_OPT_INT(BACKPAQ_SOCKET_INT_FIFO)#define DISABLE_FIFO_INT    DISABLE_OPT_INT(BACKPAQ_SOCKET_INT_FIFO)#define READ_FIFO_INT       READ_OPT_INT(BACKPAQ_SOCKET_INT_FIFO)#define ENABLE_BOTH_INT     ENABLE_OPT_INT(BACKPAQ_SOCKET_INT_FIFO | BACKPAQ_SOCKET_INT_VBLANK)#define DISABLE_BOTH_INT    DISABLE_OPT_INT(BACKPAQ_SOCKET_INT_FIFO | BACKPAQ_SOCKET_INT_VBLANK)#define READ_BOTH_INT       READ_OPT_INT(BACKPAQ_SOCKET_INT_FIFO | BACKPAQ_SOCKET_INT_VBLANK)static void capture_buffer_complete( struct h3600_camera_struct *cam ){	cam->active->state = FRAME_FULL;	cam->active = cam->active->next;	cam->capture_stats.complete_frames++;	/* Now, branch based on our state */	switch (cam->state) {	case HC_V4L_IDLE:		CAMERROR("Capture buffer complete when in IDLE state\n");		break;	case HC_V4L_GRABBING:		wake_up_interruptible(&cam->capq); 		DISABLE_BOTH_INT;		cam->capture_state = CAPTURE_OFF;		break;	case HC_V4L_STREAMING:		wake_up_interruptible(&cam->capq);		break;	}}  static void fpga_fifo_interrupt( struct h3600_camera_struct *cam ){	int retval;	DISABLE_FIFO_INT;      /* We must re-enable FIFO for the appropriate states */	cam->capture_stats.fifo_count++;	switch (cam->capture_state) {	case CAPTURE_OFF:		CAMERROR(": FIFO interrupt when capture is off?!?!\n");		break;	case CAPTURE_WAIT_FOR_REFRESH:		CAMERROR(": FIFO interrupt when capture is waiting for VBLANK!\n");		break;	case CAPTURE_WAIT_FOR_FIFO:		ENABLE_VBLANK_INT;    /* No matter what, we're interested in VBLANK again */		if ( !cam->active ) {  /* No buffer! */			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			cam->capture_stats.ef_no_capture_buffer++;			return;         /* The FIFO_INT is still disabled */		}		cam->capture_state = CAPTURE_ACTIVE;		cam->active->state = FRAME_ACTIVE;		/* Deliberate fall-through */	case CAPTURE_ACTIVE:		retval = get_fpga_data(cam);		if ( retval < 0 ) {			cam->active->bytes_read = 0;			cam->active->state = FRAME_PENDING;			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			cam->capture_stats.ef_fifo_overrun++;			return;          /* The FIFO_INT is still disabled */		}		else if ( retval > 0 )			ENABLE_FIFO_INT;   /* More data still to be read */		else {			cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;			capture_buffer_complete( cam );		}		break;	}}static void fpga_vblank_interrupt( struct h3600_camera_struct *cam ){	int retval;	cam->capture_stats.vblank_count++;	switch (cam->capture_state) {	case CAPTURE_WAIT_FOR_REFRESH:		ENABLE_FIFO_INT;		cam->capture_state = CAPTURE_WAIT_FOR_FIFO;		break;	case CAPTURE_WAIT_FOR_FIFO:		cam->capture_stats.ef_extra_vblank++;		break;	case CAPTURE_ACTIVE:   /* Suck in the last bit of data */		DISABLE_FIFO_INT;         /* Shut off the FIFO interrupt */		retval = get_fpga_data(cam);		if ( retval < 0 ) {			cam->active->bytes_read = 0;			cam->active->state = FRAME_PENDING;			cam->capture_state = CAPTURE_WAIT_FOR_FIFO;			cam->capture_stats.ef_fifo_overrun++;			ENABLE_FIFO_INT;		}		else if ( retval > 0 ) {			cam->active->bytes_read = 0;			cam->active->state = FRAME_PENDING;			cam->capture_state = CAPTURE_WAIT_FOR_FIFO;			cam->capture_stats.ef_incomplete_frames++;			ENABLE_FIFO_INT;		}		else {			cam->capture_state = CAPTURE_WAIT_FOR_FIFO;			ENABLE_FIFO_INT;			capture_buffer_complete( cam );		}		break;	case CAPTURE_OFF:		CAMERROR(": Received VBLANK interrupt when capture was off\n");		break;	}}static void fpga_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev_id;	unsigned short irq_value = READ_BOTH_INT;		if (!cam ) {		printk(KERN_ALERT __FILE__ ": interrupt %d without valid cam\n",irq);		return;	}		if ( irq != IRQ_GPIO_H3600_OPT_IRQ ) {		printk(KERN_ALERT __FILE__ ": Unknown IRQ %d\n",irq);		return;	}	/* Handle the FIFO interrupt */	if ( irq_value & BACKPAQ_SOCKET_INT_FIFO )		fpga_fifo_interrupt(cam);	/* Handle the VBLANK interrupt */	if ( irq_value & BACKPAQ_SOCKET_INT_VBLANK )		fpga_vblank_interrupt(cam);	/* Do some sanity checking */	if ( cam->state == HC_V4L_GRABBING 	     && cam->capture_stats.complete_frames == 0 	     && ( cam->capture_stats.ef_extra_vblank 		  + cam->capture_stats.ef_fifo_overrun 		  + cam->capture_stats.ef_incomplete_frames 		  + cam->capture_stats.ef_no_capture_buffer ) >= 3 ) {		/* Too many errors...abort the GRAB */		wake_up_interruptible(&cam->capq); 		DISABLE_BOTH_INT;		cam->capture_state = CAPTURE_OFF;	}	GEDR = GPIO_H3600_OPT_IRQ; /* Clear the interrupt */}/****************************************************************************** * * Turn on and off capture states * ******************************************************************************//* Add this capture buffer to the "pending" list   *//* Call this with interrupts disabled              */static int queue_capture_buffer( struct h3600_camera_struct *cam, int index ){	int result = 0;	struct frame *frame = &(cam->frame[index]);	switch (frame->state) {	case FRAME_DONE:	case FRAME_FULL:		if ( cam->active ) {			struct frame *a = cam->active;			while ( a->next )				a = a->next;			a->next = frame;		}		else			cam->active = frame;		frame->next = NULL;		frame->state = FRAME_PENDING;		break;	case FRAME_ACTIVE:		frame->state = FRAME_PENDING;		cam->capture_state = CAPTURE_WAIT_FOR_REFRESH;		DISABLE_FIFO_INT;		ENABLE_VBLANK_INT;		break;	case FRAME_PENDING:		/* Do nothing */		break;	}	if ( cam->state == HC_V4L_STREAMING 	     && (cam->mode == HC_MODE_RAW || cam->mode == HC_MODE_RAW_DECIMATED ))		frame->data = frame->shared_data;	else		frame->data = frame->local_data;	frame->bytes_read = 0;	frame->bytes_to_read = hc_raw[fpga_mode_to_decimation[cam->mode]].bytes;	frame->width         = hc_raw[fpga_mode_to_decimation[cam->mode]].width;	frame->height        = hc_raw[fpga_mode_to_decimation[cam->mode]].height;	if ( cam->active ) {		struct frame *a = cam->active;		result++;		while ( a->next ) {			a = a->next;			result++;		}	}	return result;}/* Call this with interrupts disabled                        *//* This resets each capture buffer AND all of the statistics */stati

⌨️ 快捷键说明

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