📄 spidriver.c
字号:
//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 + -