/**
  ************************************* Copyright ****************************** 
  *
  *                 Copyright (C), 2012-2016, Radioway Tech. Co., Ltd.
  *                            All Rights Reserved
  *
  *    
  * FileName   : radio.c
  * Version    : v1.0
  * Author     : Heb
  * Date       : 2024-06-27
  * Description: 
  * Function List: 
  	1. ....
          <version>: 
     <modify staff>: 
             <data>: 
      <description>: 
  	2. ...
  ******************************************************************************
 */

#include "board.h"
#include "hs6220_reg.h"
#include "radio.h"




static uint8_t rf_rx_payload[32];

uint32_t rf_sleep_cnt=20;
uint32_t rf_reset_cnt=300;

static void hs6220_delay_us(__IO uint32_t us)
{		
	u16 i=0;   
	while(us--)   
	{
		i=10;  //自己定义      
		while(i--);       
	}					 
}

static void hs6220_delay_ms(__IO uint32_t ms)
{		
	delay_ms(ms);					 
}

// OM6220直接发命令函数
static void hs6220_operation(uint8_t opt)
{	
	HS6220_CSN_LOW;
	spi_inout(opt);
	HS6220_CSN_HIGH;
}

static void hs6220_write_buffer(uint8_t addr,const uint8_t* buf,uint8_t len)
{
	HS6220_CSN_LOW;
	spi_inout(HS6220_W_REGISTER | addr);
	while(len--)
	{
		spi_inout(*buf ++);
	}
	HS6220_CSN_HIGH;
}

// OM6220写一个寄存器一个值操作函数
void hs6220_write(uint8_t addr,uint8_t data)
{
	hs6220_write_buffer(addr, &data, 1);
}

static void hs6220_read_buffer(uint8_t addr, uint8_t *buffer, uint8_t size)
{
	HS6220_CSN_LOW;
	spi_inout(HS6220_R_REGISTER|addr);
	
	for(uint8_t i = 0; i < size; i++ )
	{
		buffer[i] = spi_inout(0);
	}
	HS6220_CSN_HIGH;
}

static uint8_t hs6220_read( uint8_t addr )
{
    uint8_t data;
    hs6220_read_buffer( addr, &data, 1 );
    return data;
}

static void hs6220_write_cmd(uint8_t cmd,uint8_t data)
{
	HS6220_CSN_LOW;
	spi_inout(cmd);
	spi_inout(data);
	HS6220_CSN_HIGH;
}

// 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_ce_high_pulse(void)
{
	hs6220_operation(HS6220_CMD_CE_HIGH);
	hs6220_delay_us(300);
	hs6220_operation(HS6220_CMD_CE_LOW);	
}

/*Clear All Irq*/
void hs6220_clear_all_irq(void)
{
	hs6220_write(HS6220_BANK0_STATUS, 0x70);
}

/*Flush Rx*/
void hs6220_flush_rx(void)
{
	hs6220_operation(HS6220_FLUSH_RX);
}

/*Flush Tx*/
void hs6220_flush_tx(void)
{
	hs6220_operation(HS6220_FLUSH_TX);
}

void hs6220_bank_switch(hs6220_bank_type_t bank)
{
	uint8_t sta;
	
	sta = hs6220_read(HS6220_BANK0_STATUS);
	
	if(bank != HS6220_Bank0)
	{
		if(!(sta & HS6220_Bank1))
		{
			hs6220_write_cmd(HS6220_ACTIVATE, HS6220_ACTIVATE_DATA);
		}
	}
	else
	{
		if(sta & HS6220_Bank1)
		{
			hs6220_write_cmd(HS6220_ACTIVATE, HS6220_ACTIVATE_DATA);
		}
	}
}

// OM6220 切换RF工作模式函数
void hs6220_mode_switch(hs6220_mode_type_t mod)
{
	uint8_t tmp;
	
	tmp = hs6220_read(HS6220_BANK0_CONFIG);
	if(mod != HS6220_PRX_Mode)
	{
		tmp &= 0xFE;
        tmp |= (MASK_RX_DR|MASK_TX_DS|MASK_MAX_RT);
	}
	else
	{
		tmp |= 0x01;
        tmp &= ~(MASK_RX_DR|MASK_MAX_RT);
	}
	hs6220_write(HS6220_BANK0_CONFIG, tmp);

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

void hs6220_init(void)
{
    uint8_t temp[5];
    unsigned char count;

reset_rf_int:	
    hs6220_write(HS6220_BANK0_FEATURE, SOFT_RST); // soft_reset
    
	// 默认是3线SPI的，如果要使用4线SPI，则上电之后要设置一下
	hs6220_write(HS6220_BANK0_DYNPD, 0x08);    

    hs6220_ce_low();	
	hs6220_write(HS6220_BANK0_CONFIG, 0x8b); // power up
	hs6220_delay_ms(3); // wait 3 ms
	hs6220_write(HS6220_BANK0_PMU_CTL, 0xac); // HS6220_PWRDWN = 00
	hs6220_delay_ms(2);
    
    hs6220_write(HS6220_BANK0_FEATURE, 0x10); // VCO_AMP_TX_MUX = b'0, A2 don't need config this bit
	hs6220_write(HS6220_BANK0_RF_CH, 0x28); // VCO_AMP_TX_MUX = b'0, A2 don't need config this bit
	
	hs6220_bank_switch(HS6220_Bank1);

	hs6220_write(HS6220_BANK1_TEST_PKDET, 0x24); // pll_vdiv2_sel = 01, A2 don't need config this bit
    
//	temp[2] = 0x05;
	//temp[1] = 0xa0;
	temp[0] = 0x0c;
	hs6220_write_buffer(HS6220_BANK1_FAGC_CTRL_1, temp, 1);
    
	temp[1] = 0xb2;
	temp[0] = 0xcf;  
	hs6220_write_buffer(HS6220_BANK1_AGC_CTRL, temp, 2);
    
    hs6220_bank_switch(HS6220_Bank0);

	hs6220_ce_high();
	hs6220_delay_us(300);
	hs6220_ce_low(); // 一定要注意，校准的时候CE是低的
    
	count = 35;
	while(1)   //wait cal done
	{	
		if( (hs6220_read(HS6220_BANK0_RF_SETUP) & 0x20) )
		{
			break;
		}
				
		delay_ms(1);
		count--;
		if(!count)
		{
			goto reset_rf_int;
		}
	
	}
	
    
    
	hs6220_write(HS6220_BANK0_RF_SETUP, 0x40);  // cal_en = 0

	hs6220_write(HS6220_BANK0_FEATURE, 0x48);	
    
	hs6220_write(HS6220_BANK0_DYNPD, 0x0F);	
	hs6220_write(HS6220_BANK0_PRE_GURD, 0x67);
	
	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_write_buffer(HS6220_BANK1_CAL_CTL, temp, 3);
	
	temp[2] = 0x11;
	temp[1] = 0x04;  
	temp[0] = 0x1D;    
	hs6220_write_buffer(HS6220_BANK1_RF_IVGEN, temp, 3); // xtal_cc = 0x1d
	
	
	hs6220_bank_switch(HS6220_Bank0);	
	
	hs6220_write(HS6220_BANK0_PRE_GURD, 0x76);	
	hs6220_write(HS6220_BANK0_SETUP_VALUE, 0xff); // rx timeout 
	hs6220_write(HS6220_BANK0_CONFIG_EXT, 0x24); // 边写tx fifo 边发送, 使能hs6220内部计数器
	
//	HS6220_write_byte(HS6220_BANK0_BLE_SETUP_DELAY, 0xf0);		

	temp[0]=0x55;
	temp[1]=0x6E;
	temp[2]=0x54;
	temp[3]=0x9C;
	temp[4]=0x52;
	hs6220_write_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_write_buffer(HS6220_BANK0_TX_ADDR, temp, 5);   //set address

	hs6220_write(HS6220_BANK0_FEATURE, 0x00); 
	hs6220_write(HS6220_BANK0_EN_AA, 0x00);
	hs6220_write(HS6220_BANK0_CONFIG, 0xfb);
	hs6220_write(HS6220_BANK0_RX_PW_P0, 16);
	hs6220_write(HS6220_BANK0_RF_CH, 45);
	hs6220_write(HS6220_BANK0_EN_RXADDR, 0x01); // scramble_en = 0	
	hs6220_write(HS6220_BANK0_RF_SETUP, 0x47);
    
    uint8_t REG = hs6220_read(HS6220_BANK0_RF_SETUP);
    
	hs6220_write(HS6220_BANK0_DYNPD, 0x0E);
    
    REG = hs6220_read(HS6220_BANK0_DYNPD);
    
    hs6220_ce_low();
    hs6220_clear_all_irq();
//	hs6220_flush_rx();	
    hs6220_flush_tx();
	hs6220_mode_switch(HS6220_PRX_Mode);
    hs6220_ce_high();
}



uint8_t hs6220_receive_pack(uint8_t *buf)
{
    uint8_t sta;
	uint8_t len = 0;
    
    sta = hs6220_read(HS6220_BANK0_STATUS);
    if(HS6220_STATUS_RX_DR & sta)
    {
        len = hs6220_read(HS6220_R_RX_PL_WID);
        hs6220_write(HS6220_BANK0_STATUS, sta);/*clear irq*/
        if (len == 16)
        {
            hs6220_read_buffer(HS6220_R_RX_PAYLOAD, buf, 16);
        }
        
        rf_sleep_cnt=20;
        rf_reset_cnt=300;
    }
    
    if(sta & (HS6220_STATUS_RX_DR | HS6220_STATUS_TX_DS | HS6220_STATUS_MAX_RT))
	{
		hs6220_write(HS6220_BANK0_STATUS, sta);/*clear irq*/
	}
    
		/* 以下的复位RF和让RF睡眠唤醒的动作是必须的，不可缺少 */	
	if(rf_reset_cnt==0) // 如果300ms都没有收到1包数据，则复位RF重新初始化
	{
		rf_sleep_cnt=20;
		rf_reset_cnt=300;				
        hs6220_init();
	}

	if(rf_sleep_cnt==0)// 如果20ms都没有收到1包数据，则让RF睡眠唤醒一次
	{
        hs6220_ce_low();
		hs6220_clear_all_irq();
        hs6220_flush_rx();
        hs6220_flush_tx();
		
		hs6220_write(HS6220_BANK0_PMU_CTL, 0xae);		
		hs6220_delay_ms(1);// 这里的1ms延时不可缺少，也不能小 
		hs6220_write(HS6220_BANK0_PMU_CTL, 0xac);
		hs6220_delay_ms(1);// 这里的1ms延时不可缺少，也不能小
		hs6220_ce_high();
		rf_sleep_cnt=20;		
	}
    /* 以上的复位RF和让RF睡眠唤醒的动作是必须的，不可缺少 */	
	return len;
}


void hs6220_send(uint8_t *buff, uint16_t size)
{
    hs6220_ce_low();
    
    hs6220_mode_switch(HS6220_PTX_Mode);
    hs6220_clear_all_irq();
    hs6220_flush_tx();
    hs6220_write_buffer(HS6220_W_TX_PAYLOAD_NOACK, buff, size);
    hs6220_ce_high_pulse();
}

void rf_int(void)
{
	if(rf_sleep_cnt) rf_sleep_cnt--;
	if(rf_reset_cnt) rf_reset_cnt--;	
}






