📄 rf24l01.c
字号:
//-----------------------------------------------------------------------------
//
// Drive_24L01.c
//
//-----------------------------------------------------------------------------
#include "rf24l01.h"
//-----------------------------------------------------------------------------
//
// 各种全局变量定义
//
//-----------------------------------------------------------------------------
idata unsigned char radio_status;
static unsigned char gnDataPipeNumber;
//**********************************************************//
//
// Function: Rf24L01_Reg_RW
//
// Description:
// Writes one byte to nRF24L01, and return the byte read
// from nRF24L01 during write, according to SPI protocol
//
// In/Out parameters:
// In: 'byte', current byte to be written
// Out: 'SPI0DAT', HW SPI mode, 'byte' SW SPI mode,
//
//**********************************************************//
// Spi函数
static unsigned char Rf24L01_Reg_RW(unsigned char byte)
{
return 0;
}
//-----------------------------------------------------------------------------
//
// Function: Rf24L01_WriteByte
//
// Description:
// Writes value 'value' to register 'reg'
//
//
// In/Out parameters:
// In: 'reg' register to write value 'value' to.
// Return status byte.
//
//-----------------------------------------------------------------------------
unsigned char Rf24L01_WriteByte(unsigned char reg, unsigned char value)
{
unsigned char status;
CSN_LOW();
status = Rf24L01_Reg_RW(reg); // select register
Rf24L01_Reg_RW(value); // ..and write value to it..
CSN_HIGH();
return(status); // return nRF24L01 status byte
}
//-----------------------------------------------------------------------------
//
// Function: Rf24L01_WriteMultiByte
//
// Description:
// Writes contents of buffer '*pBuf' to nRF24L01
// Typically used to write TX payload, Rx/Tx address
//
//
// In/Out parameters:
// In: register 'reg' to write, buffer '*pBuf*' contains
// data to be written and buffer size 'buf_size' is #of
// bytes to be written
// Out: return nRF24L01 status byte.
//
//-----------------------------------------------------------------------------
unsigned char Rf24L01_WriteMultiByte(unsigned char reg, unsigned char *pBuf, unsigned char len)
{
unsigned char status,i;
CSN_LOW();
status = Rf24L01_Reg_RW(reg); // Select register to write to and read status byte
for(i=0; i<len; i++) // then write all byte in buffer(*pBuf)
{
Rf24L01_Reg_RW(*pBuf++);
}
CSN_HIGH();
return(status); // return nRF24L01 status byte
}
//-----------------------------------------------------------------------------
//
// Clear nRF24L01 IRQ flag(s)
//
//-----------------------------------------------------------------------------
unsigned char Rf24L01_Clear_IRQ(unsigned char irq_flag)
{
return Rf24L01_WriteByte(WRITE_REG + STATUS, irq_flag);
}
//-----------------------------------------------------------------------------
//
// Flush TX FIFO
//
//-----------------------------------------------------------------------------
void Rf24L01_Flush_TX(void)
{
Rf24L01_WriteByte(FLUSH_TX,0);
}
//-----------------------------------------------------------------------------
//
// Flush RX FIFO
//
//-----------------------------------------------------------------------------
void Rf24L01_Flush_RX(void)
{
Rf24L01_WriteByte(FLUSH_RX,0);
}
//**********************************************************//
//
// Function: Rf24L01_ReadByte
//
// Description:
// Read one byte from nRF24L01 register, 'reg'
//
//
// In/Out parameters:
// In: reg, register to read
// Out: return reg_val, register value.
//
//**********************************************************//
unsigned char Rf24L01_ReadByte(unsigned char reg)
{
unsigned char reg_val;
CSN_LOW();
Rf24L01_Reg_RW(reg); // Select register to read from..
reg_val = Rf24L01_Reg_RW(0); // ..then read registervalue
CSN_HIGH();
return(reg_val); // return register value
}
//-----------------------------------------------------------------------------
//
// switch PTX/PRX
//
//-----------------------------------------------------------------------------
void Rf24L01_RxTx_Switch(unsigned char bMode)
{
unsigned char bConfig;
CE_LOW();
Rf24L01_Flush_RX(); //set TX/RX FIFO to be empty
Rf24L01_Flush_TX(); //
Rf24L01_Clear_IRQ(MASK_IRQ_FLAGS); //clear IRQ STATUS register
bConfig = Rf24L01_ReadByte(CONFIG);
if(bMode == PRX)
{
if((bConfig&0x01))
{
CE_HIGH();
return;
}
bConfig &= 0xfe;
bConfig |= 0x01;
Rf24L01_WriteByte(WRITE_REG + CONFIG, bConfig);
CE_HIGH();
}
else if(bMode == PTX)
{
if(!(bConfig&0x01))
{
return;
}
bConfig &= 0xfe;
Rf24L01_WriteByte(WRITE_REG + CONFIG, bConfig);
}
}
//**********************************************************//
//
// Function: Rf24L01_ReadMultiByte
//
// Description:
// Reads 'bytes' #of bytes from register 'reg'
// Typically used to read RX payload, Rx/Tx address
//
//
// In/Out parameters:
// In: 'reg', register to read from, '*pBuf' are buffer
// the read bytes are stored to and 'bytes' are #of bytes
// to read.
// Out: return nRF24L01 status byte.
//
//**********************************************************//
static unsigned char Rf24L01_ReadMultiByte(unsigned char reg, unsigned char *pBuf, unsigned char len)
{
unsigned char status,i;
CSN_LOW();
status = Rf24L01_Reg_RW(reg); // Select register to write to and read status byte
for (i=0;i<len;i++)
{
pBuf[i] = Rf24L01_Reg_RW(0); // Perform Rf24L01_Reg_RW to read byte from nRF24L01
}
CSN_HIGH();
return(status); // return nRF24L01 status byte
}
//-----------------------------------------------------------------------------
//
// Used in RX mode.
//
//-----------------------------------------------------------------------------
static void Rf24L01_RX(unsigned char *prx_buf)
{
unsigned char gnRF_RecvLen;
gnRF_RecvLen=Rf24L01_ReadByte(READ_PAYLAODLEN);
if (prx_buf != NULL) Rf24L01_ReadMultiByte(RD_RX_PLOAD, prx_buf, gnRF_RecvLen);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Rf24L01_TX(unsigned char *ptx_buf,unsigned char nLen)
{
Rf24L01_RxTx_Switch(PTX);
Rf24L01_Flush_TX(); //clear 24L01 tx buffer
Rf24L01_WriteMultiByte(WR_TX_PLOAD, ptx_buf, nLen);
CE_PULSE();
}
//-----------------------------------------------------------------------------
//
// Function: Rf24L01_Polling_IRQ
//
// Description:
// Deal with IQR event with polling mode
//
//-----------------------------------------------------------------------------
static void rf_rdy_ov_interrupt(void) interrupt INTERRUPT_RFRDY {}
//---------------------------------------------------------------------------
static void rfirq_ov_interrupt(void) interrupt INTERRUPT_RFIRQ
{
radio_status =0xFF;
}
//---------------------------------------------------------------------------
unsigned char Rf24L01_Polling_IRQ(unsigned char * rev_buf)
{
unsigned char irq_status;
if(radio_status == 0x00)
{
if(Rf24L01_ReadByte(FIFO_STATUS) & MASK_RX_EMPTY) return IDLE;
Rf24L01_RX(rev_buf);
irq_status=Rf24L01_ReadByte(STATUS);
gnDataPipeNumber=(irq_status>>1)&0x7;
return (unsigned char)RX_DR;
}
radio_status = 0x00;
irq_status=Rf24L01_ReadByte(STATUS);
switch(irq_status&MASK_IRQ_FLAGS)
{
case MASK_RX_DR_FLAG: //rf receive data
{
if(Rf24L01_ReadByte(FIFO_STATUS) & MASK_RX_EMPTY)
{
irq_status =IDLE;
}
else
{
Rf24L01_RX(rev_buf);
gnDataPipeNumber=(irq_status>>1)&0x7;
irq_status = (unsigned char)RX_DR;
}
break;
}
case MASK_TX_DS_FLAG: //send rf data success (with ack response)
{
irq_status = (unsigned char)TX_DS;
break;
}
case MASK_MAX_RT_FLAG: //Maximum number of TX retries interrupt If MAX_RT is set it must be cleared to enable further communication.
{
irq_status = (unsigned char)MAX_RT;
break;
}
case IDLE:
{
irq_status = (unsigned char)IDLE;
break;
}
}
if(Rf24L01_ReadByte(FIFO_STATUS) & MASK_RX_EMPTY)
Rf24L01_Clear_IRQ(MASK_IRQ_FLAGS);
return irq_status;
}
//-----------------------------------------------------------------------------
unsigned char Rf24L01_Set_Init(SetupData *drc)
{
unsigned char btemp;
RFCKEN = 1; // enable L01 clock
RF = 0;
CE_LOW();
Rf24L01_Flush_RX(); //flush TX/RX FIFO to be empty
Rf24L01_Flush_TX(); //
Rf24L01_Clear_IRQ(MASK_IRQ_FLAGS); //clear IRQ STATUS register
//------------------------------------------------------
//1 set config
//------------------------------------------------------
//'comm config' default value:0000 1000
//bit7 must be 0;
//bit6,0--enable,RX interrupt enable,IRQ pin active low
//bit5,0--enable TX Succeed interrupt enable,IRQ pin active low
//bit4,0--eanble TX time over interrupt enable,IRQ pin active low
//bit3,CRC enable,if EN_AA be set,this bit will be forced to high
//bit2,CRC width,0--one byte,1--two bytes
//bit1,RF POWER ON/OFF,1--ON, 0--OFF
//bit0,transmmit mode: 1--PTX,0--PRX
btemp =0x0e;
if (drc->nOn == Dev_Normal) btemp +=0x01;
Rf24L01_WriteByte(WRITE_REG + CONFIG, btemp);
//------------------------------------------------------
//2 set ee_aa
//------------------------------------------------------
//'Enable Auto Acknowledgment'
// bit76 must be 00;
// bit 5-0 response to Pip5-0; bit: 1-en, 0-disen
// bit0 = 1;only enble pipe0
// Enable Auto.Ack:Pipe0
Rf24L01_WriteByte(WRITE_REG + EN_AA, drc->nAutoAck);
//------------------------------------------------------
//3 set en_rxaddr
//------------------------------------------------------
//'Enabled RX addresses', default 0000 0011
//bit76 must be 00;
//bit 5-0 response to Pip5-0, bit: 1-en, 0-disen
//pipe rx enble,bit0 = 1,only enable pipe0 RX
Rf24L01_WriteByte(WRITE_REG + EN_RXADDR, drc->nRecvAddr);
//------------------------------------------------------
//4 set setup_aw
//------------------------------------------------------
//'address width',default 0000 0011
//bit765432 must be 000000;
//bit10,value must be 1~3, 1--3Bytes width,2--4Bytes,3--5Bytes
//address width is 5 bytes;bit10: 00--illegal,01--3bytes,10--4bytes,11--5bytes
Rf24L01_WriteByte(WRITE_REG + SETUP_AW, 0x03);
//------------------------------------------------------
//5 set setup_retr
//------------------------------------------------------
//'Auto. Retransmite delay time and count', default 0000 0011
//delay time(bit7~3):(bit7~3+1)*250+86us;
//retran count(bit2~0):0--disenable retran,otherwise 1~15 times
//0x10;
//retran delay time:250us+86us
//drc->Retran;
btemp = (drc->nART_Factor&0x0f)<<4;
btemp += (drc->nRetran > 15 ? 15 : drc->nRetran);
Rf24L01_WriteByte(WRITE_REG + SETUP_RETR, btemp);
//------------------------------------------------------
//6 set rf_ch
//------------------------------------------------------
//'rf frequency channel' 2400+rf_ch,default:0000 0010
// bit7 must be 0
// bit6~0 rf frequency channel,one step deputy 1MHZ
// we use frequency at less than 2.49GHZ,beause WLAN use frequency band 2.4G~2.4835Ghz
// we choice rf_ch = 100; thats 2.5GHZ
// default we choice frequency range 2.495GHz~2.513GHZ channel
if (drc->nChannel>122)
{
drc->nChannel = 0;
}
Rf24L01_WriteByte(WRITE_REG + RF_CH, drc->nChannel);
//------------------------------------------------------
//7 set rf_setup
//------------------------------------------------------
//'RF setup' default 0000 1111
// bit7~4 must be 00000
// bit 3 data rate :0--1Mbps,1--2Mbps;
// bit 2~1 rf power:00,-18dbm,,01,-12dbm,,10,-6dbm,,11,0dbm
// bit 0 must be 1
btemp =((drc->nPower&0x0f)>3 ? 3:(drc->nPower&0x0f))<<1;
btemp +=0x01;
if((drc->nPower&0xf0)>0) btemp += 0x08;
//btemp |= 0x20;
Rf24L01_WriteByte(WRITE_REG + RF_SETUP, btemp);
//------------------------------------------------------
//8 set rx_addr_p0
//------------------------------------------------------
//pipe0 rx address buf
Rf24L01_WriteMultiByte(WRITE_REG + RX_ADDR_P0,drc->aAddr1,5);
//------------------------------------------------------
//9 set rx_addr_p1
//------------------------------------------------------
//'pipe1 rx payload width'
//'pipe0 rx payload width' 0000 0000
//bit76 must be 00
//bit5~0,at less than must be one byte
//the most width is 32 bytes
if (drc->nLen>32)
{
drc->nLen = 32;
}
else if (drc->nLen == 0)
{
drc->nLen = 1;
}
Rf24L01_WriteByte(WRITE_REG + RX_PW_P0, drc->nLen);
btemp = drc->nRecvAddr;
btemp = btemp>>1;
if (btemp&1)
{
//81 get rx_addr_p1
Rf24L01_WriteMultiByte(WRITE_REG + RX_ADDR_P1,drc->aAddr2,5);
//91 get rx_pw_p1
Rf24L01_WriteByte(WRITE_REG + RX_PW_P1, drc->nLen);
}
//------------------------------------------------------
//10 set tx_addr
//------------------------------------------------------
//tx address buf
Rf24L01_WriteMultiByte(WRITE_REG + TX_ADDR,drc->aAddr1,5);
//------------------------------------------------------
//11 ACTIVATE
//------------------------------------------------------
Rf24L01_WriteByte(ACTIVATE, 0x73);
//------------------------------------------------------
//12 get FEATURE
//------------------------------------------------------
Rf24L01_WriteByte(WRITE_REG + FEATURE, 0x05);
//------------------------------------------------------
//13 get DYNPD
//------------------------------------------------------
Rf24L01_WriteByte(WRITE_REG + DYNPD, drc->nRecvAddr);
RF = 1;
if(drc->nOn == Dev_Normal)
{
CE_HIGH();
}
return 0;
}
//---------------------------------------------------------------------------
//
// End file
//
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -