📄 rf905.c
字号:
/* driver/char/led.c * this is a led char device driver. * Any problem pls contact support@hhcn.com */#include <linux/module.h>#include <linux/fs.h>#include <linux/iobuf.h>#include <linux/major.h>#include <linux/blkdev.h>#include <linux/capability.h>#include <linux/smp_lock.h>#include <asm/uaccess.h>#include <asm/hardware.h>#include <asm/arch/cpu_s3c2410.h>#include <asm/io.h>#include <linux/vmalloc.h>#include <linux/config.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/highmem.h>#include <linux/in.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/tqueue.h>#include <linux/wait.h>#include <linux/interrupt.h>#include <asm/irq.h>#include <linux/delay.h>#ifdef CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>#endif//#include "rf905_ioctl.h"#define RF905_MAJOR 139#define U8 unsigned char//#define U32 unsigned int/*SPI registers*/#define rSPCON0 (*(volatile unsigned long *)r_SPCON0) /*SPI control Register*/#define rSPSTA0 (*(volatile unsigned long *)r_SPSTA0) /*SPI status Register*/#define rSPPIN0 (*(volatile unsigned long *)r_SPPIN0) /* SPI pin control Register*/#define rSPPRE0 (*(volatile unsigned long *)r_SPPRE0) /*SPI Baud Rate Prescaler Register */#define rSPTDAT0 (*(volatile unsigned long *)r_SPTDAT0) /*SPI Tx Data Register*/#define rSPRDAT0 (*(volatile unsigned long *)r_SPRDAT0) /*SPI Rx Data Register*//*I/O registers*/#define rGPECON (*(volatile unsigned long *)r_GPECON) /*Configure the pins of port E*/#define rGPEUP (*(volatile unsigned long *)r_GPEUP) /*Pull-up disable register for port E*/#define rGPBCON (*(volatile unsigned long *)r_GPBCON) /*Configure the pins of port B*/#define rGPBUP (*(volatile unsigned long *)r_GPBUP) /*Pull-up disable register for port B*/#define rGPBDAT (*(volatile unsigned long *)r_GPBDAT) /*The data register for port B*/#define rGPCCON (*(volatile unsigned long *)r_GPCCON) /*Configure the pins of port G*/#define rGPCUP (*(volatile unsigned long *)r_GPCUP) /*Pull-up disable register for port G*/#define rGPCDAT (*(volatile unsigned long *)r_GPCDAT) /*The data register for port G*/unsigned long r_SPCON0,r_SPSTA0,r_SPPIN0,r_SPPRE0,r_SPTDAT0,r_SPRDAT0;unsigned long r_GPECON,r_GPEUP;unsigned long r_GPBCON,r_GPBUP,r_GPBDAT;unsigned long r_GPCCON,r_GPCUP,r_GPCDAT;/**********************************************************//*----------------------------------------------- nrf905命令控制字 ------------------------------------------------*/ #define WC 0x00 // Write configuration register command #define RC 0x10 // Read configuration register command #define WTP 0x20 // Write TX Payload command #define RTP 0x21 // Read TX Payload command #define WTA 0x22 // Write TX Address command #define RTA 0x23 // Read TX Address command #define RRP 0x24 // Read RX Payload command /********************************************************************************************/devfs_handle_t devfs_rf905;int rf905_open(struct inode *, struct file *);int rf905_release(struct inode *, struct file *);//int rf905_ioctl(struct inode *, struct file *, unsigned int, unsigned long);//ssize_t rf905_read(struct file *, char * , size_t );ssize_t rf905_write(struct file *, char * , size_t );static void spi_poll_done(void);void spi_tx_data(U8 data);void send_data(U8 data);void init_rf905(void);void Init_SPI(void);/************************************************************************************//* *//************************************************************************************/static struct file_operations rf905_fops = { open: rf906_open,//read: rf905_read, write: rf905_write,// ioctl: rf905_ioctl, release: rf905_release,};int rf905_open(struct inode *inode, struct file *filp){ // Init_SPI(void); init_rf905(void); printk("open ok\n"); return 0;}/*ssize_t rf905_read(struct file *fp, char * buf, size_t size){ return 1;}*/ssize_t rf905_write(struct file *fp, char * buf, size_t size){ char data; unsigned long i; rGPBDAT |=0x400; udelay(80); rGPBDAT &=(~0x400); //select the chip udelay(1000); spi_tx_data(WTP); //write rf905 tx data for(i=0;i<32;i++) {if (get_user(data, buf+i)) { printk("tx data to rf905 error"); return -EFAULT; } spi_tx_data(data); //0 } rGPBDAT |=0x400; //Unselect the chip rGPBDAT |=0x203; //Unselect the chip udelay(700); for(;i<1;) { udelay(100); i =rGPCDAT; i =i&0x40; i =i/0x40; } /* i=rGPBDAT; if() */ return 1;}int rf905_release(struct inode *inode, struct file *filp){ rGPBDAT &= (~0x400); //chip_select disable rGPBDAT |=0x400; printk("release ok\n"); return 0;}/*int rf905_ioctl(struct inode *inode, struct file *flip, unsigned int command, unsigned long arg){ int err = 0; switch (command) { case break; case ; break; case ; break; case break; case break; case break; default: err = -EINVAL; } return err;}*//***********************************************************************************************//* 子程序 *//***********************************************************************************************//**********************************************************///Initialize 2410 spivoid Init_SPI(void){ int i; rSPPRE0 = 0xff; //2410 SPI_BAUD; rSPCON0 = 0x18; //polling mode is used here! for(i = 0 ; i < 10 ; i++) { rSPTDAT0 = 0xff; } rGPECON |= 0x0a800000; rGPECON &= (~0x05400000); rGPEUP |= 0x3800; //GPB10----->CS rGPBDAT |=0x400; //Unselect the chip spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff);}/*******************************************************************************/void init_rf905(void){ rGPBDAT &=(~0x2); // rGPBDAT |=0x201; // standby model udelay(3000); rGPBDAT &=(~0x400); //select the chip udelay(10000); spi_tx_data(WC); spi_tx_data(0xff); //0 spi_tx_data(0x0d); //1 spi_tx_data(0x24); //2 spi_tx_data(0x20); //3 spi_tx_data(0x20); //4 spi_tx_data(0x0); //5 spi_tx_data(0xec); //6 spi_tx_data(0xec); //7 spi_tx_data(0xec); //8 spi_tx_data(0x5b); //9 rGPBDAT |=0x400; //Unselect the chip udelay(1000); rGPBDAT |=0x400; //select the chip udelay(10000); spi_tx_data(WTA); // spi_tx_data(0x0); //0 spi_tx_data(0xC8); //0 spi_tx_data(0xC8); //0 spi_tx_data(0xC8); //0 rGPBDAT |=0x400; //Unselect the chip}/*******************************************************************************/void send_data(U8 data){ rGPBDAT &=(~0x400); //select the chip udelay(40000); spi_tx_data(data); rGPBDAT |=0x400; //Unselect the chip}/**********************************************************///To polling when SPI transfer is not finishedstatic void spi_poll_done(void){ int nCount=0; while(!(rSPSTA0 & 0x01) ) { nCount++; if(nCount>=5000) { printk("SPI state poll failed\n"); break; } }//endwhile }/**********************************************************///Transmit datavoid spi_tx_data(U8 data){ spi_poll_done(); rSPTDAT0 = data; //transmit data spi_poll_done(); }/**********************************************************//*************************************************************************************************//* *//*************************************************************************************************/int __init rf905_init(void){ printk("*********************rf905_init**************\n"); devfs_rf905 = devfs_register(NULL, "rf905", DEVFS_FL_DEFAULT,RF905_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, &rf905_fops, NULL); //SPI registers r_SPCON0 = ioremap(0x59000000,4); r_SPSTA0 = ioremap(0x59000004,4); r_SPPIN0 = ioremap(0x59000008,4); r_SPPRE0 = ioremap(0x5900000C,4); r_SPTDAT0 = ioremap(0x59000010,4); r_SPRDAT0 = ioremap(0x59000014,4); //I/O registers r_GPECON = ioremap(0x56000040,4); r_GPEUP = ioremap(0x56000048,4); r_GPBCON = ioremap(0x56000010,4); r_GPBUP = ioremap(0x56000018,4); r_GPBDAT = ioremap(0x56000014,4); r_GPCCON = ioremap(0x56000020,4); r_GPCUP = ioremap(0x56000028,4); r_GPCDAT = ioremap(0x56000024,4); //set io register rGPBCON |= 0x140005; rGPBCON &= (~0x28000a); rGPBUP |=0x403; rGPCCON &= (~0x3000); rGPCUP |=0x40; Init_SPI(); ////// spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); spi_tx_data(0xff); return 0;}static void __exit rf905_exit(void){ devfs_unregister(devfs_rf905);}module_init(rf905_init);module_exit(rf905_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -