/******************************************************************************/
/*                        -- 深圳安信可科技有限公司 --                        */
/*
//  文件名：
//  说明：
//  编写人员：
//  编写日期：
//  程序维护：
//  维护记录：
//
//
*/
// 免责声明：该程序仅用于学习与交流
// (c) Anxinke Corporation. All rights reserved.
/******************************************************************************/
//#include "typedef.h"
#include <intrins.h>
#include <string.h>
#include "NRF_24L01.h"
//#include "UART.H"
#include "delay.h"

#define uchar unsigned char


uchar const TX_ADDRESS[TX_ADR_WIDTH]  = {0x34, 0x43, 0x10, 0x10, 0x01}; // Define a static TX address

idata uchar rx_buf[TX_PLOAD_WIDTH];

idata uchar tx_buf[TX_PLOAD_WIDTH];

uchar flag;



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



//sbit LED1= P3^7;
/**************************************************/
unsigned char	bdata sta;

sbit	RX_DR	= sta ^ 6;

sbit	TX_DS	= sta ^ 5;

sbit	MAX_RT	= sta ^ 4;
/**************************************************/

/**************************************************
Function: init_io();
Description:
  flash led one time,chip enable(ready to TX or RX Mode),
  Spi disable,Spi clock line init high
/**************************************************/
#define KEY 0xaa
void init_nrf24l01_io ( void )
{
    CE = 0;			// chip enable
    CSN = 1;			// Spi disable
    SCK = 0;			// Spi clock line init high
}
/**************************************************
Function: SPI_RW();

Description:
  Writes one byte to nRF24L01, and return the byte read
  from nRF24L01 during write, according to SPI protocol
/**************************************************/
bdata unsigned char st = 0;
sbit st_1 = st ^ 0;
sbit st_2 = st ^ 1;
sbit st_3 = st ^ 2;
sbit st_4 = st ^ 3;
sbit st_5 = st ^ 4;
sbit st_6 = st ^ 5;
sbit st_7 = st ^ 6;
sbit st_8 = st ^ 7;
bdata unsigned char st1 = 0;
sbit st_11 = st1 ^ 0;
sbit st_12 = st1 ^ 1;
sbit st_13 = st1 ^ 2;
sbit st_14 = st1 ^ 3;
sbit st_15 = st1 ^ 4;
sbit st_16 = st1 ^ 5;
sbit st_17 = st1 ^ 6;
sbit st_18 = st1 ^ 7;
/*
uchar SPI_RW(uchar byte)
{
	uchar bit_ctr;
   	for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit
   	{
   		MOSI = (byte & 0x80);         // output 'byte', MSB to MOSI
   		byte = (byte << 1);           // shift next bit into MSB..
   		SCK = 1;                      // Set SCK high..
		MISO=1;
   		byte |= MISO;       		  // capture current MISO bit
   		SCK = 0;            		  // ..then set SCK low again
   	}
    return(byte);           		  // return read byte
}
*/

uchar SPI_RW ( uchar byte )
{
    //uchar bit_ctr;

    st = byte;

    MOSI = st_8;
    SCK = 1;
    st_18 = MISO;
    SCK = 0;

    MOSI = st_7;
    SCK = 1;
    st_17 = MISO;
    SCK = 0;

    MOSI = st_6;
    SCK = 1;
    st_16 = MISO;
    SCK = 0;

    MOSI = st_5;
    SCK = 1;
    st_15 = MISO;
    SCK = 0;

    MOSI = st_4;
    SCK = 1;
    st_14 = MISO;
    SCK = 0;

    MOSI = st_3;
    SCK = 1;
    st_13 = MISO;
    SCK = 0;

    MOSI = st_2;
    SCK = 1;
    st_12 = MISO;
    SCK = 0;

    MOSI = st_1;
    SCK = 1;
    st_11 = MISO;
    SCK = 0;
    return ( st1 );           		 // return read byte
}
/**************************************************/

/**************************************************
Function: SPI_RW_Reg();

Description:
  Writes value 'value' to register 'reg'
/**************************************************/
uchar SPI_RW_Reg ( BYTE reg, BYTE value )
{
    uchar status;
    CSN = 0;                   // CSN low, init SPI transaction
    status = SPI_RW ( reg );   // select register
    SPI_RW ( value );          // ..and write value to it..
    CSN = 1;                   // CSN high again
    return ( status );         // return nRF24L01 status byte
}
/**************************************************/

/**************************************************
Function: SPI_Read();

Description:
  Read one byte from nRF24L01 register, 'reg'
/**************************************************/
BYTE SPI_Read ( BYTE reg )
{
    BYTE reg_val;

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

    return ( reg_val );     // return register value
}
/**************************************************/

/**************************************************
Function: SPI_Read_Buf();

Description:
  Reads 'bytes' #of bytes from register 'reg'
  Typically used to read RX payload, Rx/Tx address
/**************************************************/
uchar SPI_Read_Buf ( BYTE reg, BYTE *pBuf, BYTE bytes )
{
    uchar status, byte_ctr;

    CSN = 0;                    		// Set CSN low, init SPI tranaction
    status = SPI_RW ( reg );       		// Select register to write to and read status byte

    for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ )
        pBuf[byte_ctr] = SPI_RW ( 0 ); // Perform SPI_RW to read byte from nRF24L01

    CSN = 1;                           // Set CSN high again

    return ( status );                 // return nRF24L01 status byte
}
/**************************************************/

/**************************************************
Function: SPI_Write_Buf();

Description:
  Writes contents of buffer '*pBuf' to nRF24L01
  Typically used to write TX payload, Rx/Tx address
/**************************************************/
uchar SPI_Write_Buf ( BYTE reg, BYTE *pBuf, BYTE bytes )
{
    uchar status, byte_ctr;

    CSN = 0;                   // Set CSN low, init SPI tranaction
    status = SPI_RW ( reg ); // Select register to write to and read status byte

    for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ ) // then write all byte in buffer(*pBuf)
        SPI_RW ( *pBuf++ );

    CSN = 1;                 // Set CSN high again
    return ( status );       // return nRF24L01 status byte
}
/**************************************************/

/**************************************************
Function: RX_Mode();

Description:
  This function initializes one nRF24L01 device to
  RX Mode, set RX address, writes RX payload width,
  select RF channel, datarate & LNA HCURR.
  After init, CE is toggled high, which means that
  this device is now ready to receive a datapacket.
/**************************************************/
void power_off()
{
    CE = 0;
    SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0D );
    CE = 1;
    Timer3_Delay10us ( 2 );
}
void ifnnrf_rx_mode ( void )
{
    power_off();
    CE = 0;
    SPI_Write_Buf ( WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH ); // Use the same address on the RX device as the TX device

    SPI_RW_Reg ( WRITE_REG + EN_AA, 0x01 );   // Enable Auto.Ack:Pipe0
    SPI_RW_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); // Enable Pipe0
    SPI_RW_Reg ( WRITE_REG + RF_CH, 40 );     // Select RF channel 40
    SPI_RW_Reg ( WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH ); // Select same RX payload width as TX Payload width
    SPI_RW_Reg ( WRITE_REG + RF_SETUP, 0x27 ); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
    SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0f );  // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..

    CE = 1; // Set CE pin high to enable RX device

    //  This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address
    //  '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.

}
/**************************************************/

/**************************************************
Function: TX_Mode();

Description:
  This function initializes one nRF24L01 device to
  TX mode, set TX address, set RX address for auto.ack,
  fill TX payload, select RF channel, datarate & TX pwr.
  PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.

  ToDo: One high pulse(>10us) on CE will now send this
  packet and expext an acknowledgment from the RX device.
/**************************************************/
void ifnnrf_tx_mode ( void )
{
    power_off();
    CE = 0;

    SPI_Write_Buf ( WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH ); // Writes TX_Address to nRF24L01
    SPI_Write_Buf ( WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH ); // RX_Addr0 same as TX_Adr for Auto.Ack
    SPI_Write_Buf ( WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH ); // Writes data to TX payload

    SPI_RW_Reg ( WRITE_REG + EN_AA, 0x01 );   // Enable Auto.Ack:Pipe0
    SPI_RW_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); // Enable Pipe0
    SPI_RW_Reg ( WRITE_REG + SETUP_RETR, 0x1a ); // 500us + 86us, 10 retrans...
    SPI_RW_Reg ( WRITE_REG + RF_CH, 40 );     // Select RF channel 40
    SPI_RW_Reg ( WRITE_REG + RF_SETUP, 0x27 ); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
    SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0e );  // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
    CE = 1;

}

void SPI_CLR_Reg ( BYTE R_T )
{
    CSN = 0;

    if ( R_T == 1 )             // CSN low, init SPI transaction
        SPI_RW ( FLUSH_TX );          // ..and write value to it..
    else
        SPI_RW ( FLUSH_RX );          // ..and write value to it..

    CSN = 1;                   // CSN high again
}

void ifnnrf_CLERN_ALL()
{
    SPI_CLR_Reg ( 0 );
    SPI_CLR_Reg ( 1 );
    SPI_RW_Reg ( WRITE_REG + STATUS, 0xff );
    IRQ = 1;
}



/*测试*/
bool nrf24l01_send ( BYTE *pBuf, BYTE bytes )
{
    BYTE time = 100;	//
    IRQ = 1;									//中断=1
    SPI_RW_Reg ( WRITE_REG + STATUS, 0xff );		//清写寄存器

    //发送
    memcpy ( tx_buf, pBuf, bytes < TX_PLOAD_WIDTH ? bytes : TX_PLOAD_WIDTH );
    ifnnrf_tx_mode();

    //返回状态
    while ( IRQ && time>0 ){time--;}

    sta = SPI_Read ( STATUS );					//读取状态
    SPI_RW_Reg ( WRITE_REG + STATUS, 0xff );		//清写寄存器

    if ( ! ( sta & STA_MARK_TX ) )  				//发送成功
    {
        ifnnrf_CLERN_ALL();
        return 0;
    }

    //切换接收模式
    ifnnrf_rx_mode();
    IRQ = 1;
    return 1;
}

BYTE nrf24l01_recv ( BYTE *pBuf )
{
	BYTE time = 100;	//
    if ( IRQ == 0 )  							//中断信号
    {
        sta = SPI_Read ( STATUS );
        SPI_RW_Reg ( WRITE_REG + STATUS, 0xff );	//清写寄存器

        if ( sta & STA_MARK_RX )   				//接收成功
        {
            SPI_Read_Buf ( RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH );
            //处理rx_buf

            //清理rx_buf
            memset ( rx_buf, 0, TX_PLOAD_WIDTH );
        }
        else
        {
            ifnnrf_CLERN_ALL();
            ifnnrf_rx_mode();
			while ( IRQ == 0 && time>0 ){time--;}
        }
    }
}



void if_main ( void )
{
    Timer3_Delay100ms ( 1 );
    init_nrf24l01_io();
    ifnnrf_rx_mode();

}




