
//ͨģnrf2401
//оƬ:	޹ش

//汾:	ڰ汾v0й̶4ֽ,汾ĳ6;
//óʱʱ

//2013312 ѳĳ¼ʽ, ȥ˳ʱʱ,ģʽת;

unit NRF2401
{
	public link unit io {}
	
	//[i] var_uint8 OS_time,
	uint8 OS_time;
	
	//[i] var_uint8 OS_EventFlag;
	uint8 OS_EventFlag;
	//[i] event receive_event;
	
	//[i] var_array buffer,
	public [uint8*LENGTH] buffer;
	
	const uint8 LENGTH = 6;
	
	[uint8*5] local_address;
	[uint8*5] target_address;
	
	bool isSend;
	
	#include "AVR_11MHZ.txt"
	
	//---------------------------------------------------
	//[i] function_void OS_init;
	public void OS_init()
	{
		port_init();
		spi.init();
		set( CONFIG, 0b0000_1111 );		//CRCʹܣ16λCRCУ飬ϵ,ģʽ
		set( EN_AA, 0x01 );			//ʹܽͨ0ԶӦ
		set( EN_RXADDR, 0x01 );			//ʹܽͨ0
		set( SETUP_AW, 0x03 );			//õַ 5ֽ
		set( SETUP_RETR, 0xff );		//Զطʱȴ4000us+86usԶط15
		set( RF_CH, 40 );				//ѡƵͨ40
		set( RF_SETUP, 0x07 );			//ݴ1Mbps书0dBmŴ
		uint8 status = get( STATUS );		//״̬Ĵ
		write_command( FLUSH_TX);
		write_command( FLUSH_RX);
		set( STATUS, status|0b0111_0000 );	//TX_DSMAX_RTжϱ־
		
		//
		//ͨ0ѡͷͨͬЧݿ
		set( RX_PW_P0, LENGTH );
		
		local_address[0] = 0x00;
		local_address[1] = 0x43;
		local_address[2] = 0x10;
		local_address[3] = 0x10;
		local_address[4] = 0x01;
		
		target_address[0] = 0x00;
		target_address[1] = 0x43;
		target_address[2] = 0x10;
		target_address[3] = 0x10;
		target_address[4] = 0x01;
		
		OS_set_receive_mode();
		
		OS_time = 1;
		OS_EventFlag = 0;
		
		isSend = false;
	}
	//---------------------------------------------------
	//[i] function_void OS_run;
	public void OS_run()
	{
		if( !isSend && io.IRQ_IN == 0 ) {
			
			//ģжȡ
			read_buffer( RD_RX_PLOAD, buffer, LENGTH );
			uint8 sta = get( STATUS );
			set( STATUS, sta );
			write_command( FLUSH_RX );
			
			OS_EventFlag.0(bit) = 1;
		}
	}
	//---------------------------------------------------
	//[i] function_void send_buffer;
	public void send_buffer()
	{
		isSend = true;
		
		OS_set_send_mode();
		
		//ͨ0ѡͷͨͬЧݿ
		set( RX_PW_P0, LENGTH );
		
		io.CE_OUT = 0;
		//дݰTX FIFO
		write_buffer( WR_TX_PLOAD, buffer, LENGTH );
		//д뷢͵ַ
		//write_buffer( WRITE_REG+TX_ADDR, target_address, 5 );
		//ΪӦ豸ͨ0ַͷ͵ַͬ
		//write_buffer( WRITE_REG+RX_ADDR_P0, target_address, 5 );
		io.CE_OUT = 1;
		
		//ȴӦ
		repeat until io.IRQ_IN == 0; {}
		uint8 status = get( STATUS );	//״̬Ĵ
		set( STATUS, status );  	//TX_DSMAX_RTжϱ־
		write_command( FLUSH_TX );
		
		OS_set_receive_mode();
		
		isSend = false;
	}
	//---------------------------------------------------
	//[i] function_bool OS_isOK;
	public bool OS_isOK()
	{
		set( RF_CH, 0x03 );
		if( get( RF_CH ) != 0x03 ) return false;
		set( RF_CH, 0x40 );
		if( get( RF_CH ) != 0x40 ) return false;
		return true;
	}
	//---------------------------------------------------
	//[i] function_void set_local_address uint8;
	public void set_local_address( uint8 addr )
	{
		local_address[0] = addr;
	}
	//---------------------------------------------------
	//[i] function_void set_target_address uint8
	public void set_target_address( uint8 addr )
	{
		target_address[0] = addr;
	}
	//=================================================================================
	void OS_to_normal_mode()
	{
		uint8 c = get( CONFIG );
		c | 0b0000_0010;
		set( CONFIG, c );
	}
	void OS_to_power_down_mode()
	{
		uint8 c = get( CONFIG );
		c & 0b1111_1101;
		set( CONFIG, c );
	}
	void OS_set_receive_mode()
	{
		io.CE_OUT = 0;
		
		//дַͨ
		write_buffer( WRITE_REG+RX_ADDR_P0, local_address, 5 );
		uint8 c = get( CONFIG );
		c | 0b0000_0001;
		set( CONFIG, c );
		io.CE_OUT = 1;
	}
	void OS_set_send_mode()
	{
		io.CE_OUT = 0;
		uint8 c = get( CONFIG );
		c & 0b1111_1110;
		set( CONFIG, c );
		io.CE_OUT = 1;
	}
	//--------------------------------
	void write_command( uint8 cmd )
	{
		io.CSN_OUT = 0;
		spi.write_byte( cmd );
		io.CSN_OUT = 1;
	}
	//p_bufед뵽nRF24L01ͨд뷢ͨݻ/͵ַ
	void write_buffer( uint8 reg, [uint8*?] p_buf, uint8 length )
	{
		io.CSN_OUT = 0;
		spi.write_byte( reg );
		repeat first uint8 i = 0; each i + 1; until i == length; {
			spi.write_byte( p_buf[i] );
		}
		io.CSN_OUT = 1;
	}
	//ȡnRF2401ĳ
	void read_buffer( uint8 reg, [uint8*?]p_buf, uint8 length)
	{
		io.CSN_OUT = 0;
		spi.write_byte( reg );
		repeat first uint8 i = 0; each i + 1; until i == length; {
			p_buf[i] = spi.read_byte();
		}
		io.CSN_OUT = 1;
	}
	//---------------------------------------------------
	//дĴ
	void set( uint8 addr, uint8 data )
	{
		io.CSN_OUT = 0;
		spi.write_byte( WRITE_REG + addr );
		spi.write_byte( data );
		io.CSN_OUT = 1;
	}
	//Ĵ
	uint8 get( uint8 addr )
	{
		io.CSN_OUT = 0;
		spi.write_byte( READ_REG + addr );
		uint8 data = spi.read_byte();
		io.CSN_OUT = 1;
		return data;
	}
	//=================================================================================
	const uint8 CONFIG = 		0x00;  //'Config'
	const uint8 EN_AA = 		0x01;  //'Enable Auto Acknowledgment'
	const uint8 EN_RXADDR = 	0x02;  //'Enabled RX addresses'
	const uint8 SETUP_AW = 		0x03;  //'Setup address width'
	const uint8 SETUP_RETR = 	0x04;  //'Setup Auto. Retrans'
	const uint8 RF_CH = 		0x05;  //'RF channel'
	const uint8 RF_SETUP = 		0x06;  //'RF setup'
	const uint8 STATUS = 		0x07;  //'Status'
	const uint8 OBSERVE_TX = 	0x08;  //'Observe TX'
	const uint8 CD = 			0x09;  //'Carrier Detect'
	const uint8 RX_ADDR_P0 = 	0x0A;  //Ƶ0ݵַ
	const uint8 RX_ADDR_P1 = 	0x0B;  //'RX address pipe1'
	const uint8 RX_ADDR_P2 = 	0x0C;  //'RX address pipe2'
	const uint8 RX_ADDR_P3 = 	0x0D;  //'RX address pipe3'
	const uint8 RX_ADDR_P4 = 	0x0E;  //'RX address pipe4'
	const uint8 RX_ADDR_P5 = 	0x0F;  //'RX address pipe5'
	const uint8 TX_ADDR = 		0x10;  //'TX address'
	const uint8 RX_PW_P0 = 		0x11;  //Ƶ0ݳ
	const uint8 RX_PW_P1 = 		0x12;  //'RX payload width; pipe1'
	const uint8 RX_PW_P2 = 		0x13;  //'RX payload width; pipe2'
	const uint8 RX_PW_P3 = 		0x14;  //'RX payload width; pipe3'
	const uint8 RX_PW_P4 = 		0x15;  //'RX payload width; pipe4'
	const uint8 RX_PW_P5 = 		0x16;  //'RX payload width; pipe5'
	const uint8 FIFO_STATUS = 	0x17;  //'FIFO Status Register'
	//SPI nRF24L01 commands
	const uint8 READ_REG =		0x00;  //Define read command to register
	const uint8 WRITE_REG =		0x20;  //Define write command to register
	const uint8 RD_RX_PLOAD =	0x61;  //Define RX payload register address
	const uint8 WR_TX_PLOAD =	0xA0;  //Define TX payload register address
	const uint8 FLUSH_TX =		0xE1;  //Define flush TX register command
	const uint8 FLUSH_RX =		0xE2;  //Define flush RX register command
	const uint8 REUSE_TX_PL =	0xE3;  //Define reuse TX payload register command
	const uint8 NOP =			0xFF;  //Define No Operation; might be used to read status register
	
	//SPIнӿԪ;λǰ;λں
	spi.SCK_DIR = io.SCK_DIR; spi.SCK_IN = io.SCK_IN; spi.SCK_OUT = io.SCK_OUT;
	spi.MISO_DIR = io.MISO_DIR; spi.MISO_IN = io.MISO_IN; spi.MISO_OUT = io.MISO_OUT;
	spi.MOSI_DIR = io.MOSI_DIR; spi.MOSI_IN = io.MOSI_IN; spi.MOSI_OUT = io.MOSI_OUT;
}








