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

📄 at2041_inf.~c

📁 这个是Linux下的关于2042的程序
💻 ~C
📖 第 1 页 / 共 2 页
字号:
	if (mux_full) {		/* acknowledge for data ready message */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8803;					mux_full = 0;	}				return 0;}static ssize_t demuxfifo_write(struct file *file,const char *buffer, size_t length, loff_t * offset){	down(&demuxfifo_write_sem);	copy_from_user(demux_buf[demux_wr_cnt], buffer, length);		demux_size_buf[demux_wr_cnt] = length;			/* de-multiplex ring buffer control */	if (!demux_ring_cnt) {		demux_wr_cnt ++;		if (demux_wr_cnt == MAX_BUF_NUM) {			demux_ring_cnt ++;			demux_wr_cnt = 0;		}	} else if (demux_ring_cnt && demux_wr_cnt < demux_rd_cnt) {		demux_wr_cnt ++;	}		return 0;}static int at2041_open(struct inode* inode, struct file* filp){	printk("the AT2041 Open!!!\n");	MOD_INC_USE_COUNT;	return 0;}static int at2041_release(struct inode* inode, struct file* filp){	printk("the AT2041 Release!!!\n"); 	MOD_DEC_USE_COUNT;	return 0;}/* the AT2041 file operations */static struct file_operations at2041_fops = {	read:   	muxfifo_read,	write:  	demuxfifo_write,	ioctl:		at2041_ioctl,	open:		at2041_open,	release: 	at2041_release,};static void at2041_interrupt_handle(int irq, void *dev_id, struct pt_regs * regs){	unsigned short tx_data;	unsigned short temp;	unsigned int data_size = 0;		//printk("now at2042 interrupt handle\n");	/* data read from Tx_FIFO of the AT2041 */	tx_data = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));	udelay(10);//printk("read_rx_id= 0x%x\n", tx_data);	/* check whether first tx message is 'data ready message' 	 * or 'data request message'	 */	if ((tx_data & 0x0001) == 0x0000){ // read data from tx_fifo		udelay(10);		/* check tx fifo empty */		if ( !(*((unsigned short *)((unsigned int)pt + AT2041_STATUS_REG_ADDR)) & 0x100) ) {			// read DATA			/* data read from Tx_FIFO of the AT2041 */			tx_data = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));//printk("read_reg_data= 0x%x\n", tx_data);		}		/* TxACK command */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;		}	else if (tx_data == 0x8803) { // read message from tx_fifo : data ready message(Encoder)		/* if first tx message is 'data ready message', 		 * read three tx message sequentially.		 * the contents of second tx_message are 'data type', 'channel ID',		 * 'skip', 'loss' and 'output buffer full', etc.		 */		/* check tx fifo empty */		if ( !(*((unsigned short *)((unsigned int)pt + AT2041_STATUS_REG_ADDR)) & 0x100) ) {			/* read the second parameter of Tx_FIFO */			mux_buf[mux_wr_cnt][0] = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));		} else {			printk("[saa7146] It can't read tx0 register\n");						/* TxACK command */			*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;			}					if ( !(*((unsigned short *)((unsigned int)pt + AT2041_STATUS_REG_ADDR)) & 0x100) ) {			/* read the third parameter of Tx_FIFO */			/* the contents of the third tx_message are 'output data size' */					mux_buf[mux_wr_cnt][1] = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));		} else {			printk("[saa7146] It can't read tx1 register\n");						/* TxACK command */			*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;		}				if ( !(*((unsigned short *)((unsigned int)pt + AT2041_STATUS_REG_ADDR)) & 0x100) ) {			/* read the fourth parameter of Tx_FIFO */			/* the contents of the fourth tx_message are 'reserved' */					mux_buf[mux_wr_cnt][2] = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));		} else {			printk("[saa7146] It can't read tx2 register\n");		}				/* calculate data size to transfer */		*size_buf[mux_wr_cnt] = mux_buf[mux_wr_cnt][1];		data_size = ((*size_buf[mux_wr_cnt] & 0xffff) << 4) + enc_txmsg_size;					/* data read from multiplex FIFO of the AT2041 */		/* write multiplex data from the AT2041 to d/d's buffer */		for (ii = enc_txmsg_size; ii < data_size; ii ++) {			mux_buf[mux_wr_cnt][ii] = *((unsigned short *)((unsigned int)pt + AT2041_MUX_FIFO_ADDR));		}		up(&muxfifo_read_sem);							/* multiplex ring buffer control */		if (!mux_ring_cnt) {			mux_wr_cnt ++;							if (mux_wr_cnt == MAX_BUF_NUM) {				mux_ring_cnt ++;								mux_wr_cnt = 0;			}		} else if (mux_ring_cnt && mux_wr_cnt < mux_rd_cnt) {			mux_wr_cnt ++;						} else {			printk("!!![MUX][%02d][%02d][%02d]\n", mux_wr_cnt, mux_rd_cnt, mux_ring_cnt);		}		/* TxACK command */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;			if (mux_ring_cnt && mux_wr_cnt == mux_rd_cnt) {			mux_full = 1;			printk("!!!!!!!! MUX FULL !!!!!!!!!\n");		} else {			/* acknowledge for data ready message */			*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8803;								}/* TxACK command */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;	/* acknowledge for data ready message */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8803;			}	/* data write to de-multiplex FIFO of the AT2041 */	else if (tx_data == 0x9003) { // read message from txfifo : data request(Decoding) 		if (!demux_ring_cnt && (demux_wr_cnt == demux_rd_cnt)) {			/* check tx fifo empty */			if (!(*((unsigned short *)((unsigned int)pt + AT2041_STATUS_REG_ADDR)) & 0x100)) {				/* txfifo ring buffer control */				temp = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));			} else {				printk("[saa7146] It can't read tx0 register\n");							/* TxACK command */				*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;			}							/* TxACK command */			*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;						/* acknowledge for data request message */			*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x9003;						return;		}		/* check tx fifo empty */		if (!(*((unsigned short *)((unsigned int)pt + AT2041_STATUS_REG_ADDR)) & 0x100)) {			/* txfifo ring buffer control */			temp = *((unsigned short *)((unsigned int)pt + AT2041_TX_FIFO_ADDR));		} else {			printk("[saa7146] It can't read tx0 register\n");						*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;		}					/* write de-multiplex data from d/d's buffer to the AT2041 */		for (ii = 0; ii < (demux_size_buf[demux_rd_cnt] + 256) / 2; ii ++) {			if ((ii == 0) && (demux_buf[demux_rd_cnt][ii] != 0x0000))				printk("data[%d] header error\n", ii);					else if ((ii == 1) && (demux_buf[demux_rd_cnt][ii] != 0x01e0))				printk("data[%d] header error\n", ii);							*((unsigned short *)((unsigned int)pt + AT2041_DEMUX_FIFO_ADDR)) = demux_buf[demux_rd_cnt][ii];		}		/* de-multiplex ring buffer control */		if (!demux_ring_cnt && demux_rd_cnt <= demux_wr_cnt) {			demux_rd_cnt ++;			if (demux_rd_cnt == MAX_BUF_NUM) {				demux_ring_cnt --;				demux_rd_cnt = 0;			}		} else if (demux_ring_cnt) {			demux_rd_cnt ++;			if (demux_rd_cnt == MAX_BUF_NUM) {				demux_ring_cnt --;				demux_rd_cnt = 0;			}						}				up(&demuxfifo_write_sem);		/* TxACK command */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;				/* acknowledge for data request message */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x9003;				}	else {		/* TxACK command */		*((unsigned short *)((unsigned int)pt + AT2041_RX_FIFO_ADDR)) = 0x8003;		}}int at2041_init_module(void){	int ret, kk;	(unsigned short *)pt = (unsigned short *)ioremap(AT2042_BASE, AT2042_REMAP_SIZE);	printk("init_at2042 0x%p ==> 0x%x\n",  pt,  (unsigned int)pt+AT2042_REMAP_SIZE);		ret = register_chrdev(AT2041_MAJOR, "at2041", &at2041_fops);	init_MUTEX_LOCKED(&muxfifo_read_sem);	sema_init(&demuxfifo_write_sem, MAX_BUF_NUM);			if (ret < 0) {		printk("at2042: at2042 register failed\n");		return ret;	}			/* mux_buf & demux_buf allocation */	for (kk = 0; kk < MAX_BUF_NUM; kk ++){		if (!(mux_buf[kk] = (unsigned short *) kmalloc(MAX_BUF_SIZE + (enc_txmsg_size << 1), GFP_KERNEL))) {			printk("AT2041 : mux_buf kmalloc failed...\n");			return -ENOMEM;		}		if (!(demux_buf[kk] = (unsigned short *) kmalloc(MAX_BUF_SIZE, GFP_KERNEL))) {			printk("AT2041 : demux_buf kmalloc failed...\n");			return -ENOMEM;		}		if (!(size_buf[kk] = (unsigned short *) vmalloc(sizeof(unsigned short)))) {			printk("AT2041 : size_buf kmalloc failed...\n");			return -ENOMEM;		}	}	printk("the AT2041 driver initialized...\n");#if 0		/* Enable interrupts for EINT0/GPF0 */	/*HJT*/	printk ("__INTERRUPT_AVAILABLE__\n");	/*HJT*/	//(volatile unsigned long) (rINTMSK) &= ~0x00000001;	//Intservice MASK ==> AVAILABLE		/*HJT*/		(volatile unsigned long) (rINTMSK) &= ~0x00000004;	//Intservice MASK ==> AVAILABLE		/*HJT*/	#endif	/* AT2041_IRQ = 25, Fast interrupt, No interrupt sharing */	//printk ("0x%x : 0x%x\n", SA_INTERRUPT, SA_SHIRQ);	if(request_irq(IRQ_EINT2, at2041_interrupt_handle, SA_INTERRUPT, "at2042", NULL)) 	//if(request_irq(IRQ_EINT2, at2041_interrupt_handle, SA_SHIRQ, "at2042", NULL)) 	//if(request_irq(IRQ_EINT2, at2041_interrupt_handle, 0, "at2042", NULL)) 	{		printk("at2042 : cannot register IRQ %d\n", IRQ_EINT2);		return -EIO;	}	printk("at2042 : register IRQ %d\n", IRQ_EINT2);	return 0;}void at2041_cleanup_module(void){	volatile int ret;		free_irq(IRQ_EINT2, NULL);	ret = unregister_chrdev(AT2041_MAJOR, "at2042");	if (ret < 0) {		printk("at2042: at2042 unregister failed\n");		return;	}	for (ii = 0; ii < MAX_BUF_NUM; ii ++) {		kfree(mux_buf[ii]);		kfree(demux_buf[ii]);		vfree(size_buf[ii]);	}	ret = unregister_chrdev(AT2041_MAJOR, "at2042");	if (ret < 0) {		printk("at2042: at2042 unregister failed\n");		return;	}	printk("at2042: at2042 unloaded\n");	iounmap((void *)pt);	return;}module_init(at2041_init_module);module_exit(at2041_cleanup_module);

⌨️ 快捷键说明

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