搜索
bottom↓
回复: 0

有没有人做过NRF24L01的mini2440接收的驱动???

[复制链接]

出0入0汤圆

发表于 2012-3-27 13:39:13 | 显示全部楼层 |阅读模式
自己最近在移植一个NRF24L01的驱动,可以在友善之臂的mini2440上运行,不过测试总是无法接收到发送过来的信号(发送端是好的,用的是51单片机控制的NRF24L01),不知道怎么回事,是驱动程序的问题?  
  
     还是友善的mini2440上引出的CON4 GPIO引脚不能用(我用的就是它自带的linux系统)? 请大家指教!!!!!!!

    下面是原驱动代码:


#ifndef _NRF24L01_H_
#define _NRF24L01_H_

#define DEVICE_NAME "NRF24L01"

#ifndef NRF24L01_MAJOR
#define NRF24L01_MAJOR 248
#endif

#ifndef NRF24L01_MINOR
#define NRF24L01_MINOR 0
#endif

#ifndef NRF24L01_NR_DEVS                //
#define NRF24L01_NR_DEVS 1
#endif


//鍜屽紩鑴氱浉鍏崇殑瀹忓畾涔?
#define CSN       S3C2410_GPG(0)
     
#define MOSI      S3C2410_GPG(3)
   
#define IRQ       S3C2410_GPG(5)
      
#define MISO      S3C2410_GPG(6)
   
#define SCK       S3C2410_GPG(7)
   
#define CE        S3C2410_GPG(11)
      

//NRF24L01绔彛瀹氫箟
#define CE_OUT  s3c2410_gpio_cfgpin(CE,S3C2410_GPIO_OUTPUT)  //
#define CE_UP        s3c2410_gpio_pullup(CE, 1)        //
#define CE_L  s3c2410_gpio_setpin(CE, 0)   //
#define CE_H  s3c2410_gpio_setpin(CE, 1)   //

#define SCK_OUT  s3c2410_gpio_cfgpin(SCK,S3C2410_GPIO_OUTPUT)//
#define SCK_UP        s3c2410_gpio_pullup(SCK, 1)        //
#define SCK_L  s3c2410_gpio_setpin(SCK, 0)  //
#define SCK_H  s3c2410_gpio_setpin(SCK, 1)  //

#define MISO_IN  s3c2410_gpio_cfgpin(MISO,S3C2410_GPIO_INPUT) /
#define MISO_UP        s3c2410_gpio_pullup(MISO, 1)        //
#define MISO_STU       s3c2410_gpio_getpin(MISO)   //

#define IRQ_IN  s3c2410_gpio_cfgpin(IRQ,S3C2410_GPIO_INPUT) //
#define IRQ_UP        s3c2410_gpio_pullup(IRQ, 1)        //
#define IRQ_L  s3c2410_gpio_setpin(IRQ, 0)   //
#define IRQ_H  s3c2410_gpio_setpin(IRQ, 1)   //

#define MOSI_OUT s3c2410_gpio_cfgpin(MOSI,S3C2410_GPIO_OUTPUT) //
#define MOSI_UP        s3c2410_gpio_pullup(MOSI, 1)        //
#define MOSI_L  s3c2410_gpio_setpin(MOSI, 0)  //
#define MOSI_H  s3c2410_gpio_setpin(MOSI, 1)  /


#define CSN_OUT  s3c2410_gpio_cfgpin(CSN,S3C2410_GPIO_OUTPUT) //
#define CSN_UP        s3c2410_gpio_pullup(CSN, 1)        //
#define CSN_L  s3c2410_gpio_setpin(CSN, 0)  //
#define CSN_H  s3c2410_gpio_setpin(CSN, 1)  //

//NRF24L01
#define TX_ADR_WIDTH    5        // 5 uint8s TX address width
#define RX_ADR_WIDTH    5        // 5 uint8s RX address width
#define TX_PLOAD_WIDTH  20    // 20 uint8s TX payload
#define RX_PLOAD_WIDTH  20       // 20 uint8s TX payload
unsigned char   TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};    //
unsigned char  RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};    //


//NRF24L01瀵勫瓨鍣ㄦ寚浠?
#define READ_REG        0x00    //
#define WRITE_REG       0x20    //
#define RD_RX_PLOAD     0x61    // 璇诲彇鎺ユ敹鏁版嵁鎸囦护
#define WR_TX_PLOAD     0xA0    // 鍐欏緟鍙戞暟鎹寚浠?
#define FLUSH_TX        0xE1    // 鍐叉礂鍙戦€?FIFO鎸囦护
#define FLUSH_RX        0xE2    // 鍐叉礂鎺ユ敹 FIFO鎸囦护
#define REUSE_TX_PL     0xE3    // 瀹氫箟閲嶅瑁呰浇鏁版嵁鎸囦护
#define NOP             0xFF    // 淇濈暀


//SPI(nRF24L01)瀵勫瓨鍣ㄥ湴鍧€
#define CONFIG          0x00  // 閰嶇疆鏀跺彂鐘舵€侊紝CRC鏍¢獙妯″紡浠ュ強鏀跺彂鐘舵€佸搷搴旀柟寮?
#define EN_AA           0x01  // 鑷姩搴旂瓟鍔熻兘璁剧疆
#define EN_RXADDR       0x02  // 鍙敤淇¢亾璁剧疆
#define SETUP_AW        0x03  // 鏀跺彂鍦板潃瀹藉害璁剧疆
#define SETUP_RETR      0x04  // 鑷姩閲嶅彂鍔熻兘璁剧疆
#define RF_CH           0x05  // 宸ヤ綔棰戠巼璁剧疆
#define RF_SETUP        0x06  // 鍙戝皠閫熺巼銆佸姛鑰楀姛鑳借缃?
#define STATUS          0x07  // 鐘舵€佸瘎瀛樺櫒
#define OBSERVE_TX      0x08  // 鍙戦€佺洃娴嬪姛鑳?
#define CD              0x09  // 鍦板潃妫€娴?         
#define RX_ADDR_P0      0x0A  // 棰戦亾0鎺ユ敹鏁版嵁鍦板潃
#define RX_ADDR_P1      0x0B  // 棰戦亾1鎺ユ敹鏁版嵁鍦板潃
#define RX_ADDR_P2      0x0C  // 棰戦亾2鎺ユ敹鏁版嵁鍦板潃
#define RX_ADDR_P3      0x0D  // 棰戦亾3鎺ユ敹鏁版嵁鍦板潃
#define RX_ADDR_P4      0x0E  // 棰戦亾4鎺ユ敹鏁版嵁鍦板潃
#define RX_ADDR_P5      0x0F  // 棰戦亾5鎺ユ敹鏁版嵁鍦板潃
#define TX_ADDR         0x10  // 鍙戦€佸湴鍧€瀵勫瓨鍣?
#define RX_PW_P0        0x11  // 鎺ユ敹棰戦亾0鎺ユ敹鏁版嵁闀垮害
#define RX_PW_P1        0x12  // 鎺ユ敹棰戦亾0鎺ユ敹鏁版嵁闀垮害
#define RX_PW_P2        0x13  // 鎺ユ敹棰戦亾0鎺ユ敹鏁版嵁闀垮害
#define RX_PW_P3        0x14  // 鎺ユ敹棰戦亾0鎺ユ敹鏁版嵁闀垮害
#define RX_PW_P4        0x15  // 鎺ユ敹棰戦亾0鎺ユ敹鏁版嵁闀垮害
#define RX_PW_P5        0x16  // 鎺ユ敹棰戦亾0鎺ユ敹鏁版嵁闀垮害
#define FIFO_STATUS     0x17  // FIFO鏍堝叆鏍堝嚭鐘舵€佸瘎瀛樺櫒璁剧疆



#endif /* _NRF24L01_H_ */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/irq.h>

#include "NRF24L01.h"

static int nrf24l01_major=NRF24L01_MAJOR;                //涓昏澶囧彿
static int nrf24l01_minor=NRF24L01_MINOR;                //娆¤澶囧彿

dev_t dev;

struct cdev nrf24l01;

unsigned char TxBuf[20]={0};         
unsigned char RxBuf[20]={0};

unsigned char opencount = 0;                                        //鍏ㄥ眬鍙橀噺
unsigned char flag = 0;
char     sta;                                          //鐘舵€佹爣蹇?



void init_NRF24L01(void);

unsigned char SPI_RW(unsigned char tmp);

unsigned char SPI_Read(unsigned char reg);

void SetRX_Mode(void);

unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);

unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars);

unsigned char  SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars);

unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);

void nRF24L01_TxPacket(unsigned char * tx_buf);


void init_NRF24L01(void)                                //NRF24L01鍒濆鍖?
{
       
    MISO_UP;

    CE_OUT;
    CSN_OUT;
    SCK_OUT;
    MOSI_OUT;
    MISO_IN;
    IRQ_IN;
    flag = 1;
    udelay(100);

    CE_L;    // chip enable
//   ndelay(60);
    CSN_H;   // Spi disable
//   ndelay(60);
    SCK_L;   // Spi clock line init high
//   ndelay(60);
    SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 鍐欐湰鍦板湴鍧€
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 鍐欐帴鏀剁鍦板潃
    SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  棰戦亾0鑷姩 ACK搴旂瓟鍏佽
    SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  鍏佽鎺ユ敹鍦板潃鍙湁棰戦亾0锛屽鏋滈渶瑕佸棰戦亾鍙互鍙傝€働age21  
    SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   璁剧疆淇¢亾宸ヤ綔涓?.4GHZ锛屾敹鍙戝繀椤讳竴鑷?
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //璁剧疆鎺ユ敹鏁版嵁闀垮害锛屾湰娆¤缃负32瀛楄妭
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);         //璁剧疆鍙戝皠閫熺巼涓?MHZ锛屽彂灏勫姛鐜囦负鏈€澶у€?dB
   
    printk("init! \n");
//    mdelay(1000);
}


//鍑芥暟锛歶nsigned char SPI_RW(uint8 tmp)
//鍔熻兘锛歂RF24L01鐨凷PI鍐欐椂搴弔mp
unsigned char SPI_RW(unsigned char tmp)
{
    unsigned char bit_ctr;

    for(bit_ctr=0 ;bit_ctr<8 ;bit_ctr++) // output 8-bit
    {
        if(tmp & 0x80)         // output 'tmp', MSB to MOSI
                       MOSI_H;
        else
                    MOSI_L;

        tmp <<= 1;           // shift next bit into MSB..

        SCK_H;                   // Set SCK high..
//         ndelay(60);

        tmp |= MISO_STU;          // capture current MISO bit
        SCK_L;                   // ..then set SCK low again
//        ndelay(60);
    }
    return(tmp);                    // return read tmp
}


//鍑芥暟锛歶nsigned char SPI_Read(uint8 reg)
//鍔熻兘锛歂RF24L01鐨凷PI鏃跺簭
unsigned char SPI_Read(unsigned char reg)
{
        unsigned char reg_val;

        CSN_L;                // CSN low, initialize SPI communication...
//        ndelay(60);
        SPI_RW(reg);             // Select register to read from..
        reg_val = SPI_RW(0);     // ..then read registervalue
        CSN_H;               // CSN high, terminate SPI communication
//        ndelay(60);

        return(reg_val);           // return register value
}



//鍔熻兘锛歂RF24L01璇诲啓瀵勫瓨鍣ㄥ嚱鏁?
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
        unsigned char status;  

        CSN_L;                   // CSN low, init SPI transaction
//        ndelay(60);       
        status = SPI_RW(reg);      // select register
        SPI_RW(value);             // ..and write value to it..
        CSN_H;                   // CSN high again
//        ndelay(60);

        return(status);            // return nRF24L01 status uint8
}



//鍑芥暟锛歶nsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)
//鍔熻兘: 鐢ㄤ簬璇绘暟鎹紝reg锛氫负瀵勫瓨鍣ㄥ湴鍧€锛宲Buf锛氫负寰呰鍑烘暟鎹湴鍧€锛寀chars锛氳鍑烘暟鎹殑涓暟
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)
{
        unsigned char status,bit_ctr;

        CSN_L;                            // Set CSN low, init SPI tranaction
//        ndelay(60);
        status = SPI_RW(reg);               // Select register to write to and read status uint8

        for(bit_ctr=0;bit_ctr<uchars;bit_ctr++)
        {
                pBuf[bit_ctr] = SPI_RW(0);    //
//                ndelay(20);
           }
   
        CSN_H;
//        ndelay(60);
   
            return(status);                    // return nRF24L01 status uint8
}


//鍑芥暟锛歶nsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)
//鍔熻兘: 鐢ㄤ簬鍐欐暟鎹細涓哄瘎瀛樺櫒鍦板潃锛宲Buf锛氫负寰呭啓鍏ユ暟鎹湴鍧€锛寀chars锛氬啓鍏ユ暟鎹殑涓暟
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)
{
        unsigned char status,bit_ctr;

        CSN_L;            //SPI浣胯兘  
//        ndelay(60);
        status = SPI_RW(reg);   
        for(bit_ctr=0; bit_ctr<uchars; bit_ctr++) //
        {
                SPI_RW(*pBuf++);
                //ndelay(20);
        }
        CSN_H;           //鍏抽棴SPI
//        ndelay(60);
        return(status);    //
}


//鍑芥暟锛歷oid SetRX_Mode(void)
//鍔熻兘锛氭暟鎹帴鏀堕厤缃?
void SetRX_Mode(void)
{

        CE_L;
//        ndelay(60);
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);           // IRQ鏀跺彂瀹屾垚涓柇鍝嶅簲锛?6浣岰RC 锛屼富鎺ユ敹
        CE_H;
        udelay(130);
}



//鍑芥暟锛歶nsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
//鍔熻兘锛氭暟鎹鍙栧悗鏀惧rx_buf鎺ユ敹缂撳啿鍖轰腑
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
        unsigned char revale=0;
        sta = 0;
        sta=SPI_Read(STATUS);   // 璇诲彇鐘舵€佸瘎瀛樺叾鏉ュ垽鏂暟鎹帴鏀剁姸鍐?
        printk("sta is %d \n",sta);
        if(sta&0x40)     // 鍒ゆ柇鏄惁鎺ユ敹鍒版暟鎹?
        {
                CE_L;             //SPI浣胯兘
//                udelay(50);
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
                revale =1;          //璇诲彇鏁版嵁瀹屾垚鏍囧織
                printk("rx_buf is %s \n",rx_buf);
        }
        SPI_RW_Reg(WRITE_REG+STATUS,sta);   //鎺ユ敹鍒版暟鎹悗RX_DR,TX_DS,MAX_PT閮界疆楂樹负1锛岄€氳繃鍐?鏉ユ竻妤氫腑鏂爣蹇?
        return revale;
}


//鍑芥暟锛歷oid nRF24L01_TxPacket(unsigned char * tx_buf)
//鍔熻兘锛氬彂閫?tx_buf涓暟鎹?
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        CE_L;           //StandBy I妯″紡
//        ndelay(60);
        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 瑁呰浇鎺ユ敹绔湴鍧€
        SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);              // 瑁呰浇鏁版嵁
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);            // IRQ鏀跺彂瀹屾垚涓柇鍝嶅簲锛?6浣岰RC锛屼富鍙戦€?
        CE_H;        //缃珮CE锛屾縺鍙戞暟鎹彂閫?
        udelay(10);
}

//鏂囦欢鐨勫啓鍑芥暟
static ssize_t nrf24l01_write(struct file *filp, const char *buffer,
             size_t size, loff_t *ppos)
{
    if( copy_from_user( &TxBuf, buffer, size ) );    //浠庡唴鏍哥┖闂村鍒跺埌鐢ㄦ埛绌洪棿
    {
        printk("Can't Send Data !");
        return -EFAULT;
    }

    nRF24L01_TxPacket(TxBuf);
    SPI_RW_Reg(WRITE_REG+STATUS,0XFF);
    printk("OK! \n");
    return(0);
}

//鏂囦欢鐨勮鍑芥暟
static ssize_t nrf24l01_read(struct file *filp, char *buffer,
              size_t size, loff_t *ppos)
{
        int ret,t;
        unsigned char a,b;
            SetRX_Mode();

        mdelay(10);
            nRF24L01_RxPacket(RxBuf);
        a = RxBuf[1];
        b = RxBuf[2];
        printk("this is %d \n",a);
        printk("this is %d \n",b);
        t=b;
            t<<=8;
            t=t|a; //涓ゅ瓧鑺傚悎鎴愪竴涓暣鍨嬪彉閲忋€?
        mdelay(100);
        ret=copy_to_user(buffer,&t,size);                        //鐢卞唴鏍镐紶鍒扮敤鎴风┖闂?
        if(ret>0){
                return -EFAULT;       
        }
        return 0;
          
}

static int nrf24l01_open(struct inode *node, struct file *file)
{
       

        if(opencount == 1)
        return -EBUSY;
        init_NRF24L01();
        TxBuf[1] = 1;
        TxBuf[2] = 1;
        nRF24L01_TxPacket(TxBuf);        // Transmit Tx buffer data
       
        mdelay(100);
        if(flag == 0)
        {
                printk("unable to open device!\n");
                return -1;
        }
        else
        {
                opencount++;
                printk("device opened !\n");
                return 0;
        }
}

static int nrf24l01_release(struct inode *node, struct file *file)
{
        opencount--;
        printk(DEVICE_NAME " released !\n");
        return 0;
}

static struct file_operations nrf24l01_fops = {
        .owner = THIS_MODULE,
        .open = nrf24l01_open,
        .write = nrf24l01_write,
        .read = nrf24l01_read,
        .release = nrf24l01_release,
};

static int __init nrf24l01_init(void)
{
            int result;

            printk("Initial driver for NRF24L01......................\n");

            if(nrf24l01_major){
                dev = MKDEV(nrf24l01_major,nrf24l01_minor);
                result = register_chrdev_region(dev,NRF24L01_NR_DEVS,DEVICE_NAME);
        }else{
        result = alloc_chrdev_region(&dev,nrf24l01_minor,NRF24L01_NR_DEVS,DEVICE_NAME);
        nrf24l01_major = MAJOR(dev);
        }
        if(result<0){
                printk("nrf24l01:can't get major %d\n",nrf24l01_major);
                return result;
        }

        cdev_init(&nrf24l01,&nrf24l01_fops);
        nrf24l01.owner = THIS_MODULE;
        nrf24l01.ops = &nrf24l01_fops;

        cdev_add(&nrf24l01,dev,NRF24L01_NR_DEVS);       
        return 0;
   
}

static void __exit nrf24l01_exit(void)
{
        cdev_del(&nrf24l01);
        unregister_chrdev_region(NRF24L01_MAJOR,NRF24L01_NR_DEVS);
        printk("NRF24L01 DEVICE REMOVE!\n");
}


module_init(nrf24l01_init);
module_exit(nrf24l01_exit);
MODULE_AUTHOR("XX");
MODULE_DESCRIPTION("nrf24l01 driver for mini2440");
MODULE_LICENSE("GPL");

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 17:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表