//------------------------------------------------------------------------------------
// HS6206.c
//------------------------------------------------------------------------------------
// Copyright 2014, HunterSun Electronics Co., Ltd.
// Yufeng. Yao
// 2014-01-16
//
// Program Description:
//
//
//
#include "uti.h"
#include "HS6220_RF.h"
#include ".\Sys\GF90F0320T.h"
#include "gpio.h"

#include ".\Sys\GF90F0320T.h"
#include "intrins.h"
#include ".\Sys\register.h"
#include ".\Sys\gpio.h"
#include ".\Sys\flash.h"
#include ".\Sys\timer.h"
#include ".\Hdw\HS6200_RF.h"
#include "led.h"
#include "uti.h"
#include "uart.h"
#include "stdio.h"
#include <string.h>
/* OM6220 模拟SPI(3,4线)接口初始化函数
  已经没有硬件CE的控制脚了，
  IRQ脚根据需要进行配置
*/

void HS6220_SPI_Init(void)
{
    P0M3 |= IOL_PUSHPULL_OUT;    
    P2M1 = IOH_PUSHPULL_OUT | IOL_PULLUP_IN;    
    P2M2 =IOH_PUSHPULL_OUT|  IOL_PUSHPULL_OUT;    
//    P2M3 |= IOH_PUSHPULL_OUT;    //P2.7 output
//    P1M0 |= IOL_PULLUP_IN;       //P1.0 input

	  
	HS6220_SCK_LOW;
	HS6220_SDIO_HIGH;
	HS6220_CSN_HIGH;
//	RF_SPI_CE_LOW; 
	//RF_SPI_CE_HIGH;  
	
//  GPIO_InitTypeDef GPIO_InitStruct;            
//	
//	GPIO_InitStruct.Pin = HS6220_CSN_PIN;           
//	GPIO_InitStruct.Mode = MODE_PP_OUT;           
//	GPIO_Init(HS6220_CSN_PORT,&GPIO_InitStruct);   
//	
//	GPIO_InitStruct.Pin = HS6220_SCK_PIN;           
//	GPIO_InitStruct.Mode = MODE_PP_OUT;           
//	GPIO_Init(HS6220_SCK_PORT,&GPIO_InitStruct);   
//		
////	GPIO_InitStruct.Pin = HS6220_MOSI_PIN;           
////	GPIO_InitStruct.Mode = MODE_PP_OUT;           
////	GPIO_Init(HS6220_MOSI_PORT,&GPIO_InitStruct);   

////	GPIO_InitStruct.Pin = HS6220_MISO_PIN;           	
////	GPIO_InitStruct.Mode = MODE_PP_OUT;           	
////	GPIO_Init(HS6220_MISO_PORT,&GPIO_InitStruct);    
//	
//	GPIO_InitStruct.Pin = HS6220_SDIO_PIN;           	
//	GPIO_InitStruct.Mode = MODE_PP_OUT;           	
//	GPIO_Init(HS6220_SDIO_PORT,&GPIO_InitStruct);   

////	GPIO_InitStruct.Pin = HS6220_IRQ_PIN;            	
////	GPIO_InitStruct.Mode = MODE_PU_IN;           	
////	GPIO_Init(HS6220_IRQ_PORT,&GPIO_InitStruct);  
//	
//	HS6220_SDIO_HIGH;
//	HS6220_CSN_HIGH;	
//	HS6220_SCK_LOW;
}

// 3线SPI写操作函数
void SPI_3wire_sendByte(unsigned char TxData)
{
	unsigned char i;
	unsigned char data_output_bit;
	
//	GPIO_InitTypeDef GPIO_InitStruct;  
//	
//	GPIO_InitStruct.Pin = HS6220_SDIO_PIN;           	
//	GPIO_InitStruct.Mode = MODE_PP_OUT;           	
//	GPIO_Init(HS6220_SDIO_PORT,&GPIO_InitStruct); //设置DIO为输出
	P2M1 = IOH_PUSHPULL_OUT | IOL_PULLUP_IN;
	
	for(i = 0; i < 8; i ++) 
	{
		data_output_bit = TxData & 0x80 ? 1 : 0;
		HS6220_SCK_LOW;
		if(data_output_bit){
			HS6220_SDIO_HIGH;
		}
		else{
			HS6220_SDIO_LOW;
		}

		HS6220_SCK_HIGH;
//		NOP_DELAY();
		TxData = TxData << 1;
	}

	HS6220_SDIO_LOW;
	HS6220_SCK_LOW;
//	NOP_DELAY();NOP_DELAY();NOP_DELAY();
}

// 3线SPI读操作函数
unsigned char SPI_3wire_readByte(void)
{
	unsigned char bit_ctr;
	unsigned char byte = 0;
	unsigned char temp = 0;
	
//	GPIO_InitTypeDef GPIO_InitStruct;  
//	
//	GPIO_InitStruct.Pin = HS6220_SDIO_PIN;           	
//	GPIO_InitStruct.Mode = MODE_FLOATING_IN;           	
//	GPIO_Init(HS6220_SDIO_PORT,&GPIO_InitStruct); // 设置DIO为输入

		P2M1 = IOH_PULLUP_IN | IOL_PULLUP_IN;
	
	for(bit_ctr = 0; bit_ctr < 8; bit_ctr ++) // output 8-bit
	{
		byte = byte << 1;
		HS6220_SCK_HIGH;  
		if(HS6220_SDIO_IN)
		{
				temp=1;
		}
		else
		{
				temp=0;
		}
	//	temp = HS6220_SDIO_IN;
		byte |= temp;          
		HS6220_SCK_LOW;               
	}

	return (byte); // return read byte
}

// 封装起来的对外可调用的SPI写函数
void SPI_SendByte(unsigned char Data)
{
#if (HS6220_SPI_NWIRE == SPI_3_WIRE)
	// 3线SPI写
	SPI_3wire_sendByte(Data);
#else
	// 4线SPI读写
	spi_4wire_wrd(Data);
#endif
}

// 封装起来的对外可调用的SPI读函数
unsigned char SPI_ReadByte(void)
{
#if (HS6220_SPI_NWIRE == SPI_3_WIRE)
	// 3线SPI读
	return SPI_3wire_readByte();
#else
	// 4线SPI读
	return spi_4wire_wrd(0);
#endif
}

// OM6220写一个寄存器一个值操作函数
void HS6220_write_byte(unsigned char addr,unsigned char D)
{
	HS6220_CSN_LOW;
	SPI_SendByte(HS6220_W_REGISTER | addr);
	SPI_SendByte(D);
	HS6220_CSN_HIGH;
}

// OM6220写一个寄存器多个数值操作函数
void HS6220_wr_buffer(unsigned char addr,const unsigned char* buf,unsigned char len)
{
	HS6220_CSN_LOW;
	SPI_SendByte(HS6220_W_REGISTER | addr);
	while(len--)
	{
		SPI_SendByte(*buf ++);
	}
	HS6220_CSN_HIGH;
}

// OM6220读一个寄存器一个值操作函数
unsigned char HS6220_read_byte(unsigned char addr)
{
	unsigned char rxdata;
	
	HS6220_CSN_LOW;
	SPI_SendByte(HS6220_R_REGISTER | addr);
	rxdata = SPI_ReadByte();
	HS6220_CSN_HIGH;
	
	return(rxdata);
}

// OM6220读一个寄存器多个值操作函数
void HS6220_read_buffer(unsigned char addr, unsigned char* buf, unsigned char len)
{
	HS6220_CSN_LOW;
	SPI_SendByte(HS6220_R_REGISTER | addr);
	
	while(len --)
	{
		*buf ++ = SPI_ReadByte();
	}
	HS6220_CSN_HIGH;
}

// OM6220直接发命令函数
void HS6220_Operation(unsigned char opt)
{	
	HS6220_CSN_LOW;
	SPI_SendByte(opt);
	HS6220_CSN_HIGH;
}


/* OM6220 初始化函数
第一版的模块，只做测试用，初始化的内容还有点多
改第二版之后，有些值会作为默认值，初始化内容就会少很多
*/
void HS6220_Init(void)
{
	xdata unsigned char temp[5];
	HS6220_SPI_Init();
	
l_rf_reset:	
	HS6220_write_byte(HS6220_BANK0_FEATURE, SOFT_RST); // soft_reset

#if (HS6220_SPI_NWIRE == SPI_4_WIRE) 
	// 默认是3线SPI的，如果要使用4线SPI，则上电之后要设置一下
	HS6220_write_byte(HS6220_BANK0_DYNPD, 0x08);
#else
	HS6220_write_byte(HS6220_BANK0_DYNPD, 0x00);
#endif

	HS6220_CE_Low();	
	HS6220_write_byte(HS6220_BANK0_CONFIG, 0x8b); // power up
	Delay1ms(3); // wait 3 ms
	HS6220_write_byte(HS6220_BANK0_PMU_CTL, 0xac); // HS6220_PWRDWN = 00
	Delay1ms(2);
    
	HS6220_write_byte(HS6220_BANK0_FEATURE, 0x10); // VCO_AMP_TX_MUX = b'0, A2 don't need config this bit

	HS6220_Bank_Switch(HS6220_Bank1);

	HS6220_write_byte(HS6220_BANK1_TEST_PKDET, 0x20); // pll_vdiv2_sel = 01, A2 don't need config this bit
    
	temp[2] = 0x05;
	temp[1] = 0xa0;
	temp[0] = 0x01;
	HS6220_wr_buffer(HS6220_BANK1_FAGC_CTRL_1, temp, 3);
    
	temp[1] = 0xb2;
	temp[0] = 0xcf;  
	HS6220_wr_buffer(HS6220_BANK1_AGC_CTRL, temp, 2);
	
	HS6220_Bank_Switch(HS6220_Bank0);

	HS6220_CE_High();
	Delay10us(10);
	HS6220_CE_Low(); // 一定要注意，校准的时候CE是低的

	temp[0] = 35;
	while(1)
	{	//
		if(HS6220_read_byte(HS6220_BANK0_RF_SETUP) & 0x20)
		{
			break;
		}
		Delay1ms(1);
		temp[0]--;
		if(0 == temp[0])
		{
			goto l_rf_reset;
		}
	}
	HS6220_write_byte(HS6220_BANK0_RF_SETUP, 0x40);  // cal_en = 0

	HS6220_Bank_Switch(HS6220_Bank1);	

	temp[2] = 0x75;  //bp_dac =1 bp_rc = 1
	temp[1] = 0x98;  // bp_vco_amp = 1 bp_vco_ldo=1
	temp[0] = 0x20;
	HS6220_wr_buffer(HS6220_BANK1_CAL_CTL, temp, 3);

	HS6220_Bank_Switch(HS6220_Bank0);	

	temp[0]=0x55;
	temp[1]=0x6E;
	temp[2]=0x54;
	temp[3]=0x9C;
	temp[4]=0x52;
	HS6220_wr_buffer(HS6220_BANK0_RX_ADDR_P0, temp, 5); // set address

	temp[0]=0x55;
	temp[1]=0x6E;
	temp[2]=0x54;
	temp[3]=0x9C;
	temp[4]=0x52;
	HS6220_wr_buffer(HS6220_BANK0_TX_ADDR, temp, 5);   //set address


	HS6220_write_byte(HS6220_BANK0_FEATURE, 0x00); 
	HS6220_write_byte(HS6220_BANK0_EN_AA, 0x00);
	HS6220_write_byte(HS6220_BANK0_CONFIG, 0xfb);
	HS6220_write_byte(HS6220_BANK0_RX_PW_P0, MAX_DATA_LENGTH);
	HS6220_write_byte(HS6220_BANK0_RF_CH, 02);
	HS6220_write_byte(HS6220_BANK0_EN_RXADDR, 0x01); // scramble_en = 0	
	HS6220_write_byte(HS6220_BANK0_RF_SETUP, 0x47);
	HS6220_write_byte(HS6220_BANK0_DYNPD, 0x06);
	
//	HS6220_write_byte(HS6220_BANK0_CONFIG, 0xfb);
//	HS6220_write_byte(HS6220_BANK0_RX_PW_P0, MAX_DATA_LENGTH);
//	HS6220_write_byte(HS6220_BANK0_DYNPD, 0x06);
//	HS6220_write_byte(HS6220_BANK0_FEATURE, 0x00); 
//	temp[0]=0x40;
//	temp[1]=0x5a;
//	temp[2]=0x80;
//	temp[3]=0x06;
//	temp[4]=0x00;
//	HS6220_wr_buffer(HS6220_BANK0_SETUP_VALUE, temp, 5);   //set address
//	HS6220_write_byte(HS6220_BANK0_PRE_GURD, 0x77); 	
//	HS6220_write_byte(HS6220_BANK0_EN_AA, 0x00);	
//	HS6220_write_byte(HS6220_BANK0_EN_RXADDR, 0x01);	
//	HS6220_write_byte(HS6220_BANK0_SETUP_RETR, 0x0f);	
//	HS6220_write_byte(HS6220_BANK0_RF_CH, 02);	
//	HS6220_write_byte(HS6220_BANK0_RF_SETUP, 0x47);

	HS6220_Clear_All_Irq();
	HS6220_Flush_Tx();	
	HS6220_ModeSwitch(HS6220_PTX_Mode);
	
	HS6220_CE_High();
//	while(1);			
}

/*OM6220 读写寄存器函数
 cmd = code; 
 D = data
 */
void HS6220_wr_cmd(unsigned char cmd,unsigned char D)
{
	HS6220_CSN_LOW;
	SPI_SendByte(cmd);
	SPI_SendByte(D);
	HS6220_CSN_HIGH;
}

// 切换OM6220 BANK
void HS6220_Bank_Switch(HS6220_Bank_TypeDef bank)
{
	unsigned char sta;
	
	sta = HS6220_read_byte(HS6220_BANK0_STATUS);
//	printf("hs6220_ble_init\n");
	printf("sta:%x\r\n",sta);  
	Uart1_SendOneByte(sta);
	if(bank != HS6220_Bank0)
	{
		if(!(sta & HS6220_Bank1))
		{
			HS6220_wr_cmd(HS6220_ACTIVATE, HS6220_ACTIVATE_DATA);
		}
	}
	else
	{
		if(sta & HS6220_Bank1)
		{
			HS6220_wr_cmd(HS6220_ACTIVATE, HS6220_ACTIVATE_DATA);
		}
	}
}

// OM6220 切换速率
void HS6220_Change_Rate(HS6220_Rate_TypeDef rate)
{
	unsigned char tmp;
	
	tmp = HS6220_read_byte(HS6220_BANK0_RF_SETUP);

	if(rate == Rate_1M)
	{
		tmp &= 0xf7;
		HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
	}
	else if(rate == Rate_2M)
	{
		tmp |= 0x08;
		HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
	}
}

// OM6220 切换信道
void HS6220_Change_CH(unsigned char chn)
{
	if(chn < 0x80)
		HS6220_write_byte(HS6220_BANK0_RF_CH, chn);
}

// OM6220 切换功率
void HS6220_Change_Pwr(HS6220_Pwr_TypeDef pwr)
{
	unsigned char tmp;

	tmp = HS6220_read_byte(HS6220_BANK0_RF_SETUP);
	tmp &= ~0x47;

	switch (pwr)
	{
		case Pwr_8db:
			tmp |= 0x47;
			HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		break;

		case Pwr_5db:
			tmp |= 0x40;
			HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		break;

		case Pwr_4db:
			tmp |= 0x07;
			HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		break;

		case Pwr_0db:
			tmp |= 0x03;
			HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		break;

		case Pwr_n6db:
			tmp |= 0x01;
			HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		break;
	
		default: // 默认就设置成0db
			tmp |= 0x03;
			HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		break;
	}
}

// OM6220 切换地址
void HS6220_Change_Addr(unsigned char *buf, unsigned char len)
{
	if(len <= 6)
	HS6220_wr_buffer(HS6220_BANK0_RX_ADDR_P0, buf, len); // set address
}


/*OM6220 接收数据包函数
buf：读取到的数据存放的地方
return：正常读取之后，返回的是读取到的数据包长度
*/
unsigned char rf_sleep_cnt;
unsigned short int rf_reset_cnt;
unsigned char HS6220_ReceivePack(unsigned char *buf)
{
	unsigned char sta;
	unsigned char fifo_sta;
	unsigned char len;

	sta = HS6220_read_byte(HS6220_BANK0_STATUS);

	if(HS6220_STATUS_RX_DR & sta)
	{
			rf_reset_cnt=rf_reset_time;
			rf_sleep_cnt=rf_sleep_time;
		do
		{
			len = HS6220_read_byte(HS6220_R_RX_PL_WID);
			
			if(len <= HS6220_FIFO_MAX_PACK_SIZE)
			{
				HS6220_read_buffer(HS6220_R_RX_PAYLOAD, buf, len);
			}
			else
			{
				HS6220_Flush_Rx();
			}
			
			fifo_sta = HS6220_read_byte(HS6220_BANK0_FIFO_STATUS);
		}while(!(fifo_sta & HS6220_FIFO_STA_RX_EMPTY));/*not empty continue read out*/ 
		
		HS6220_write_byte(HS6220_BANK0_STATUS, sta);/*clear irq*/
		HS6220_Clear_All_Irq();
		HS6220_Flush_Tx();
		HS6220_Flush_Rx();		
		return len;
	}

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

//	if(rf_sleep_cnt==0)// 如果20ms都没有收到1包数据，则让RF睡眠唤醒一次
//	{
//		
//		HS6220_CE_Low();
//		HS6220_Flush_Rx();
//		HS6220_Clear_All_Irq();
//		
//		HS6220_write_byte(HS6220_BANK0_PMU_CTL, 0xae);		
//		Delay1ms(1);// 这里的1ms延时不可缺少，也不能小 
//		HS6220_write_byte(HS6220_BANK0_PMU_CTL, 0xac);
//		Delay1ms(1);// 这里的1ms延时不可缺少，也不能小
//		HS6220_CE_High(); 
//		rf_sleep_cnt=10;
//	}
	
	return 0;
}


/* OM6220发送数据包函数
  buf:要发送的数据包内容指针 
  len:数据包的长度，从1到32字节 
  cmd: 发送数据包的命令，HS6220_W_TX_PAYLOAD和HS6220_W_TX_PAYLOAD_NOACK
*/
void HS6220_SendPack(unsigned char cmd, unsigned char* buf, unsigned char len)
{
	unsigned char sta;
	
	sta = HS6220_read_byte(HS6220_BANK0_STATUS);
	if(!(sta & HS6220_STATUS_TX_FULL))
	{
		HS6220_wr_buffer(cmd, buf, len);
	}
}

// OM6220 切换RF工作模式函数
void HS6220_ModeSwitch(HS6220_ModeTypeDef mod)
{
	unsigned char tmp;
	
	tmp = HS6220_read_byte(HS6220_BANK0_CONFIG);
	if(mod != HS6220_PRX_Mode)
	{
		tmp &= 0xFE;
	}
	else
	{
		tmp |= 0x01;
	}
	HS6220_write_byte(HS6220_BANK0_CONFIG, tmp);

	if(mod == HS6220_Carrier_Mode)
	{
		tmp = 0Xc7;//0x80 | HS6220_read_byte(HS6220_BANK0_RF_SETUP);
		HS6220_write_byte(HS6220_BANK0_RF_SETUP, tmp);
		/* 注意：最高位为载波使能位，设置了载波模式之后，CE要拉高，载波才会出来；
		   如果不要切换频点，功率等，就不要去在操作RF，否则会看不到载波信号的*/
	}
}

// OM6220 清中断标志
void HS6220_Clear_All_Irq(void)
{
	HS6220_write_byte(HS6220_BANK0_STATUS, 0x70);
}

// OM6220 清空TX FIFO
void HS6220_Flush_Tx(void)
{
	HS6220_Operation(HS6220_FLUSH_TX);
}

// OM6220 清空RX FIFO
void HS6220_Flush_Rx(void)
{
	HS6220_Operation(HS6220_FLUSH_RX);
}

// OM6220 CE拉高
void HS6220_CE_High(void)
{
	HS6220_Operation(HS6220_CMD_CE_HIGH);;
}

// OM6220 CE拉低
void HS6220_CE_Low(void)
{
	HS6220_Operation(HS6220_CMD_CE_LOW);
}
void HS6220_RF_CE_High_Pulse(void)
{
	//RFCON |=RFSPI_CE;
	HS6220_CE_High();
	Delay10us(8);
	//RFCON &=~RFSPI_CE;	
	HS6220_CE_Low();
}
// 读取MO6220接收到的数据包长度的函数
unsigned char HS6220_read_payload_length(void)
{
	return HS6220_read_byte(HS6220_R_RX_PL_WID);
}

