linux 下的nrf24l01成功的驱动,模拟spi

7 篇文章 0 订阅
6 篇文章 0 订阅

刚刚接触到linux,有很多东西还不是很熟悉,希望大神指正。

前些日子做了一个项目远程家电控制系统,用的stm32f4;后面为了最求更高的境界,就前往学linux了,其中一万个坑呀。

就想到吧nrf24l01的驱动移植到linux上看行不,进过一段时间的尝试,成功了,虽然只是最简单的,没有用到中断,只是用到了模拟的spi,查询方式,不过至少是可行的。

总共有三个文件24l01.c 24l01.h my_nrf24l01_dev.c 

文件24l01.c

#include "24l01.h"

#include <asm/irq.h>

#include <mach/regs-gpio.h>

#include <linux/gpio.h>

#include <linux/delay.h>

#include <linux/kernel.h>

#define SPI_DELAY 1000

const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x02}; //send addr

const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //read addr

/**************************************************

Function: SPI_RW();



  Description:

  Writes one byte to nRF24L01, and return the byte read

  from nRF24L01 during write, according to SPI protocol

**************************************************/

u8 SPI_RW(u8 byte)

{

	u8 bit_ctr;

	for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit

	{

		MOSI((byte & 0x80)>>7);         // output 'byte', MSB to MOSI

		ndelay(SPI_DELAY);

		byte = (byte << 1);           // shift next bit into MSB..

		SCK(1);                      // Set SCK high..

		ndelay(SPI_DELAY);

		byte |= MISO;       		  // capture current MISO bit

		SCK(0);            		  // ..then set SCK low again

		ndelay(SPI_DELAY);

	}

   return(byte);           		  // return read byte

}

//init spi gpio

void NRF24L01_Init_Gpio(void){

	//init miso mosi sck cs ce irq for spi

	//miso ->> e.11

	//mosi ->> e.12

	//sck  ->> e.13

	//cs   ->> g.2

	//ce   ->> g.5

	//irq  ->> g.6

	//printk(KERN_DEBUG"init_nrf24l01_gpio");

	s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_INPUT);

	s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPIO_OUTPUT);

	s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_OUTPUT);

	s3c2410_gpio_cfgpin(S3C2410_GPG(2), S3C2410_GPIO_OUTPUT);

	s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_OUTPUT);

	s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPIO_INPUT);

	s3c2410_gpio_pullup(S3C2410_GPG(0),0);

	//s3c2410_gpio_pullup(S3C2410_GPE(12),1);	

	//s3c2410_gpio_pullup(S3C2410_GPE(13),1);

	//s3c2410_gpio_pullup(S3C2410_GPG(2),1);

	//s3c2410_gpio_pullup(S3C2410_GPG(6),1);

	//s3c2410_gpio_pullup(S3C2410_GPG(5),1);

	s3c2410_gpio_setpin(S3C2410_GPE(12), 0);

	s3c2410_gpio_setpin(S3C2410_GPE(13), 0);

	s3c2410_gpio_setpin(S3C2410_GPG(7), 0);

	s3c2410_gpio_setpin(S3C2410_GPG(5), 0);

}



void NRF24L01_Init(void)

{





	NRF24L01_Init_Gpio();

	NRF24L01_CE(0); 	

	NRF24L01_CSN(1);	

	mdelay(50);

	NRF24L01_RX_Mode();

}

//check nrf2401 	

u8 NRF24L01_Check(void)

{

	u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};

	u8 i; 

	NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//ÐŽÈë5žö×֜ڵĵØÖ·.	

	NRF24L01_Read_Buf(TX_ADDR,buf,5); //¶Á³öÐŽÈëµÄµØÖ·  

	for(i=0;i<5;i++)if(buf[i]!=0XA5)break;	 							   

	printk(KERN_DEBUG"i=%d\n",i);

	if(i!=5)return 1;//fail	

	return 0;	//suc

}	 	 

//SPIÐŽŒÄŽæÆ÷

//reg:Öž¶šŒÄŽæÆ÷µØÖ·

//value:ÐŽÈëµÄÖµ

u8 NRF24L01_Write_Reg(u8 reg,u8 value)

{

	u8 status;	

  NRF24L01_CSN(0);                 //ʹÄÜSPIŽ«Êä

  status =SPI_RW(reg);//·¢Ë͌ĎæÆ÷ºÅ 

  SPI_RW(value);      //ÐŽÈëŒÄŽæÆ÷µÄÖµ

  NRF24L01_CSN(1);                 //œûÖ¹SPIŽ«Êä	   

  return(status);       			//·µ»Ø׎ֵ̬

}

//¶ÁÈ¡SPIŒÄŽæÆ÷Öµ

//reg:Òª¶ÁµÄŒÄŽæÆ÷

u8 NRF24L01_Read_Reg(u8 reg)

{

	u8 reg_val;	    

  NRF24L01_CSN(0);          //ʹÄÜSPIŽ«Êä		

  SPI_RW(reg);   //·¢Ë͌ĎæÆ÷ºÅ

  reg_val=SPI_RW(0XFF);//¶ÁÈ¡ŒÄŽæÆ÷ÄÚÈÝ

  NRF24L01_CSN(1);          //œûÖ¹SPIŽ«Êä		    

  return(reg_val);           //·µ»Ø׎ֵ̬

}	

//ÔÚÖž¶šÎ»ÖöÁ³öÖž¶š³€¶ÈµÄÊýŸÝ

//reg:ŒÄŽæÆ÷(λÖÃ)

//*pBuf:ÊýŸÝÖžÕë

//len:ÊýŸÝ³€¶È

//·µ»ØÖµ,ŽËŽÎ¶ÁµœµÄ׎̬ŒÄŽæÆ÷Öµ 

u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)

{

  u8 status,u8_ctr;	       

  NRF24L01_CSN(0);           //ʹÄÜSPIŽ«Êä

  status=SPI_RW(reg);//·¢Ë͌ĎæÆ÷Öµ(λÖÃ),²¢¶Áȡ׎ֵ̬   	   

  for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPI_RW(0XFF);//¶Á³öÊýŸÝ

  NRF24L01_CSN(1);       //¹Ø±ÕSPIŽ«Êä

  return status;        //·µ»Ø¶ÁµœµÄ׎ֵ̬

}

//ÔÚÖž¶šÎ»ÖÃÐŽÖž¶š³€¶ÈµÄÊýŸÝ

//reg:ŒÄŽæÆ÷(λÖÃ)

//*pBuf:ÊýŸÝÖžÕë

//len:ÊýŸÝ³€¶È

//·µ»ØÖµ,ŽËŽÎ¶ÁµœµÄ׎̬ŒÄŽæÆ÷Öµ

u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)

{

  u8 status,u8_ctr;	    

  NRF24L01_CSN(0);          //ʹÄÜSPIŽ«Êä

  status = SPI_RW(reg);//·¢Ë͌ĎæÆ÷Öµ(λÖÃ),²¢¶Áȡ׎ֵ̬

  for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI_RW(*pBuf++); //ÐŽÈëÊýŸÝ	 

  NRF24L01_CSN(1);       //¹Ø±ÕSPIŽ«Êä

  return status;          //·µ»Ø¶ÁµœµÄ׎ֵ̬

}				   

//Æô¶¯NRF24L01·¢ËÍÒ»ŽÎÊýŸÝ

//txbuf:Žý·¢ËÍÊýŸÝÊ×µØÖ·

//·µ»ØÖµ:·¢ËÍÍê³É׎¿ö

#include <linux/time.h>

u8 NRF24L01_TxPacket(u8 *txbuf)

{

	u8 sta;

	u8 i=0;

 	//SPIHighSpeed(SPI_BaudRatePrescaler_256);//spiËÙ¶ÈΪ10.5Mhz£š24L01µÄ×îŽóSPIʱÖÓΪ10Mhz£©   

	NRF24L01_CE(0);

  NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//ÐŽÊýŸÝµœTX BUF  32žö×ÖœÚ

 	NRF24L01_CE(1);//Æô¶¯·¢ËÍ

	//printk(KERN_DEBUG"send data");	   

	while(NRF24L01_IRQ!=0&&(i<50)){i++;};//µÈŽý·¢ËÍÍê³É

	sta=NRF24L01_Read_Reg(STATUS);  //¶Áȡ׎̬ŒÄŽæÆ÷µÄÖµ	   

	NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //Çå³ýTX_DS»òMAX_RTÖжϱêÖŸ

	if(sta&MAX_TX)//Žïµœ×îŽóÖØ·¢ŽÎÊý

	{

		NRF24L01_Write_Reg(FLUSH_TX,0xff);//Çå³ýTX FIFOŒÄŽæÆ÷ 

		return MAX_TX; 

	}

	if(sta&TX_OK)//·¢ËÍÍê³É

	{

		return TX_OK;

	}

	return 0xff;//ÆäËûÔ­Òò·¢ËÍʧ°Ü

}

//Æô¶¯NRF24L01·¢ËÍÒ»ŽÎÊýŸÝ

//txbuf:Žý·¢ËÍÊýŸÝÊ×µØÖ·

//·µ»ØÖµ:0£¬œÓÊÕÍê³É£»ÆäËû£¬ŽíÎóŽúÂë

u8 NRF24L01_RxPacket(u8 *rxbuf)

{

	u8 sta;		    							   

	//SPIHighSpeed(SPI_BaudRatePrescaler_256); //spiËÙ¶ÈΪ10.5Mhz£š24L01µÄ×îŽóSPIʱÖÓΪ10Mhz£©   

	sta=NRF24L01_Read_Reg(STATUS);  //¶Áȡ׎̬ŒÄŽæÆ÷µÄÖµ    	 

	NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //Çå³ýTX_DS»òMAX_RTÖжϱêÖŸ

	if(sta&RX_OK)//œÓÊÕµœÊýŸÝ

	{

		NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//¶ÁÈ¡ÊýŸÝ

		NRF24L01_Write_Reg(FLUSH_RX,0xff);//Çå³ýRX FIFOŒÄŽæÆ÷ 

		return 0; 

	}	   

	return 1;//ûÊÕµœÈκÎÊýŸÝ

}					    

//žÃº¯Êý³õÊŒ»¯NRF24L01µœRXģʜ

//ÉèÖÃRXµØÖ·,ÐŽRXÊýŸÝ¿í¶È,Ñ¡ÔñRFƵµÀ,²šÌØÂʺÍLNA HCURR

//µ±CE±äžßºó,ŒŽœøÈëRXģʜ,²¢¿ÉÒÔœÓÊÕÊýŸÝÁË		   

void NRF24L01_RX_Mode(void)

{

  NRF24L01_CE(0);	  

  NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//ÐŽRXœÚµãµØÖ·

	  

  NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);    //ʹÄÜÍšµÀ0µÄ×Ô¶¯ÓŠŽð    

  NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//ʹÄÜÍšµÀ0µÄœÓÊÕµØÖ·  	 

  NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);	     //ÉèÖÃRFÍšÐÅƵÂÊ		  

  NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//Ñ¡ÔñÍšµÀ0µÄÓÐЧÊýŸÝ¿í¶È 	    

  NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//ÉèÖÃTX·¢Éä²ÎÊý,0dbÔöÒæ,2Mbps,µÍÔëÉùÔöÒ濪Æô   

  NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//ÅäÖûù±Ÿ¹€×÷ģʜµÄ²ÎÊý;PWR_UP,EN_CRC,16BIT_CRC,œÓÊÕģʜ 

  NRF24L01_CE(1); //CEΪžß,œøÈëœÓÊÕģʜ 

}						 

//žÃº¯Êý³õÊŒ»¯NRF24L01µœTXģʜ

//ÉèÖÃTXµØÖ·,ÐŽTXÊýŸÝ¿í¶È,ÉèÖÃRX×Ô¶¯ÓŠŽðµÄµØÖ·,Ìî³äTX·¢ËÍÊýŸÝ,Ñ¡ÔñRFƵµÀ,²šÌØÂʺÍLNA HCURR

//PWR_UP,CRCʹÄÜ

//µ±CE±äžßºó,ŒŽœøÈëRXģʜ,²¢¿ÉÒÔœÓÊÕÊýŸÝÁË		   

//CEΪžßŽóÓÚ10us,ÔòÆô¶¯·¢ËÍ.	 

void NRF24L01_TX_Mode(void)

{														 

  NRF24L01_CE(0);	    

  NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//ÐŽTXœÚµãµØÖ· 

  NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //ÉèÖÃTXœÚµãµØÖ·,Ö÷ҪΪÁËʹÄÜACK	  



  NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //ʹÄÜÍšµÀ0µÄ×Ô¶¯ÓŠŽð    

  NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //ʹÄÜÍšµÀ0µÄœÓÊÕµØÖ·  

  NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//ÉèÖÃ×Ô¶¯ÖØ·¢ŒäžôʱŒä:500us + 86us;×îŽó×Ô¶¯ÖØ·¢ŽÎÊý:10ŽÎ

  NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);       //ÉèÖÃRFÍšµÀΪ40

  NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);  //ÉèÖÃTX·¢Éä²ÎÊý,0dbÔöÒæ,2Mbps,µÍÔëÉùÔöÒ濪Æô   

  NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);    //ÅäÖûù±Ÿ¹€×÷ģʜµÄ²ÎÊý;PWR_UP,EN_CRC,16BIT_CRC,œÓÊÕģʜ,¿ªÆôËùÓÐÖжÏ

  NRF24L01_CE(1);//CEΪžß,10usºóÆô¶¯·¢ËÍ

}



u8 NRF24L01_SEND_Data(u8 *data){

	u8 result;

	NRF24L01_TX_Mode();

	result=NRF24L01_TxPacket((u8*)data);

	NRF24L01_RX_Mode();

	return result;

}





















文件24l01.h

#ifndef __24L01_H

#define __24L01_H	 

#ifdef __cplusplus

 extern "C" {

#endif /* __cplusplus */

#include <asm/irq.h>

#include <mach/regs-gpio.h>

#include <linux/gpio.h>

#include <linux/delay.h>

//

//NRF24L01ŒÄŽæÆ÷²Ù×÷ÃüÁî

#define NRF_READ_REG    0x00  //¶ÁÅäÖÌĎæÆ÷,µÍ5λΪŒÄŽæÆ÷µØÖ·

#define NRF_WRITE_REG   0x20  //ÐŽÅäÖÌĎæÆ÷,µÍ5λΪŒÄŽæÆ÷µØÖ·

#define RD_RX_PLOAD     0x61  //¶ÁRXÓÐЧÊýŸÝ,1~32×ÖœÚ

#define WR_TX_PLOAD     0xA0  //ÐŽTXÓÐЧÊýŸÝ,1~32×ÖœÚ

#define FLUSH_TX        0xE1  //Çå³ýTX FIFOŒÄŽæÆ÷.·¢ÉäģʜÏÂÓÃ

#define FLUSH_RX        0xE2  //Çå³ýRX FIFOŒÄŽæÆ÷.œÓÊÕģʜÏÂÓÃ

#define REUSE_TX_PL     0xE3  //ÖØÐÂʹÓÃÉÏÒ»°üÊýŸÝ,CEΪžß,ÊýŸÝ°ü±»²»¶Ï·¢ËÍ.

#define NOP             0xFF  //¿Õ²Ù×÷,¿ÉÒÔÓÃÀŽ¶Á׎̬ŒÄŽæÆ÷	 

//SPI(NRF24L01)ŒÄŽæÆ÷µØÖ·

#define CONFIG          0x00  //ÅäÖÌĎæÆ÷µØÖ·;bit0:1œÓÊÕģʜ,0·¢Éäģʜ;bit1:µçÑ¡Ôñ;bit2:CRCģʜ;bit3:CRCʹÄÜ;

                              //bit4:ÖжÏMAX_RT(Žïµœ×îŽóÖØ·¢ŽÎÊýÖжÏ)ʹÄÜ;bit5:ÖжÏTX_DSʹÄÜ;bit6:ÖжÏRX_DRʹÄÜ

#define EN_AA           0x01  //ʹÄÜ×Ô¶¯ÓŠŽð¹ŠÄÜ  bit0~5,¶ÔÓŠÍšµÀ0~5

#define EN_RXADDR       0x02  //œÓÊÕµØÖ·ÔÊÐí,bit0~5,¶ÔÓŠÍšµÀ0~5

#define SETUP_AW        0x03  //ÉèÖõØÖ·¿í¶È(ËùÓÐÊýŸÝÍšµÀ):bit1,0:00,3×ÖœÚ;01,4×ÖœÚ;02,5×ÖœÚ;

#define SETUP_RETR      0x04  //œšÁ¢×Ô¶¯ÖØ·¢;bit3:0,×Ô¶¯ÖØ·¢ŒÆÊýÆ÷;bit7:4,×Ô¶¯ÖØ·¢ÑÓʱ 250*x+86us

#define RF_CH           0x05  //RFÍšµÀ,bit6:0,¹€×÷ÍšµÀƵÂÊ;

#define RF_SETUP        0x06  //RFŒÄŽæÆ÷;bit3:Ž«ÊäËÙÂÊ(0:1Mbps,1:2Mbps);bit2:1,·¢É乊ÂÊ;bit0:µÍÔëÉù·ÅŽóÆ÷ÔöÒæ

#define STATUS          0x07  //׎̬ŒÄŽæÆ÷;bit0:TX FIFOÂú±êÖŸ;bit3:1,œÓÊÕÊýŸÝÍšµÀºÅ(×îŽó:6);bit4,Žïµœ×î¶àŽÎÖØ·¢

                              //bit5:ÊýŸÝ·¢ËÍÍê³ÉÖжÏ;bit6:œÓÊÕÊýŸÝÖжÏ;

#define MAX_TX  		0x10  //Žïµœ×îŽó·¢ËÍŽÎÊýÖжÏ

#define TX_OK   		0x20  //TX·¢ËÍÍê³ÉÖжÏ

#define RX_OK   		0x40  //œÓÊÕµœÊýŸÝÖжÏ



#define OBSERVE_TX      0x08  //·¢ËÍŒì²âŒÄŽæÆ÷,bit7:4,ÊýŸÝ°ü¶ªÊ§ŒÆÊýÆ÷;bit3:0,ÖØ·¢ŒÆÊýÆ÷

#define CD              0x09  //ÔزšŒì²âŒÄŽæÆ÷,bit0,ÔزšŒì²â;

#define RX_ADDR_P0      0x0A  //ÊýŸÝÍšµÀ0œÓÊÕµØÖ·,×îŽó³€¶È5žö×ÖœÚ,µÍ×ÖœÚÔÚÇ°

#define RX_ADDR_P1      0x0B  //ÊýŸÝÍšµÀ1œÓÊÕµØÖ·,×îŽó³€¶È5žö×ÖœÚ,µÍ×ÖœÚÔÚÇ°

#define RX_ADDR_P2      0x0C  //ÊýŸÝÍšµÀ2œÓÊÕµØÖ·,×îµÍ×֜ڿÉÉèÖÃ,žß×ÖœÚ,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;

#define RX_ADDR_P3      0x0D  //ÊýŸÝÍšµÀ3œÓÊÕµØÖ·,×îµÍ×֜ڿÉÉèÖÃ,žß×ÖœÚ,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;

#define RX_ADDR_P4      0x0E  //ÊýŸÝÍšµÀ4œÓÊÕµØÖ·,×îµÍ×֜ڿÉÉèÖÃ,žß×ÖœÚ,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;

#define RX_ADDR_P5      0x0F  //ÊýŸÝÍšµÀ5œÓÊÕµØÖ·,×îµÍ×֜ڿÉÉèÖÃ,žß×ÖœÚ,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;

#define TX_ADDR         0x10  //·¢Ë͵ØÖ·(µÍ×ÖœÚÔÚÇ°),ShockBurstTMģʜÏÂ,RX_ADDR_P0ÓëŽËµØÖ·ÏàµÈ

#define RX_PW_P0        0x11  //œÓÊÕÊýŸÝÍšµÀ0ÓÐЧÊýŸÝ¿í¶È(1~32×ÖœÚ),ÉèÖÃΪ0Ôò·Ç·š

#define RX_PW_P1        0x12  //œÓÊÕÊýŸÝÍšµÀ1ÓÐЧÊýŸÝ¿í¶È(1~32×ÖœÚ),ÉèÖÃΪ0Ôò·Ç·š

#define RX_PW_P2        0x13  //œÓÊÕÊýŸÝÍšµÀ2ÓÐЧÊýŸÝ¿í¶È(1~32×ÖœÚ),ÉèÖÃΪ0Ôò·Ç·š

#define RX_PW_P3        0x14  //œÓÊÕÊýŸÝÍšµÀ3ÓÐЧÊýŸÝ¿í¶È(1~32×ÖœÚ),ÉèÖÃΪ0Ôò·Ç·š

#define RX_PW_P4        0x15  //œÓÊÕÊýŸÝÍšµÀ4ÓÐЧÊýŸÝ¿í¶È(1~32×ÖœÚ),ÉèÖÃΪ0Ôò·Ç·š

#define RX_PW_P5        0x16  //œÓÊÕÊýŸÝÍšµÀ5ÓÐЧÊýŸÝ¿í¶È(1~32×ÖœÚ),ÉèÖÃΪ0Ôò·Ç·š

#define NRF_FIFO_STATUS 0x17  //FIFO׎̬ŒÄŽæÆ÷;bit0,RX FIFOŒÄŽæÆ÷¿Õ±êÖŸ;bit1,RX FIFOÂú±êÖŸ;bit2,3,±£Áô

                              //bit4,TX FIFO¿Õ±êÖŸ;bit5,TX FIFOÂú±êÖŸ;bit6,1,Ñ­»··¢ËÍÉÏÒ»ÊýŸÝ°ü.0,²»Ñ­»·;

//

//

#define NRF24L01_CE(a)   s3c2410_gpio_setpin(S3C2410_GPG(5), (a)) //

#define NRF24L01_CSN(a)  s3c2410_gpio_setpin(S3C2410_GPG(2), (a))//	   

#define NRF24L01_IRQ  	 s3c2410_gpio_getpin(S3C2410_GPG(6)) //

#define MISO 	s3c2410_gpio_getpin(S3C2410_GPG(0))

#define MOSI(a) s3c2410_gpio_setpin(S3C2410_GPE(12), (a))

#define SCK(a)  s3c2410_gpio_setpin(S3C2410_GPE(13), (a))



//24L01·¢ËÍœÓÊÕÊýŸÝ¿í¶È¶šÒå

#define TX_ADR_WIDTH    5   //5×֜ڵĵØÖ·¿í¶È

#define RX_ADR_WIDTH    5   //5×֜ڵĵØÖ·¿í¶È

#define TX_PLOAD_WIDTH  32  //20×֜ڵÄÓû§ÊýŸÝ¿í¶È

#define RX_PLOAD_WIDTH  32  //20×֜ڵÄÓû§ÊýŸÝ¿í¶È

									   	   



void NRF24L01_Init(void);//³õÊŒ»¯

void NRF24L01_RX_Mode(void);//ÅäÖÃΪœÓÊÕģʜ

void NRF24L01_TX_Mode(void);//ÅäÖÃΪ·¢ËÍģʜ

u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s);//ÐŽÊýŸÝÇø

u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s);//¶ÁÊýŸÝÇø		  

u8 NRF24L01_Read_Reg(u8 reg);			//¶ÁŒÄŽæÆ÷

u8 NRF24L01_Write_Reg(u8 reg, u8 value);//ÐŽŒÄŽæÆ÷

u8 NRF24L01_Check(void);//Œì²é24L01ÊÇ·ñŽæÔÚ

u8 NRF24L01_TxPacket(u8 *txbuf);//·¢ËÍÒ»žö°üµÄÊýŸÝ

u8 NRF24L01_RxPacket(u8 *rxbuf);//œÓÊÕÒ»žö°üµÄÊýŸÝ

u8 NRF24L01_SEND_Data(u8 *data);

// USER START (Optionally insert additional static code)

// USER END



#ifdef __cplusplus

}

#endif /* __cplusplus */

#endif




















文件my_nrf24l01_dev.c 驱动文件

#include <linux/miscdevice.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.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 <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include "24l01.h"
u8 nrf24l01_buffer[32]={0};
const  char *MY_DEVICE_NAME="nrf24l01_dev";
static int sbc2440_nrf24l01_ioctl(
	struct inode *inode, 
	struct file *file, 
	unsigned int cmd, 
	unsigned long arg){
	printk(KERN_DEBUG"ioctl");
	//nrf24l01 cs enable or disable
	s3c2410_gpio_setpin(S3C2410_GPG(2), cmd);

	return 0;
} 
static int my_open(struct inode *id,struct file* filp){
	char flag=0;
	NRF24L01_Init();
	mdelay(50);
	try_module_get(THIS_MODULE);
	flag=NRF24L01_Check();
	// flag for 1 fail 
	if(flag==1){
		return -1;
	}
	return 0;
}
static int my_release(struct inode *id ,struct file* filp){
	module_put(THIS_MODULE);
	return 0;
}
static ssize_t my_read(struct file *mfile ,char __user *user,size_t t,
loff_t *f){
	NRF24L01_RX_Mode();
	if(NRF24L01_RxPacket(nrf24l01_buffer)==1){
		return -EFAULT;
	}
	if(copy_to_user(user,nrf24l01_buffer,32)){
		return -EFAULT;
	}
	return sizeof(nrf24l01_buffer);
}
static ssize_t my_write(struct file *mfile,const char __user *user,
size_t t,loff_t *f){
	int result;
	char data[32]={0};
//	printk(KERN_DEBUG"write..");
	//copy_from_user(data,user,32);
	
	NRF24L01_TX_Mode();
	result=NRF24L01_TxPacket((u8*)user);
	ndelay(20);
	if(result==1){
		return -EFAULT;
	}
	return sizeof(nrf24l01_buffer);
}
static struct file_operations dev_fops = {
	.owner	=	THIS_MODULE,
	.ioctl	=	sbc2440_nrf24l01_ioctl,
	.read	=	my_read,
	.write	=	my_write,
	.open	=	my_open,
	.release=	my_release,
};

static struct miscdevice misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "my_nrf24l01",
	.fops = &dev_fops,
};
static int __init dev_init(void){
	int ret;
	printk(KERN_DEBUG"init..");
	NRF24L01_Init(); 
	ret = misc_register(&misc);
	return ret;
}
static void  __exit dev_exit(void){
	misc_deregister(&misc);
}



module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lotoohe Inc.");

在Kconfig中的配置,直接编译成为驱动模块

利用insmod命令加载模块:insmod my_nrf24l01_dev.ko

利用rmmod 命令卸载模块:rmmod my_nrf24l01_dev

config MINI2440_LOT_NRF24L01
	tristate "NRF24L01 drvier for lotoohe mini2440 development boards"
	depends on MACH_MINI2440
	default y if MACH_MINI2440
	help
	  this is NRF24L01 drvier for lotoohe mini2440 devlopment boards


Makefile中编译文件的配置:

obj-$(CONFIG_MINI2440_LOT_NRF24L01) += my_nrf24l01.o

my_nrf24l01-objs = 24l01.o my_nrf24l01_dev.o


这只是一个最简单的版本,希望大家指正,我已经测试过能够正常使用。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值