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

📄 meteor.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 21 */	0x80,	/* 7:0	[7:0] Pixel number per line on output	*//* 22 */	0x80,	/* 7:0	[7:0] Pixel number per line on input	*//* 23 */	0x03,	/* 7:0	[7:0] Horizontal start position of scaling win*//* 24 */	0x8a,	/* 7:5	Horizontal decimation filter			     4  [8] Horizontal start position of scaling win			   3:2	[9:8] Pixel number per line on input			   1:0  [9:8] Pixel number per line on output 	*//* 25 */	0xf0,	/* 7:0	[7:0] Line number per output field	*//* 26 */	0xf0,	/* 7:0	[7:0] Line number per input field	*//* 27 */	0x0f,	/* 7:0	[7:0] Vertical start of scaling window	*//* 28 */	0x80,	/*   7	Adaptive filter switch			   6:5	Vertical luminance data processing			     4	[8] Vertical start of scaling window 			   3:2  [9:8] Line number per input field			   1:0	[9:8] Line number per output field	*//* 29 */	0x16,	/* 7:0	[7:0] Vertical bypass start		*//* 2a */	0x00,	/* 7:0	[7:0] Vertical bypass count		*//* 2b */	0x00,	/*   4  [8] Vertical bypass start			     2  [8] Vertical bypass count			     0	Polarity, internally detected odd even flag *//* 2c */	0x80,	/* 7:0	Set lower limit V for colour-keying	*//* 2d */	0x7f,	/* 7:0	Set upper limit V for colour-keying	*//* 2e */	0x80,	/* 7:0	Set lower limit U for colour-keying	*//* 2f */	0x7f,	/* 7:0	Set upper limit U for colour-keying	*//* 30 */	0xbf	/*   7	VRAM bus output format			     6	Adaptive geometrical filter			     5	Luminance limiting value			     4	Monochrome and two's complement output data sel			     3	Line quailifier flag			     2	Pixel qualifier flag			     1	Transparent data transfer			     0	Extended formats enable bit		*/};static u_char bt254_default[NUM_BT254_REGS] = {	0x00, 	/* 24 bpp */	0xa0,	0xa0,	0xa0,	0x50,	0x50,	0x50,} ;/* * i2c_write: * Returns	0	Succesful completion. * Returns	1	If transfer aborted or timeout occured. * */static i2c_print_err = 1;static inti2c_write(meteor_reg_t * mtr, u_char slave, u_char rw, u_char reg, u_char data){register unsigned long	wait_counter = 0x0001ffff;register mreg_t *	iic_write_loc = &mtr->base->i2c_write;register int		err = 0;	/* Write the data the the i2c write register */	*iic_write_loc = SAA7116_IIC_NEW_CYCLE |		(((u_long)slave|(u_long)rw) << 16) |		((u_long)reg << 8) | (u_long)data;	/* Wait until the i2c cycle is compeleted */	while((*iic_write_loc & SAA7116_IIC_NEW_CYCLE)) {		if(!wait_counter) break;		wait_counter--;	}	/* 1ffff should be enough delay time for the i2c cycle to complete */	if(!wait_counter) {		if(i2c_print_err)			printf("meteor%d: %d i2c %s transfer timeout 0x%x",				METEOR_NUM(mtr), slave, 				rw ? "read" : "write", *iic_write_loc);					err=1;	} 	/* Check for error on direct write, clear if any */	if(mtr->base->i2c_read & SAA7116_IIC_DIRECT_TRANSFER_ABORTED){		mtr->base->i2c_read |= SAA7116_IIC_DIRECT_TRANSFER_ABORTED;		if(i2c_print_err)			printf("meteor%d: 0x%x i2c %s tranfer aborted",				METEOR_NUM(mtr), slave,				rw ? "read" : "write" );		err= 1;	}	if(err) {		if(i2c_print_err)			printf(" - reg=0x%x, value=0x%x.\n", reg, data);	}			return err;}#undef i2c_printstatic	const char *met_probe (pcici_t tag, pcidi_t type){		switch (type) {	case SAA7116_PHILIPS_ID:	/* meteor */		return("Philips SAA 7116");	};	return ((char *)0);}	/* interrupt handling routine 	   complete meteor_read() if using interrupts	*/static voidmeteor_intr(void *arg){	meteor_reg_t	*mtr	   = (meteor_reg_t *) arg;	mreg_t		*cap	   = &mtr->base->cap_cntl,			*base	   = &mtr->base->dma1e,			*stat	   = &mtr->base->irq_stat;	u_long		status	   = *stat,			cap_err	   = *cap & 0x00000f00,#ifdef METEOR_CHECK_PCI_BUS			pci_err    = pci_conf_read(mtr->tag,						PCI_COMMAND_STATUS_REG),#endif			next_base  = (u_long)(vtophys(mtr->bigbuf));	/*	 * Disable future interrupts if a capture mode is not selected.	 * This can happen when we are in the process of closing or 	 * changing capture modes, otherwise it shouldn't happen.	 */	if(!(mtr->flags & METEOR_CAP_MASK)) {		*cap &= 0x8ff0;	/* disable future interrupts */	}#ifdef METEOR_CHECK_PCI_BUS	/*	 * Check for pci bus errors.	 */#define METEOR_MASTER_ABORT	0x20000000#define METEOR_TARGET_ABORT	0x10000000	if(pci_err & METEOR_MASTER_ABORT) {		printf("meteor%d: intr: pci bus master dma abort: 0x%x 0x%x.\n",			METEOR_NUM(mtr), *base, *(base+3));		pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err);	}	if(pci_err & METEOR_TARGET_ABORT) {		printf("meteor%d: intr: pci bus target dma abort: 0x%x 0x%x.\n",			METEOR_NUM(mtr), *base, *(base+3));		pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err);	}#endif	/*	 * Check for errors.	 */	if (cap_err) {	   if (cap_err & 0x300) {		if(mtr->fifo_errors % 50 == 0) {	   		printf("meteor%d: capture error", METEOR_NUM(mtr));			printf(": %s FIFO overflow.\n",				cap_err&0x0100? "even" : "odd");		}		mtr->fifo_errors++ ;	/* increment fifo capture errors cnt */	   }	   if (cap_err & 0xc00) {		if(mtr->dma_errors % 50 == 0) {	   		printf("meteor%d: capture error", METEOR_NUM(mtr));			printf(": %s DMA address.\n",				cap_err&0x0400? "even" : "odd");		}		mtr->dma_errors++ ;	/* increment DMA capture errors cnt */	   }	}	*cap |= 0x0f30;		/* clear error and field done */	/*	 * In synchronous capture mode we need to know what the address	 * offset for the next field/frame will be.  next_base holds the	 * value for the even dma buffers (for odd, one must add stride).	 */	if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait &&	   (mtr->current < mtr->frames)) { /* could be !=, but < is safer */		/* next_base is initialized to mtr->bigbuf */		next_base += mtr->frame_size * mtr->current;		if(mtr->flags & METEOR_WANT_TS)			next_base += sizeof(struct timeval) * mtr->current;	}	/*	 * Count the field and clear the field flag.	 *	 * In single mode capture, clear the continuous capture mode.	 *	 * In synchronous capture mode, if we have room for another field,	 * adjust DMA buffer pointers.	 * When we are above the hi water mark (hiwat), mtr->synch_wait will	 * be set and we will not bump the DMA buffer pointers.  Thus, once	 * we reach the hi water mark,  the driver acts like a continuous mode	 * capture on the mtr->current frame until we hit the low water	 * mark (lowat).  The user had the option of stopping or halting	 * the capture if this is not the desired effect.	 */	if (status & 0x1) {		/* even field */		mtr->even_fields_captured++;		mtr->flags &= ~METEOR_WANT_EVEN;		if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) {			*base = next_base;			/* XXX should add adjustments for YUV_422 & PLANAR */		}		/*		 * If the user requested to be notified via signal,		 * let them know the field is complete.		 */		if(mtr->proc && (mtr->signal & METEOR_SIG_MODE_MASK))			psignal(mtr->proc, mtr->signal&(~METEOR_SIG_MODE_MASK));	}	if (status & 0x2) {		/* odd field */		mtr->odd_fields_captured++;		mtr->flags &= ~METEOR_WANT_ODD;		if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) {			*(base+3) = next_base + *(base+6);			/* XXX should add adjustments for YUV_422 & PLANAR */		}		/*		 * If the user requested to be notified via signal,		 * let them know the field is complete.		 */		if(mtr->proc && (mtr->signal & METEOR_SIG_MODE_MASK))			psignal(mtr->proc, mtr->signal&(~METEOR_SIG_MODE_MASK));	}	/*	 * If we have a complete frame.	 */	if(!(mtr->flags & METEOR_WANT_MASK)) {		mtr->frames_captured++;		/*		 * post the completion time. 		 */		if(mtr->flags & METEOR_WANT_TS) {			struct timeval *ts;						if(mtr->alloc_pages * PAGE_SIZE <= (mtr->frame_size +					sizeof(struct timeval))) {				ts =(struct timeval *)mtr->bigbuf +							mtr->frame_size;			/* doesn't work in synch mode except for first frame */			/* XXX */				microtime(ts);			}		}		/*		 * Wake up the user in single capture mode.		 */		if(mtr->flags & METEOR_SINGLE)			wakeup((caddr_t)mtr);		/*		 * If the user requested to be notified via signal,		 * let them know the frame is complete.		 */		if(mtr->proc && !(mtr->signal & METEOR_SIG_MODE_MASK))			psignal(mtr->proc, mtr->signal&(~METEOR_SIG_MODE_MASK));		/*		 * Reset the want flags if in continuous or		 * synchronous capture mode.		 */		if(mtr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {			switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {			case METEOR_ONLY_ODD_FIELDS:				mtr->flags |= METEOR_WANT_ODD;				break;			case METEOR_ONLY_EVEN_FIELDS:				mtr->flags |= METEOR_WANT_EVEN;				break;			default:				mtr->flags |= METEOR_WANT_MASK;				break;			}		}		/*		 * Special handling for synchronous capture mode.		 */		if(mtr->flags & METEOR_SYNCAP) {			struct meteor_mem *mm = mtr->mem;			/*			 * Mark the current frame as active.  It is up to			 * the user to clear this, but we will clear it			 * for the user for the current frame being captured			 * if we are within the water marks (see below).			 */			mm->active |= 1 << (mtr->current - 1);			/*			 * Since the user can muck with these values, we need			 * to check and see if they are sane. If they don't			 * pass the sanity check, disable the capture mode.			 * This is rather rude, but then so was the user.			 *			 * Do we really need all of this or should we just			 * eliminate the possiblity of allowing the			 * user to change hi and lo water marks while it			 * is running? XXX			 */			if(mm->num_active_bufs < 0 ||			   mm->num_active_bufs > mtr->frames ||		   	   mm->lowat < 1 || mm->lowat >= mtr->frames ||			   mm->hiwat < 1 || mm->hiwat >= mtr->frames ||			   mm->lowat > mm->hiwat ) {				*cap &= 0x8ff0;				mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK);			} else {				/*			 	 * Ok, they are sane, now we want to				 * check the water marks.			 	 */				if(mm->num_active_bufs <= mm->lowat)					mtr->synch_wait = 0;				if(mm->num_active_bufs >= mm->hiwat)					mtr->synch_wait = 1;				/*				 * Clear the active frame bit for this frame				 * and advance the counters if we are within				 * the banks of the water marks. 				 */				if(!mtr->synch_wait) {					mm->active &= ~(1 << mtr->current);					mtr->current++;					if(mtr->current > mtr->frames)						mtr->current = 1;					mm->num_active_bufs++;				}			}		}	}	*stat |=  0x7;		/* clear interrupt status */	return;}static voidset_fps(meteor_reg_t *mtr, u_short fps){	struct saa7116_regs *s7116 = mtr->base;	unsigned status;	unsigned maxfps, mask = 0x1, length = 0;	SAA7196_WRITE(mtr, SAA7196_STDC, SAA7196_REG(mtr, SAA7196_STDC) | 0x02);	SAA7196_READ(mtr);	status = (s7116->i2c_read & 0xff000000L) >> 24;	/*	 * Determine if there is an input signal.  Depending on the	 * frequency we either have a max of 25 fps (50 hz) or 30 fps (60 hz).	 * If there is no input signal, then we need some defaults.  If the	 * user neglected to specify any defaults, just set to the fps to max.	 */	if((status & 0x40) == 0) {	/* Is there a signal ? */		if(status & 0x20) {			maxfps = 30;	/* 60 hz system */		} else {			maxfps = 25;	/* 50 hz system */		}	} else {			/* We have no signal, check defaults */#if METEOR_SYSTEM_DEFAULT == METEOR_PAL || METEOR_SYSTEM_DEFAULT == METEOR_SECAM		maxfps = 25;#elif METEOR_SYSTEM_DEFAULT == METEOR_NTSC		maxfps = 30;#else		/* Don't really know what to do, just set max */		maxfps = 30;		fps = 30;#endif	}	/*	 * A little sanity checking...	 */	if(fps <  1)	  fps = 1;	if(fps > maxfps) fps = maxfps;	/*	 * Compute the mask/length using the fps.	 */	if(fps == maxfps) {		mask = 0x1;		length = 0x0;	} else if ((float)fps == maxfps/2.0) {			mask = 0x1;		length = 0x1;	} else if (fps > maxfps/2) {		float step, b;		mask = (1<<maxfps) - 1;		length = maxfps - 1;		step = (float)(maxfps - 1)/(float)(maxfps - fps);		for(b=step; b < maxfps; b += step) {			mask &= ~(1<<((int)b));	/* mask out the bth frame */		}	} else {	/* fps < maxfps/2 */		float step, b;		mask = 0x1;		length = maxfps - 1;		step = (float)(maxfps -1)/(float)(fps);		for(b = step + 1; b < maxfps - 1; b += step) {			mask |= (1<<((int)b));	/* mask in the bth frame */		}	}	/*	 * Set the fps.	 */	s7116->fme = s7116->fmo = mask;	s7116->fml = (length << 16) | length;;	mtr->fps = fps;	return;

⌨️ 快捷键说明

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