#include "nRF24L01_API.h"

static uchar TX_ADDRESS[TX_ADR_WIDTH] = {0x00, TR_ADDR_B1, TR_ADDR_B2, TR_ADDR_B3, TR_ADDR_B4}; //发送地址
static uchar RX_ADDRESS[RX_ADR_WIDTH] = {0x00, TR_ADDR_B1, TR_ADDR_B2, TR_ADDR_B3, TR_ADDR_B4}; //接收地址

/*
00		配置寄存器
		[7]
		[6]可屏蔽中断 RX_RD
		[5]可屏蔽中断 TX_DS
		[4]可屏蔽中断 MAX_RT
		[3]CRC 使能
		[2]CRC 模式
		[1]1:上电0:掉电
		[0]1:接收模式0:发射模式
01		使能“自动应答”功能
		[7:6]
		[5:0]数据通道 5 ~0自动应答允许
02		接收地址允许
		[7:6]
		[5:0]接收数据通道 5 ~0允许
03		设置地址宽度（所有数据通道）
		[7:2]
		[1:0]0.无效 1.3byte  2.4byte  3.5byte 宽度
04		建立自动重发
		[7:4]自动重发延时:'0000'-等待 250+86us  '1111'-等待 4000+86us
		[3:0]自动重发计数:'0000'-禁止自动重发 '1111'-自动重发 15 次
05		射频通道
		[7]
		[6:0]设置 nRF24L01 工作通道频率
06		射频寄存器

.....
.....


*/

#define delay_ms(ms)	Timer3_Delay1ms(ms)
#define delay_us(us)	Timer3_Delay1us(us)	//{u8 i; for(i=0;i<us;i++) {nop;}}

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

/*******************************************************************/
//spi速度为9Mhz（24L01的最大SPI时钟为10Mhz）
#if 0
uchar SPI_RW ( uchar byte )
{
    uchar bit_ctr;

    for ( bit_ctr = 0; bit_ctr < 8; bit_ctr++ ) // 输出8位
    {
        NRF_MOSI = ( byte & 0x80 ); 			// MSB TO MOSI
        byte = ( byte << 1 );					// shift next bit to MSB
        NRF_SCK = 1;
        byte |= NRF_MISO;	        		// capture current MISO bit
        NRF_SCK = 0;
    }

    return byte;
}
#else
uchar SPI_RW ( uchar byte )
{
    uchar i;
    SPDR = byte;						//写寄存器

    for ( i = 0; i < 255; i++ )
    {
        if ( SPSR & SET_BIT7 )
        {
            break;   //等待传输
        }
    }

    SPSR &= ~SET_BIT7;
    byte = SPDR;						//读寄存器
    return byte;
}

#endif
/*********************************************/
/* 函数功能：给24L01的寄存器写值（一个字节） */
/* 入口参数：reg   要写的寄存器地址          */
/*           value 给寄存器写的值            */
/* 出口参数：status 状态值                   */
/*********************************************/
uchar NRF24L01_Write_Reg ( uchar reg, uchar value )
{
    uchar status;
    NRF_CSN = 0;                //CSN=0;
    status = SPI_RW ( reg );		//发送寄存器地址,并读取状态值
    SPI_RW ( value );
    NRF_CSN = 1;                //CSN=1;

    return status;
}
/*************************************************/
/* 函数功能：读24L01的寄存器值 （一个字节）      */
/* 入口参数：reg  要读的寄存器地址               */
/* 出口参数：value 读出寄存器的值                */
/*************************************************/
uchar NRF24L01_Read_Reg ( uchar reg )
{
    uchar value;

    NRF_CSN = 0;            	//CSN=0;
    SPI_RW ( reg );				//发送寄存器值(位置),并读取状态值
    value = SPI_RW ( NOP );
    NRF_CSN = 1;             	//CSN=1;

    return value;
}
/*********************************************/
/* 函数功能：读24L01的寄存器值（多个字节）   */
/* 入口参数：reg   寄存器地址                */
/*           *pBuf 读出寄存器值的存放数组    */
/*           len   数组字节长度              */
/* 出口参数：status 状态值                   */
/*********************************************/
uchar NRF24L01_Read_Buf ( uchar reg, uchar *pBuf, uchar len )
{
    uchar status, u8_ctr;
    NRF_CSN = 0;                   	//CSN=0
    status = SPI_RW ( reg );				//发送寄存器地址,并读取状态值

    for ( u8_ctr = 0; u8_ctr < len; u8_ctr++ )
    {
        pBuf[u8_ctr] = SPI_RW ( 0XFF );		//读出数据
    }

    NRF_CSN = 1;                 		//CSN=1
    return status;        			//返回读到的状态值
}
/**********************************************/
/* 函数功能：给24L01的寄存器写值（多个字节）  */
/* 入口参数：reg  要写的寄存器地址            */
/*           *pBuf 值的存放数组               */
/*           len   数组字节长度               */
/**********************************************/
uchar NRF24L01_Write_Buf ( uchar reg, uchar *pBuf, uchar len )
{
    uchar status, u8_ctr;
    NRF_CSN = 0;
    status = SPI_RW ( reg );			//发送寄存器值(位置),并读取状态值

    for ( u8_ctr = 0; u8_ctr < len; u8_ctr++ )
    {
        SPI_RW ( *pBuf++ ); 				//写入数据
    }

    NRF_CSN = 1;
    return status;          		//返回读到的状态值
}

/*********************************************/
/* 函数功能：24L01接收数据               */
/* 入口参数：rxbuf 接收数据数组     */
/* 返回值： 0   成功收到数据            */
/*          1   没有收到数据                 	  */
/*********************************************/
uchar NRF24L01_RxPacket ( uchar *rxbuf, uchar rxlen )
{
    uchar state;
    uchar res = 0;

    state = NRF24L01_Read_Reg ( STATUS );  			//读取状态寄存器的值

    if ( state & RX_DR )								//接收到数据
    {
        state &= ~RX_DR;
        NRF_CE = 0;		//配置前
        rxlen = ( rxlen < RX_PLOAD_WIDTH ) ? ( rxlen ) : ( RX_PLOAD_WIDTH );
        NRF24L01_Read_Buf ( RD_RX_PLOAD, rxbuf, RX_PLOAD_WIDTH ); //读取数据
        NRF24L01_Write_Reg ( FLUSH_RX, 0xff );					//清除RX FIFO寄存器
        NRF_CE = 1;		//配置完,使能收发
        delay_us ( 150 );
        res = 1;
    }

    NRF24L01_Write_Reg ( WRITE_REG + STATUS, state ); //清除TX_DS或MAX_RT中断标志
    return res;//没收到任何数据
}
/**********************************************/
/* 函数功能：设置24L01为发送模式              */
/* 入口参数：txbuf  发送数据数组              */
/* 返回值； 0x10    达到最大重发次数，发送失败*/
/*          0x20    成功发送完成              */
/*          0xff    发送失败                  */
/**********************************************/
uchar NRF24L01_TxPacket ( uchar *txbuf, uchar txlen )
{
    uchar res = 1;
    uchar state;
    uint16 i;

    NRF_CE = 0;					//CE拉低，使能24L01配置
    txlen = ( txlen < TX_PLOAD_WIDTH ) ? ( txlen ) : ( TX_PLOAD_WIDTH );
    NRF24L01_Write_Buf ( WR_TX_PLOAD, txbuf, TX_PLOAD_WIDTH );	//写数据到TX BUF  32个字节
    NRF_CE = 1;					//CE置高，使能发送

    for ( i = 0; i < 60; i++ )	//(500+86)us*10
    {
    	delay_us(100);
        if ( NRF_IRQ == 1 )
        {
            break;   //等待发送完成
        }
    }

    state = NRF24L01_Read_Reg ( STATUS );  						//读取状态寄存器的值

    if ( state & MAX_RT )															//达到最大重发次数
    {
        NRF24L01_Write_Reg ( FLUSH_TX, 0xff );					//清除TX FIFO寄存器
        state &= ~MAX_RT;
        res = 0;
    }

    if ( state & TX_DS )										//发送完成
    {
        state &= ~TX_DS;
        res = 0;
    }

    NRF24L01_Write_Reg ( WRITE_REG + STATUS, state ); 		//清除TX_DS或MAX_RT中断标志
    return res;												//发送失败
}

/********************************************/
/* 函数功能：检测24L01是否存在              */
/* 返回值；  1  存在                        */
/*           0  不存在                      */
/********************************************/
uchar NRF24L01_Check ( void )
{
    uchar res = 0;
    uchar check_in_buf[5] = {0x11, 0x22, 0x33, 0x44, 0x55};
    uchar check_out_buf[5] = {0x00};

    NRF_SCK = 0;
    NRF_CSN = 1;
    NRF_CE = 0;

    NRF24L01_Write_Buf ( WRITE_REG + TX_ADDR, check_in_buf, 5 );

    NRF24L01_Read_Buf ( READ_REG + TX_ADDR, check_out_buf, 5 );

    if ( ( check_out_buf[0] == 0x11 ) && \
            ( check_out_buf[1] == 0x22 ) && \
            ( check_out_buf[2] == 0x33 ) && \
            ( check_out_buf[3] == 0x44 ) && \
            ( check_out_buf[4] == 0x55 ) )
    {
        res = 1;
    }

    return res;
}

uint16 NRF24L01_Wait_Check ( void )
{
    uint16 i;

    for ( i = 0; i < 50; i++ )
    {
        if ( NRF24L01_Check() )
        {
            break;   //等待发送完成
        }

        Timer3_Delay10us ( 10 );
    }

    return i;
}
/**********************************************/
/* 函数功能：24L01初始化                      */
/* 入口参数：PLOAD_WIDTH  有效数据宽度        */
/* 			 TX_ADR  发送地址		          */
/* 		     TX_ADDR_WIDTH  发送地址宽度      */
/* 			 RX_ADR  接收发送地址        	  */
/* 			 RX_ADDR_WIDTH  接收地址宽度      */
/* 			 RATE  有效数据宽度        		  */
/* 返回值  ；无	     	                      */
/**********************************************/
void NRF24L01_RT_Init ( void )
{
    NRF_CE = 0;
    NRF24L01_Write_Reg ( WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH ); //设置接收数据长度，本次设置为32字节
    NRF24L01_Write_Reg ( FLUSH_RX, 0xff ); 					//清除RX FIFO寄存器
    NRF24L01_Write_Buf ( WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH ); //写TX节点地址
    NRF24L01_Write_Buf ( WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH ); //设置RX节点地址,主要为了使能ACK

    NRF24L01_Write_Reg ( WRITE_REG + EN_AA, 0x05 ); 		//使能通道0的自动应答
    NRF24L01_Write_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); 	//使能通道0的接收地址

    NRF24L01_Write_Reg ( WRITE_REG + FEATURE, 0x00 );		//使能动态数据包长度,AUTO_ACK模式
    NRF24L01_Write_Reg ( WRITE_REG + DYNPD, 0x01 );     	//选择通道0动态数据包长度

    NRF24L01_Write_Reg ( WRITE_REG + SETUP_RETR, 0x1a ); 	//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10(a)次
    NRF24L01_Write_Reg ( WRITE_REG + RF_CH, 40 ); 			//设置RF通道为40 收发必须一致，0为2.4GHz + 40
    NRF24L01_Write_Reg ( WRITE_REG + RF_SETUP, 0x0f ); 		//设置TX发射参数,0db增益,2Mbps,低噪声增益开启
    NRF24L01_Write_Reg ( WRITE_REG + CONFIG, 0x0f );		 //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
	NRF_CE = 1;					//CE置高，使能发送
	delay_us ( 130 );
}
/**********************************************/
/* 函数功能：发射函数                     	  */
/* 入口参数：buf  发送寄存器	          	  */
/* 返回值  ；无	     	                      */
/**********************************************/
/*
nRF24L01 可以设置为以下几种主要的模式，
模式 			PWR_UP 		PRIM_RX 		CE 		FIFO 寄存器状态
接收模式 	1 			1 			1 		-
发送模式 	1 			0 			1 		数据在 TX FIFO 寄存器中
发送模式 	1 			0 			1→0 	停留在发送模式，直至数据发送完
待机模式II 	1 			0 			1 		TX FIFO 为空
待机模式I 	1 			- 			0 		无数据传输
掉电模式 	0 			- 			- 		-
CONFIG[0]	PRIM_RX:	1:接收模式 0:发射模式
CONFIG[1]	PWR_UP:		1:上电 0:掉电
*/
uchar SEND_BUF ( uchar *buf, uchar len )
{
    uchar state;
    NRF_CE = 0;
    NRF24L01_Write_Reg ( WRITE_REG + CONFIG, 0x0e );	//CONFIG[0] PRIM_RX=0.发射
    NRF_CE = 1;
    delay_us ( 10 );
    state = NRF24L01_TxPacket ( buf, len );
    NRF_CE = 0;
    NRF24L01_Write_Reg ( WRITE_REG + CONFIG, 0x0f );	//CONFIG[0] PRIM_RX=0.发射
    NRF_CE = 1;
    delay_us ( 130 );	
    return state;
}

