#include "main.h"
#include "bc3603.h"
#include <string.h>
#include "application.h"

#define _RECEIVER_PDLEN_ 63

/** 
 * 模组基本参数定义
 */
typedef struct 
{
	bool    is_tx;
	bool    is_rx;	
	uint8_t rx_buffer[255];
	uint8_t rx_length;
	int8_t  rx_rssi;
}context_ewm47_t;

/** 
 * 模组默认配置
 */
static context_ewm47_t context_ewm47 = {
	.is_tx     = false,
	.is_rx     = false,	
	.rx_length = 0,
};

static volatile uint8_t IRQStatus;

/**
 * @brief  模组初始化
 */
void ewm47_demo_init( void )
{
	uint8_t							Syncw[SYNCWORD_MAX_SIZE];
	RF_InitTypeDef	    RF_InitStruct;	
	
	/* BC3603 default register configuration */
	if( BC3603_DeInit() != BC3603_SUCCESS)
	{
		while(1);//出错
	}	
	/* BC3603 RF parameter configuration */

	/* Config by <rf_parameter.h> */
	RF_InitStruct.RFBand = BAND433M;
	RF_InitStruct.Frequency = 433000;      //单位KHz 433000 = 433.000MHz
	RF_InitStruct.TxPower = TXPOWER19DBM;  //发送功率
	RF_InitStruct.DataRate = DATARATE2K;  //空中速率
	RF_InitStruct.TxPremLength = 4;
	RF_InitStruct.TxPremClass = PMSYNCMSB;
	RF_InitStruct.TxPremPattern = 0xAAAA;	
	RF_InitStruct.SyncWordWidth = SYNCLEN6BYTE;
	RF_InitStruct.TrailerField = BC3603_DISABLE;
	RF_InitStruct.HeadField = HEAD_8BIT;
	RF_InitStruct.LengthField = BC3603_ENABLE;
	RF_InitStruct.CRCField = CRC_CCIT16;
	RF_InitStruct.CRCInv = CRC_NONINVERTED;
	RF_InitStruct.CRCBitOD = CRC_MSB_FIRST;
	RF_InitStruct.CRCByteOD = CRC_HIGH_FIRST;
	RF_InitStruct.CRCSeed = 0xFFFF;	
	RF_InitStruct.ManchesterCode = BC3603_DISABLE;
	RF_InitStruct.HammingCode = BC3603_DISABLE;
	RF_InitStruct.HeadAddrExamine = BC3603_DISABLE;
	RF_InitStruct.WhiteningCodec = WHT_OFF;
	RF_InitStruct.WhiteningSeed = 0x3B;
	RF_InitStruct.ReceiverMode = RECEIVER_SINGLE;
	RF_InitStruct.AutomaticACK = BC3603_DISABLE;
	RF_InitStruct.TimeUnit = ATRTU_250US;
	
	/* RF enter light sleep */
	BC3603_EnterLightSleep();	
	/* wait crystal ready */
	if(BC3603_WaitCrystalReady() != BC3603_SUCCESS)	
	{
		while(1);//出错
	}
	/* RF set crysatal tune */
	BC3603_SetCrystalCload(1,3);
	/* RF packet */
	if(BC3603_Configures(&RF_InitStruct) != BC3603_SUCCESS) 
	{
		while(1);//出错
	}		

	BC3603_SetReceiverLength( _RECEIVER_PDLEN_ );
	BC3603_SetHeaderAddress(0x00);	
	
	/* RF SYNC */
	*((uint16_t *)(&Syncw[0])) = _SYNCWORD_LOW_ & 0xFFFF;
	*((uint16_t *)(&Syncw[2])) = _SYNCWORD_LOW_ >> 16;
	*((uint16_t *)(&Syncw[4])) = _SYNCWORD_HIGH_ & 0xFFFF;
	*((uint16_t *)(&Syncw[6])) = _SYNCWORD_HIGH_ >> 16;

	BC3603_SetSyncWord(Syncw,SYNCWORD_MAX_SIZE);	

	/* LIRC calibartion */
	if(BC3603_LIRCCalibration() != BC3603_SUCCESS)
	{
		while(1);//出错
	}		

	/* enter deep sleep */
	BC3603_EnterDeepSleep();	
	
}

/**
 * @brief 使用显示菜单用户配置参数重新配置模组
 *
 * @param config 菜单配置参数信息
 */
void ewm47_demo_menu_config( menu_config_t *config )
{
	uint8_t							Syncw[SYNCWORD_MAX_SIZE];
	RF_InitTypeDef	    RF_InitStruct;	
	
	/* BC3603 RF parameter configuration */
	/* 用户菜单设定超过470M就重新划分频段 */
	RF_InitStruct.RFBand = (config->frequency_mhz > 470)? BAND470M : BAND433M;
	/* 用户菜单设定频率转换 */
	RF_InitStruct.Frequency = config->frequency_mhz * 1000;      //单位KHz 
	/* 用户菜单设定功率转换 */
	switch ( config->tx_power )
	{
		case 19:
			RF_InitStruct.TxPower = TXPOWER19DBM; 
		  break;
		case 17:
			RF_InitStruct.TxPower = TXPOWER17DBM;  
		  break;
		case 13:
			RF_InitStruct.TxPower = TXPOWER13DBM; 
		  break;
		case 10:
			RF_InitStruct.TxPower = TXPOWER10DBM;
		  break;
		case 0:
			RF_InitStruct.TxPower = TXPOWER0DBM;
		  break;		
	}
	/* 用户菜单设定速率转换 */
	switch ( config->data_rate )
	{
		case 250:
			RF_InitStruct.DataRate = DATARATE250K; 
		  break;
		case 125:
			RF_InitStruct.DataRate = DATARATE125K; 
		  break;
		case 50:
			RF_InitStruct.DataRate = DATARATE50K; 
		  break;
		case 10:
			RF_InitStruct.DataRate = DATARATE10K; 
		  break;
		case 2:
			RF_InitStruct.DataRate = DATARATE2K;  //发送功率
		  break;		
	}	

	RF_InitStruct.TxPremLength = 4;
	RF_InitStruct.TxPremClass = PMSYNCMSB;
	RF_InitStruct.TxPremPattern = 0xAAAA;	
	RF_InitStruct.SyncWordWidth = SYNCLEN6BYTE;
	RF_InitStruct.TrailerField = BC3603_DISABLE;
	RF_InitStruct.HeadField = HEAD_8BIT;
	RF_InitStruct.LengthField = BC3603_ENABLE;
	RF_InitStruct.CRCField = CRC_CCIT16;
	RF_InitStruct.CRCInv = CRC_NONINVERTED;
	RF_InitStruct.CRCBitOD = CRC_MSB_FIRST;
	RF_InitStruct.CRCByteOD = CRC_HIGH_FIRST;
	RF_InitStruct.CRCSeed = 0xFFFF;	
	RF_InitStruct.ManchesterCode = BC3603_DISABLE;
	RF_InitStruct.HammingCode = BC3603_DISABLE;
	RF_InitStruct.HeadAddrExamine = BC3603_DISABLE;
	RF_InitStruct.WhiteningCodec = WHT_OFF;
	RF_InitStruct.WhiteningSeed = 0x3B;
	RF_InitStruct.ReceiverMode = RECEIVER_SINGLE;
	RF_InitStruct.AutomaticACK = BC3603_DISABLE;
	RF_InitStruct.TimeUnit = ATRTU_250US;
	
	/* RF enter light sleep */
	BC3603_EnterLightSleep();	
	/* wait crystal ready */
	if(BC3603_WaitCrystalReady() != BC3603_SUCCESS)	
	{
		while(1);//出错
	}
	/* RF set crysatal tune */
	BC3603_SetCrystalCload(1,3);
	/* RF packet */
	if(BC3603_Configures(&RF_InitStruct) != BC3603_SUCCESS) 
	{
		while(1);//出错
	}		

	BC3603_SetReceiverLength( _RECEIVER_PDLEN_ );
	BC3603_SetHeaderAddress(0x00);	
	
	/* RF SYNC */
	*((uint16_t *)(&Syncw[0])) = _SYNCWORD_LOW_ & 0xFFFF;
	*((uint16_t *)(&Syncw[2])) = _SYNCWORD_LOW_ >> 16;
	*((uint16_t *)(&Syncw[4])) = _SYNCWORD_HIGH_ & 0xFFFF;
	*((uint16_t *)(&Syncw[6])) = _SYNCWORD_HIGH_ >> 16;

	BC3603_SetSyncWord(Syncw,SYNCWORD_MAX_SIZE);	

	/* LIRC calibartion */
	if(BC3603_LIRCCalibration() != BC3603_SUCCESS)
	{
		while(1);//出错
	}		

	/* enter deep sleep */
	BC3603_EnterDeepSleep();		
	
}


/**
 * @brief 向模组写入数据并开始发射
 *
 * @param buffer 指向数据缓存
 * @param length 写入长度
 */
void ewm47_demo_transmit( uint8_t *buffer , uint8_t length )
{
	/* RF enter light sleep */
	BC3603_EnterLightSleep();		
	/* wait crystal ready */
	BC3603_WaitCrystalReady();
	/* set RF TX IRQ enable */
	BC3603_IRQConfig(IRQ_TXCMPIE,BC3603_ENABLE);
	/* set buffer */
	BC3603_WriteTransmitPayload(buffer,length);
	/* set TX start */
	BC3603_EnterTransmit(0);
	
	
	/* 设置发送标记 */
	context_ewm47.is_tx = true;
	/* (可选) LED TX指示 */
	gpio_led_tx_on();	
}


/**
 * @brief  模组切换到持续接收状态
 */
void ewm47_demo_receive( void )
{
	/* RF enter light sleep */
	BC3603_EnterLightSleep();		
	/* wait crystal ready */
	BC3603_WaitCrystalReady();
	/* set RF RX IRQ enable */
	BC3603_IRQConfig(IRQ_RXCMPIE|IRQ_RXERRIE,BC3603_ENABLE);
	/* set RX payload length */
	BC3603_SetReceiverLength(_RECEIVER_PDLEN_);	
	/* reset rf fifo point */
	BC3603_ResetRxFIFOPosition();
	/* RF enter receive mode */
	BC3603_EnterReceiver();	
}	

/**
 * @brief  查询是否有接收数据
 *
 * @param   buffer 指向待拷贝数据缓存
 * @param   length 接收数据长度
 * @return  bool 有新接收数据则返回true; 否则返回false。
 */
bool  ewm47_demo_check_rx_done( uint8_t *buffer, uint8_t * length  , int8_t *rssi)
{
    uint8_t ret = 0;

    if( context_ewm47.is_rx  )
    {
        context_ewm47.is_rx = 0;

        memcpy( buffer,  context_ewm47.rx_buffer, context_ewm47.rx_length );

        *length = context_ewm47.rx_length;
        context_ewm47.rx_length = 0;

        *rssi = context_ewm47.rx_rssi;
        context_ewm47.rx_rssi = 0;

        ret = 1;
    }
		
    return ret;	
}

/**
 * @brief  模组引脚中断响应
 *
 * @note 与收发函数内的中断配置关联，默认仅实现了发送完成与接收完成
 */
void ewm47_demo_gio_interrupt_callback(void)
{
	IRQStatus = BC3603_GetIRQFlag();
	
	if( IRQStatus & IRQ_TXCMPIE )
	{
			/* 清除发送标记 */
			context_ewm47.is_tx = false;
		
			ewm47_demo_receive();
		
			/* (可选) LED TX指示 */
			gpio_led_tx_off();		
	}
	
	if(IRQStatus & (IRQ_RXCMPIE|IRQ_RXERRIE))
	{
			/* read data */
			context_ewm47.rx_length = BC3603_ReadReceiverPayload(context_ewm47.rx_buffer);
			/* read rssi result */
			context_ewm47.rx_rssi = -BC3603_GetSYNCRSSIValue();
			
			/* RX ERROR PROC */
			if(IRQStatus & IRQ_RXERRIE)
			{

			}
			/* RX DONE PROC */
			else
			{
					/* 标记接收 */
					context_ewm47.is_rx = true;
					
					/* (可选) LED RX指示 */
					gpio_led_rx_on();			
			}
			
			ewm47_demo_receive();

	}
	
	BC3603_ClearIRQFlag(IRQStatus);
}

