// 
// rw1600 driver
//
// author: Radioway
//=========================================================================    
//              
//    SCK--PA4 |1    16| PA5--MISO
//         PA0 |2    15| PA1
//    CSN--PB7 |3    14| PA2
//         PB6 |4    13| PA3
//         VDD |5    12| GND
//         PB5 |6    11| PB0--MOSI
//         PB4 |7    10| PB1                                
//         PB3 |8     9| PB2
//
//==========================================================================
#include    <8PE531A.H>
#include    "rw1620drv.h"
#include    "typesdefine.h"   

byte rf_data_buf[20];
byte rf_buf;    
byte rf_write_data_cnt;
byte rf_reg;  
byte rf_data;
byte DelayCnt;     
byte spiwrbytei;
//
//=========================== Sub Function =================================
//
void Delay100US(void)
{
    unsigned char cntt0;
    
	while(--DelayCnt)
	{
	    cntt0=50;
		while(--cntt0)
		{
		    NOP();
		    NOP();
		}
	};
}

void Delay5US(unsigned int dlyus)
{
	while(--dlyus)
	{NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
	}
}


void rf_SPI_init(void)
{   
    PORTA &= ~0x20;    // PA5 out 0
    IOSTA |=  0x20;    // PA5 as in pin
    APHCON &= ~0x20;   // pull up
 //   AWUCON |= 0x20;    // Enable PA5 week up
    
//    PORTA |= 0x20;    // PA5--MISO out 0
//    IOSTA |= 0x20;    // PA5--MISO as input pin

    PORTA &= ~0x10;    // PA4--SCK out 0
    IOSTA &= ~0x10;   // PA4--SCK as output pin

    PORTB |= 0x81;    // PB0--MOSI,PB7--CSN out 1
    IOSTB &= ~0x81;   // PB0--MOSI,PB7--CSN as output pin   
    
    BPHCON &= ~0x01;   // pull up
}


void spi_Writeabyte(void)
{        
 
        IOSTB &= ~0x01; 
        
	spiwrbytei=8;
	while(spiwrbytei--)//do
	{         
	        spi_sck = 0;
		if(rf_buf&0x80)spi_mosi = 1;//MSB sent first
		else	   spi_mosi = 0;			
		spi_sck = 1;  
		rf_buf<<=1;
		
	};
	spi_sck = 0;
	spi_mosi = 0;	
}         
void  spi_Readabyte(void)
{        
 
        IOSTB |= 0x01;   
        
	spiwrbytei=8;
	while(spiwrbytei--)//do
	{       
		rf_buf<<=1;  
	        spi_sck = 1;
		if(spi_mosi)rf_buf |= 1;//MSB sent first			
		spi_sck = 0;  		
	};
//	SPI_CLK = 0;
//	SPI_MOSI = 0;	 

}      
//===============================================
//write reg
//===============================================
void rf_write_onebyte(void)
{
	spi_csn=0;
	rf_buf=rf_reg;
	spi_Writeabyte();
	rf_buf=rf_data;
	spi_Writeabyte();
    	spi_csn=1;
}
//===============================================
//write reg
//===============================================
void rf_read_onebyte(void)
{
	spi_csn=0;
	rf_buf=rf_reg;
	spi_Writeabyte();
	rf_buf=rf_data;
	spi_Readabyte();
    spi_csn=1;
	Delay5US(1);	
}

//===============================================
//flush fifo
//===============================================
void flush_tx_fifo(void)
{
	spi_csn=0;
	rf_buf=HS6220_FLUSH_TX;
	spi_Writeabyte();
//	rf_buf=0;
//	spi_Writeabyte();
    spi_csn=1;
}
//===============================================
//flush fifo
//===============================================
void flush_rx_fifo(void)
{
	spi_csn=0;
	rf_buf=HS6220_FLUSH_RX;
	spi_Writeabyte();
//	rf_buf=0;
//	spi_Writeabyte();
    spi_csn=1;
}
//===============================================
//clear rf status flag
//===============================================
void clear_rf_status(void)
{
    spi_csn=0;
	rf_buf=0x27;  //HS6220_BANK0_STATUS
	spi_Writeabyte();
	rf_buf=0x70;
	spi_Writeabyte();
    spi_csn=1;

}
//===============================================
//get rf status flag
//===============================================
void get_rf_status_flag(void)
{
    spi_csn=0;
    rf_buf=0x07;
    spi_Writeabyte();
    spi_Readabyte();       //read rf status
    spi_csn=1;
}

//===============================================
//set_tx
//===============================================
void rf_tx_set(void)
{
    spi_csn=0;
	rf_buf=0x20;
	spi_Writeabyte();
	rf_buf=0xfa;
	spi_Writeabyte();
    spi_csn=1;
}
//===============================================
//set_rx
//===============================================
void rf_rx_set(void)
{
    spi_csn=0;
	rf_buf=0x20;
	spi_Writeabyte();
	rf_buf=0xfb;
	spi_Writeabyte();
    spi_csn=1;
}
//===============================================
//rf power up
//===============================================
void rf_power_up(void)
{
	rf_reg = HS6220_BANK0_CONFIG | HS6220_W_REGISTER;   rf_data =0Xfa;rf_write_onebyte();
	DelayCnt = 10;Delay100US();// 这个1ms的时间是必须的，等待晶体起振和RF芯片的一系列动作

	rf_reg = HS6220_BANK0_PMU_CTL | HS6220_R_REGISTER;   rf_data =0;rf_read_onebyte();
	rf_buf&=0xfc;
	rf_reg = HS6220_BANK0_PMU_CTL | HS6220_W_REGISTER;   rf_data =0xa8;rf_write_onebyte();

}
//===============================================
//rf power down
//===============================================
void rf_power_down(void)
{
	rf_reg = HS6220_BANK0_PMU_CTL | HS6220_R_REGISTER;   rf_data =0;rf_read_onebyte();
	rf_buf&=0xfc;
	rf_buf|=0x01;
	rf_reg = HS6220_BANK0_PMU_CTL | HS6220_W_REGISTER;   rf_data =rf_buf;rf_write_onebyte();
	DelayCnt = 10;Delay100US();// 这个1ms时间是必须要的，要等待RF完成一系列动作

	rf_reg = HS6220_BANK0_CONFIG | HS6220_W_REGISTER;   rf_data =0Xf8;rf_write_onebyte();
}

//===============================================
//ce low
//===============================================
void rf_ce_low(void)
{

    spi_csn=0;
    rf_buf=HS6220_CMD_CE_LOW;
    spi_Writeabyte();
    spi_csn=1;
}
//===============================================
//ce high
//===============================================
void rf_ce_high(void)
{
    spi_csn=0;
    rf_buf=HS6220_CMD_CE_HIGH;
    spi_Writeabyte();
    spi_csn=1;
}   
//==============================================
//write rf_buf
//==============================================
void write_rf_data_buf(void)
{
     byte temp01_buf;

	 temp01_buf=0;
	 while(temp01_buf<rf_write_data_cnt)
	 {
	     rf_buf=rf_data_buf[temp01_buf];  
	     spi_Writeabyte();
	     temp01_buf++;
	 }
}
//==============================================
//write rf_buf
//==============================================
void read_rf_data_buf(void)
{
     byte temp01_buf;

	 temp01_buf=0;
	 while(temp01_buf<rf_write_data_cnt)
	 {
             spi_Readabyte();
	     rf_data_buf[temp01_buf]=rf_buf;
	     temp01_buf++;
	 }
}
//==============================================
//write tx0_address
//==============================================
void write_tx0_address(void)
{
	spi_csn=0;
	rf_buf=0x30;       //write TX0 address
	spi_Writeabyte();
	rf_write_data_cnt=5;
	write_rf_data_buf();
	spi_csn=1;
}
//==============================================
//write rx0_address
//==============================================
void write_rx0_address(void)
{
	spi_csn=0;
	rf_buf=0x2a;     //write  rx address
	spi_Writeabyte();
	rf_write_data_cnt=5;
	write_rf_data_buf();
	spi_csn=1;
}
/*******************************************************************************
* 名称: HS6220_Bank_Select
* 功能: 
* 形参:       
* 返回: 无
* 说明: 
*******************************************************************************/
void rf_bank_Switch(void)
{
	byte bank = rf_buf;//保存选择blank

	get_rf_status_flag();
	
	if(bank == Rf_Bank1)//选择bank1
	{
		if(!(rf_buf&0x80)){
			rf_reg=HS6220_ACTIVATE; rf_data=HS6220_ACTIVATE_DATA; rf_write_onebyte();
		}
	}
	else
	{
		if(rf_buf&0x80){
			rf_reg=HS6220_ACTIVATE; rf_data=HS6220_ACTIVATE_DATA; rf_write_onebyte();
		}
	}
}
void init_rf(void)
{   
	byte temp00,tmp_data;

	rf_reg=HS6220_BANK0_FEATURE+HS6220_W_REGISTER; rf_data=SOFT_RST;rf_write_onebyte();// soft_reset

	rf_reg=HS6220_BANK0_DYNPD+HS6220_W_REGISTER; rf_data=0x00;rf_write_onebyte();//三线通信
//	rf_reg=HS6220_BANK0_DYNPD+HS6220_W_REGISTER; rf_data=0x08;rf_write_onebyte();//四线通信

	rf_ce_low();
	rf_reg=HS6220_BANK0_CONFIG+HS6220_W_REGISTER; rf_data=0x8b;rf_write_onebyte();// power up
	DelayCnt = 30;Delay100US();// wait 3 ms
	rf_reg=HS6220_BANK0_PMU_CTL+HS6220_W_REGISTER; rf_data=0xac;rf_write_onebyte();// HS6220_PWRDWN = 00
	DelayCnt = 20;Delay100US();// wait 2 ms
	rf_reg=HS6220_BANK0_FEATURE+HS6220_W_REGISTER; rf_data=0x10;rf_write_onebyte();// VCO_AMP_TX_MUX = b'0, A2 don't need config this bit

	rf_buf=Rf_Bank1; rf_bank_Switch();//切换到bank1

	rf_reg=HS6220_BANK1_TEST_PKDET+HS6220_W_REGISTER; rf_data=0x20;rf_write_onebyte();// pll_vdiv2_sel = 01, A2 don't need config this bit

	spi_csn=0;
	rf_buf=HS6220_BANK1_FAGC_CTRL_1+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[0]=0x01;
	rf_write_data_cnt=1;
	write_rf_data_buf();
    	spi_csn=1;
//************电机动作的时候 HS6220_BANK1_FAGC_CTRL_1按以下配置**********要先拉低CE，切换到Bank1去操作*****	
//*********** 6220为了提高抗干扰能力, 提高了 VCO的增益, 而这样做, 也增强了 本振泄露, 过认证又不好过了. 
//**********一个可行的解决办法:  接收小车在 马达转动的时候才提高VCO, 不转的时候恢复原来的值
 /*
	spi_csn=0;
	rf_buf=HS6220_BANK1_FAGC_CTRL_1+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[0]=0x0c;
	rf_write_data_cnt=1;
	write_rf_data_buf();
    	spi_csn=1; 
*/	
//************电机动作的时候 HS6220_BANK1_FAGC_CTRL_1按以上配置***************	

    	spi_csn=0;
	rf_buf=HS6220_BANK1_AGC_CTRL+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[1]=0xb2;
	rf_data_buf[0]=0xcf;
	rf_write_data_cnt=2;
	write_rf_data_buf();
    	spi_csn=1;

	rf_buf=Rf_Bank0; rf_bank_Switch();//切换到bank0
	rf_ce_high();
	DelayCnt = 2;Delay100US();// wait 100us
	rf_ce_low();// 一定要注意，校准的时候CE是低的

	while(1)
	{
		rf_reg=HS6220_BANK0_RF_SETUP+HS6220_R_REGISTER; rf_data=0x40;rf_read_onebyte();
		if(rf_buf&0x20)  break;
	}
	rf_reg=HS6220_BANK0_RF_SETUP+HS6220_W_REGISTER; rf_data=0x40;rf_write_onebyte();

	rf_buf=Rf_Bank1; rf_bank_Switch();//切换到bank1
    	spi_csn=0;
	rf_buf=HS6220_BANK1_CAL_CTL+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[2]=0x75;
	rf_data_buf[1]=0x98;
	rf_data_buf[0]=0x20;
	rf_write_data_cnt=3;
	write_rf_data_buf();
    	spi_csn=1;
	/* increase fitler agc threshold start (A2 don't need config this bit)*/
/*
	spi_csn=0;
	rf_buf=HS6220_BANK1_FAGC_CTRL_1+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[2]=0x05;
	rf_data_buf[1]=0xa0;
	rf_data_buf[0]=0x03;
	rf_write_data_cnt=3;
	write_rf_data_buf();
    spi_csn=1;

    spi_csn=0;
	rf_buf=HS6220_BANK1_AGC_CTRL+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[1]=0xb2;
	rf_data_buf[0]=0xcf;
	rf_write_data_cnt=2;
	write_rf_data_buf();
    spi_csn=1;
*/	
	/* increase fitler agc threshold end (A2 don't need config this bit)*/

/*    spi_csn=0;
	rf_buf=HS6220_BANK1_RF_IVGEN+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[2]=0x11;
	rf_data_buf[1]=0x04;
	rf_data_buf[0]=0x1f;
	rf_write_data_cnt=3;
	write_rf_data_buf();
    spi_csn=1;
*/
	rf_buf=Rf_Bank0; rf_bank_Switch();//切换到bank0

    	spi_csn=0;
	rf_buf=HS6220_BANK0_RX_ADDR_P0+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[0]=0x46;
	rf_data_buf[1]=0x0b;
	rf_data_buf[2]=0xaf;
	rf_data_buf[3]=0x43;
	rf_data_buf[4]=0x98;
	rf_write_data_cnt=5;
	write_rf_data_buf();
    	spi_csn=1;

    	spi_csn=0;
	rf_buf=HS6220_BANK0_TX_ADDR+HS6220_W_REGISTER;
	spi_Writeabyte();
	rf_data_buf[0]=0x46;
	rf_data_buf[1]=0x0b;
	rf_data_buf[2]=0xaf;
	rf_data_buf[3]=0x43;
	rf_data_buf[4]=0x98;
	rf_write_data_cnt=5;
	write_rf_data_buf();
    	spi_csn=1;

	rf_reg=HS6220_BANK0_FEATURE+HS6220_W_REGISTER; rf_data=0x10;rf_write_onebyte();
	rf_reg=HS6220_BANK0_EN_AA+HS6220_W_REGISTER; rf_data=0x00;rf_write_onebyte();
	rf_reg=HS6220_BANK0_CONFIG+HS6220_W_REGISTER; rf_data=0xfa;rf_write_onebyte();
	rf_reg=HS6220_BANK0_RX_PW_P0+HS6220_W_REGISTER; rf_data=rx_lenth;rf_write_onebyte();
	rf_reg=HS6220_BANK0_RF_CH+HS6220_W_REGISTER; rf_data=45;rf_write_onebyte();
	rf_reg=HS6220_BANK0_EN_RXADDR+HS6220_W_REGISTER; rf_data=0x03;rf_write_onebyte();//scramble_en = 0
	rf_reg=HS6220_BANK0_RF_SETUP+HS6220_W_REGISTER; rf_data=0x47;rf_write_onebyte();
//	rf_reg=HS6220_BANK0_DYNPD+HS6220_W_REGISTER; rf_data=0x07;rf_write_onebyte();

	clear_rf_status();
	flush_rx_fifo();    
	rf_ce_high();
}
//===============================================
//tx_rf_data
//===============================================
void rf_tx_data(void)
{
	byte repeat_send_cnt=10;

	rf_ce_low();
	flush_tx_fifo();
	clear_rf_status();
	spi_csn=0;
	rf_buf=HS6220_W_TX_PAYLOAD_NOACK;
     	spi_Writeabyte();
     	rf_write_data_cnt=rx_lenth;
	write_rf_data_buf();
	spi_csn=1;
	rf_ce_high();
	DelayCnt = 1;Delay100US();//


}
//===============================================
//rf_RecivePack
//===============================================  
extern byte rf_reset_cnt;
extern byte rf_sleep_cnt;
void rf_RecivePack(void)
{
//	rf_ce_low();
//	rf_reg=HS6220_BANK0_RF_CH+HS6220_R_REGISTER; rf_data=0x00;rf_read_onebyte();
	get_rf_status_flag();
	if(rf_buf&0x40) //rx_dr
	{   
	rf_reset_cnt=150;
	rf_sleep_cnt=10;
			
	 rf_reg = HS6220_R_RX_PL_WID | HS6220_R_REGISTER;   rf_data =0;rf_read_onebyte();
	 if(rf_buf==rx_lenth)  //16
	 {
		 rf_write_data_cnt=rf_buf;
		 spi_csn=0;
		 rf_buf=HS6220_R_RX_PAYLOAD;
		 spi_Writeabyte();
		 rf_write_data_cnt=rx_lenth;
		 read_rf_data_buf();
		 spi_csn=1;
	 }
	// 接收到数据并读取FIFO之后，这个操作必须的
	rf_ce_low();
	flush_rx_fifo();
	clear_rf_status();
	rf_ce_high(); // CE拉高等待下次数据到来

	}

	if(!rf_reset_cnt) // 如果300ms都没有收到1包数据，则复位RF重新初始化
	{

		init_rf();  
		rf_ce_low();
		rf_rx_set();
		rf_ce_high();		
		rf_reset_cnt=150;

	}
	if(!rf_sleep_cnt)// 如果20ms都没有收到1包数据，则让RF睡眠唤醒一次
	{
		
		rf_ce_low();
		flush_rx_fifo();
		clear_rf_status();
		rf_reg = HS6220_BANK0_PMU_CTL | HS6220_W_REGISTER;   rf_data =0xae;rf_write_onebyte();
		DelayCnt = 10;Delay100US();// 这里的1ms延时不可缺少，也不能小 
		rf_reg = HS6220_BANK0_PMU_CTL | HS6220_W_REGISTER;   rf_data =0xac;rf_write_onebyte();
		DelayCnt = 10;Delay100US();// 这里的1ms延时不可缺少，也不能小
		rf_ce_high(); 
		rf_sleep_cnt=10;
	}


}

/* 注意：最高位为载波使能位，设置了载波模式之后，CE要拉高，载波才会出来；
如果不要切换频点，功率等，就不要去在操作RF，否则会看不到载波信号的*/
void hs6220_carrier_mode(void)
{
	rf_ce_low();

	 spi_csn=0;
	 rf_buf=0x26;
     spi_Writeabyte();
	 rf_buf=0xc7;
     spi_Writeabyte();  
	 spi_csn=1;
	 spi_csn=0;
	 rf_buf=0x25;
     spi_Writeabyte();
	 rf_buf=45;
     spi_Writeabyte();  
	 spi_csn=1;
	 rf_ce_high();
	 while(1){
	 };


} 
