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

📄 spidriver.c

📁 国腾8142扩展芯片在S3C2410上的SPI驱动程序,数据接收与发送.
💻 C
📖 第 1 页 / 共 2 页
字号:
   //printk("Queue is empty, can't dequeue...");  return -1; } x=p->data; q->front=p->next;  if (q->rear==p)  q->rear=NULL; kfree(p); return x;}//return queuevoid return_queue(link_queue *q,char x){queue_node *p=(queue_node *)kmalloc(sizeof(queue_node), GFP_ATOMIC); p->data=x; p->next=NULL; if (queue_empty(q))  q->front=q->rear=p; else {	p->next=q->front; 	p=q->front;  }}void disp(link_queue *s){ queue_node *p=s->front; printk("------------queue data: \n"); while (p!=NULL) {  printk("%c, ",p->data);  p=p->next; } printk("\n");}static ssize_t spi_write(struct file *filp, const char *buf, size_t size, loff_t *f_pos);static ssize_t spi_read(struct file *filp, char *buf, size_t size, loff_t *f_pos);static int spi_open(struct inode *inode, struct file *filp);static int spi_release(struct inode *inode, struct file *filp); static int spi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long param);int  spi_init(void);static void spi_cleanup(void);static void spi_interrupt(int irq,void *dev_id,struct pt_regs *regs);/********************************************************************************************************              define announce********************************************************************************************************/module_init(spi_init);module_exit(spi_cleanup);//MODULE_LICENSE("GPL");MODULE_DESCRIPTION("SPI driver");MODULE_SUPPORTED_DEVICE("arm-linux 2.4.18 sc2410 spi");MODULE_AUTHOR("xiao");/********************************************************************************************************/static struct file_operations spi_fops =        /* driver info  */{    owner:  THIS_MODULE,    write:    spi_write,    read:     spi_read,    ioctl:    spi_ioctl,    open:     spi_open,    release:  spi_release,};static ssize_t spi_read(struct file *filp, char *buf, size_t size, loff_t *f_pos){  	//	 unsigned int i;	 char chr;	 char tmp_buf[1024];	 queue_node *p = read_queue->front; 	 //queue_node *p = write_queue->front;  //debug  	memset(&tmp_buf, 0x0, 1024); 	 //printk("enter into [read]....\n"); 	 if(verify_area(VERIFY_READ,buf,size) == -EFAULT)    	return -EFAULT;	//seting readflags	read_flags=1;  	i = 0; 	 while( p!= NULL)  	{   	 tmp_buf[i] = p->data;   	 chr = de_queue(read_queue);    	p = p->next;    	i++;  	} 	 if(i > 0) 	 {    		copy_to_user(buf, tmp_buf,i);    	 //printk("read buf = %s\n", buf); 	 }	   return i;}static ssize_t spi_write(struct file *filp, const char *buf, size_t size, loff_t *f_pos){   	//	 unsigned int i;  	char tmp_buf[1024];  	memset(&tmp_buf, 0x0, 1024);	//seting write flags	write_flags=1;  	if(verify_area(VERIFY_WRITE,buf,size) == -EFAULT)    		return -EFAULT;  	if(copy_from_user(tmp_buf,buf,size))      		return -EFAULT;    	//printk("write buf: %s\n", tmp_buf);  	i = 0;  	while( i < size )  	{    	en_queue(write_queue,tmp_buf[i]);    	i++;  	}  	disp(write_queue);	  return i;}                /*********************************************************************************************************** Function name: spi_open** Descriptions:  open device** Input:inode:   information of device**       filp:    pointer of file** Output 0:      OK**        other:  not OK****------------------------------------------------------------------------------------------------------********************************************************************************************************/static int spi_open(struct inode *inode, struct file *filp){   	printk("Now,SPI program begin...\n");	printk("GPE,GPF,GPG port initial...\n");/****************************************************************Define SPI0 Interface configuration**GPG2=nSS0,GPE11=SPIMISO0,GPE12=SPIMOSI0,GPE13=SPICLK0,**GPF3=EINT3,**************************************************************/	spi_gpgcon &=0xffffffcf;  //GPGCON-2=11	spi_gpgcon |=0x30;	spi_gpgup &=0xfffb;  //GPGUP-2=0      MOD_INC_USE_COUNT;	printk("SPI device open!\n");    return 0;          /* success */} static int spi_release(struct inode *inode, struct file *filp) {           MOD_DEC_USE_COUNT;	printk("SPI device release!\n");       return(0); } static int spi_ioctl(struct inode *inode, struct file *filp,                        unsigned int cmd, unsigned long arg){    	int flags;	unsigned int temp1;	local_irq_save(flags);	if((cmd <0) && (cmd>3))		{			printk("UART Number is Error!\n");			return -1;		}	else		{		switch(cmd)			{			case UART0:				//setting baud 4800,odd parity,10bits,disable transform interrupt,				temp1=Write814xConfig(0,0xc0, 0x05);				com_number=0;				break;			case UART1:				//setting baud 4800,odd parity,10bits,disable transform interrupt,				temp1=Write814xConfig(1,0xc0, 0x05);				com_number=1;				break;			case UART2:				//setting baud 4800,odd parity,10bits,disable transform interrupt,				temp1=Write814xConfig(2,0xc0, 0x05);				com_number=2;				break;			case UART3:				//setting baud 4800,odd parity,10bits,disable transform interrupt,				temp1=Write814xConfig(3,0xc0, 0x05);				com_number=3;				break;						}		}		local_irq_restore(flags);    return 0;}static int __init spi_init(void){	int ret;	int flags;	unsigned int temp1,temp2,temp3,temp4;/****************************************************************Define SPI0 Interface configuration**GPG2=nSS0,GPE11=SPIMISO0,GPE12=SPIMOSI0,GPE13=SPICLK0,**GPF3=EINT3,**************************************************************/	SPI_GPGCON=ioremap(0x56000060,4);	SPI_GPGCON=ioremap(0x56000064,4);	SPI_GPGUP = ioremap(0x56000068,4);	SPI_SPCON0=ioremap(0x59000000,4);	SPI_SPSTAT0=ioremap(0x59000004,4);	SPI_SPPIN0 =ioremap(0x59000008,4);	SPI_SPPRE0=ioremap(0x5900000c,4);	SPI_SPTDAT0=ioremap(0x59000010,4);	SPI_SPRDAT0=ioremap(0x59000014,4);		local_irq_save(flags);   //save current system interrupt      //setting baud 4800,odd parity,10bits,disable transform interrupt,	temp1=Write814xConfig(0,0xc0, 0x05);  	temp2=Write814xConfig(1,0xc0, 0x05);	temp3=Write814xConfig(2,0xc0,0x05);	temp4=Write814xConfig(3,0xc0,0x05);	local_irq_restore(flags);  //restore current system interrupt	ret = register_chrdev(0,DEVICE_NAME,&spi_fops);	if(ret <0)		{		printk(DEVICE_NAME "Can't get major number\n");		return ret;		}	//open GM8142 interrupt	set_external_irq(interrupt_IO, EXT_LOWLEVEL, GPIO_PULLUP_EN);  	ret=request_irq(interrupt_IO,&spi_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL); 	 if (ret<0)  	{   	 printk("Cannot SPI interrupt!\n");   	 return ret;  	} 	 else  	  printk("Interrupt has been registed!\n");	 printk(DEVICE_NAME " initialized\n");	 //init read and write queue 	read_queue = (link_queue *)kmalloc(sizeof(link_queue), GFP_ATOMIC);  	write_queue = (link_queue *)kmalloc(sizeof(link_queue), GFP_ATOMIC);  	init_queue(read_queue);  	init_queue(write_queue);	 return 0;}static void __exit spi_cleanup(void){    	unregister_chrdev(DEVICE_MAJOR, DEVICE_NAME);	free_irq(interrupt_IO,spi_interrupt);	printk("SPI device is cleanup\n");}static void spi_interrupt(int irq,void *dev_id,struct pt_regs *regs){	unsigned int temp,temp1,temp2,temp3,temp4;	unsigned int state,recv_data;	unsigned char send_data; disable_irq(irq);//tansimt dataif(read_flags==1){	send_data =  de_queue(write_queue);	switch(com_number)		{		case 0:			while(Flag1_T==1)				{				temp=SendDataToCom(0,send_data);				ManageRevData(temp); 				Delay(5);				}										break;		case 1:			while(Flag2_T==1)				{				temp=SendDataToCom(1,send_data);				ManageRevData(temp);				Delay(5);				}										break;		case 2:			while(Flag3_T==1)				{				temp=SendDataToCom(2,send_data);				ManageRevData(temp); 				Delay(5);				}										break;		case 3:			while(Flag4_T==1)				{				temp=SendDataToCom(3,send_data);				ManageRevData(temp); 				Delay(5);				}										break;		}	read_flags=0;}	//receive dataif (write_flags==1){	//get GM814x configuration 	temp1=Read814xConfig(0) ;	temp2=Read814xConfig(1) ;	temp3=Read814xConfig(2) ;	temp4=Read814xConfig(3) ;	//get FIFO state	state=ReadTFIFOState();	//get FIFO data	recv_data=ReadRFIFOData();	//handle receive data	ManageRevData(recv_data); 	switch(com_number)		{		case 0:			printk("Received Port is UART0,Received_data = %c\n", Revbuff1);      	 		en_queue(read_queue, Revbuff1);			disp(read_queue);			break;		case 1:			printk("Received Port is UART1,Received_data = %c\n", Revbuff2);      	 		en_queue(read_queue, Revbuff2);			disp(read_queue);			break;		case 2:			printk("Received Port is UART2,Received_data = %c\n", Revbuff3);      	 		en_queue(read_queue, Revbuff3);			disp(read_queue);			break;		case 3:			printk("Received Port is UART3,Received_data = %c\n", Revbuff4);      	 		en_queue(read_queue, Revbuff4);			disp(read_queue);			break;				}	write_flags=0;		} enable_irq(irq);}

⌨️ 快捷键说明

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