/******************************************************/
/***************NRF2401_Wireless module****************/
/******************************************************/
/******************************************************/
#include "global.h"
/************************* Define Pin *****************/
#define CE P0_0
#define CSN P0_1
#define IRQ P0_2
#define MISO P0_3
#define MOSI P0_4
#define SCK P0_5
/******************************************************/
/********************SPI(nRF24L01) commands****************/
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
/********************* registers addresses *********************/
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
/*******************************************************/
#define TX_DATA_WIDTH 32
#define ADDR_DATA_WIDTH 5
uchar code TX_ADDR_DATA[] = {"0xe7,0xe7,0xe7,0xe7,0xe7"};
uchar code RX_ADDR_P0_DATA[] = {"0xe7,0xe7,0xe7,0xe7,0xe7"};
uchar TX_DATA[TX_DATA_WIDTH];
uchar RX_DATA[TX_DATA_WIDTH];
uchar bdata sta;
sbit RX_DR = sta^6;
sbit TX_DS = sta^5;
sbit MAX_RT = sta^4;
/**************************************************/
/*******************************************************/
/**************** SPI Write or Read *************************/
uchar SPI_WD(uchar Data)
{
uint i;
for(i=0;i<8;i++)
{
SCK=1;
MOSI = Data & 0x80;
Data<<=1;
Data |= MISO;
SCK=0;
}
return Data;
}
/*******************************************************/
/*******************************************************/
/**************** Write_Data *************************/
uchar Write_Data(uchar Command,uchar *Data,uchar byte) //Write operation
{
uchar status;
CSN=0;
status=SPI_WD(Command); //select REG and read status
for(i=0;i<byte;i++) //Send data
SPI_WD(Data[i]);
CSN=1;
return status;
}
/*******************************************************/
/*******************************************************/
/**************** Read_Data *************************/
uchar Read_Data(uchar Command,uchar *Data,uchar byte) //Read operation
{
uchar status;
CSN=0;
status=SPI_WD(Command); //select REG and read status
for(i=0;i<byte;i++) //Read data
Data[i]=SPI_WD(0);
CSN=1;
return status;
}
/*******************************************************/
/*******************************************************/
/**************** Transmit mode **********************/
void TX_Mode(uchar *TX_Data)
{
CE=0;
Write_Data(WRITE_REG + TX_ADDR, TX_ADDRESS, ADDR_DATA_WIDTH);
/*set transmit address */
Write_Data(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, ADDR_DATA_WIDTH);
/*set the same address with T_ADDR to receive the answer sign*/
Write_Data(W_RX_PAYLOAD, TX_Data, TX_DATA_WIDTH);
/*write data to TX_FIFO */
Write_Data(WRITE_REG + EN_AA, 0x01, 1);
/* enable R_channel 0 auto answer */
Write_Data(WRITE_REG + EN_RXADDR, 0x01, 1);
/* enable R_channel 0 */
Write_Data(WRITE_REG + SETUP_RETR, 0x0a, 1);
/* automatic retransmission delay 250us+86us,10 times */
Write_Data(WRITE_REG + RF_CH, 0x40, 1);
/* select RF_channel 0x40 */
Write_Data(WRITE_REG + RF_SETUP, 0x07, 1);
/* data transmiting rate 1Mbps,transmiting power 0dBm,LNA gain */
Write_Data(WRITE_REG + CONFIG, 0x0e, 1);
/* CRC enable,16bit CRC checkout,power on */
CE=1;
}
/*******************************************************/
/*******************************************************/
/**************** receive mode ***********************/
void RX_Mode()
{
CE=0;
Write_Data(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_DATA_WIDTH);
/* set the same address with T_mode */
Write_Data(WRITE_REG + EN_AA, 0x01, 1);
/* enable R_channel 0 auto answer */
Write_Data(WRITE_REG + EN_RXADDR, 0x01, 1);
/* enable R_channel 0 */
Write_Data(WRITE_REG + RF_CH, 0x40, 1);
/* select RF_channel 0x40 */
Write_Data(WRITE_REG + RX_PW_P0, TX_DATA_WIDTH);
/* same valid data with T_channel in R_channel 0 */
Write_Data(WRITE_REG + RF_SETUP, 0x07, 1);
/* data transmiting rate 1Mbps,transmiting power 0dBm,LNA gain */
Write_Data(WRITE_REG + CONFIG, 0x0f, 1);
/* CRC enable,16bit CRC checkout,power on , R_mode*/
CE=1;
}
/*******************************************************/
/************ check if receive the data ***************/
/*******************************************************/
uchar Check_ACK(bit clear)
{
while(IRQ);
// 返回状态寄存器
if(MAX_RT)
if(clear) // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
{
CE=0;
SPT_WD(FLUSH_TX);
CE=1;
}
Write_Data(WRITE_REG + STATUS, &sta, 1);
// clear TX_DS or MAX_RT interrupt flag
IRQ = 1;
if(TX_DS)
return(0x00);
else
return(0xff);
}
/**************************************************/
/*******************************************************/
/******************** NRF_Init *************************/
void NRF_Init()
{
CE = 0; // stand by
CSN = 1; // SPI lock
SCK = 0; // SPI clock lown down
IRQ = 1; // interrupt reset
}
/*******************************************************/
void main()
{
uchar sta;
NRF_Init(); // Init NRF
RX_Mode(); // set R_mode
TX_Mode(TX_Data);
Check_ACK(1);
Read_Data(STATUS, &sta, 1); // read STATUS REG
if(RX_DR) // whether if receive the data
{
Read_Data(RD_RX_PLOAD, RX_DATA, TX_DATA_WIDTH);
//read data from RX_FIFO
}
Write_Data(WRITE_REG + STATUS, sta, 1); // clear RX_DS interrupt flag
}