#include <string.h>
#include "delay.h"
#include "DebugDataDefine.h"
#include "CommandsDefine.h"
#include "AnalogChannelCtrl_Dictionary.h"
#include "ProjectConfig.h"
#include "Probe_MSO7000X_2d5g.h"
#include "AnalogChannelCtrl_2d5g_base.h"
#include "Helper.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////
// 			2203/5/X GHz_ljw 合并版,业务逻辑下沉  模拟通道控制
//////////////////////////////////////////////////////////////////////////////

u8 Get4094CtrlWord(struct Paras595 params, u32* ctrlWord)
{
	u32 _ctrlWord = 0;
	u8 _isHigh = 0;
	// 带宽
	
	if(params.bandwidth == 0xFFFF)//FULL
	{
		_ctrlWord|=bwCtrlWords[0];
	}
	else if(params.bandwidth == 1000) //1GHz
	{
		_ctrlWord|=bwCtrlWords[1];
	}
	else if(params.bandwidth == 500) //500MHz
	{
		_ctrlWord|=bwCtrlWords[2];
	}
	else if(params.bandwidth == 20) //20MHz
	{
		_ctrlWord|=bwCtrlWords[3];
	}
	else
	{
		return 0; //error
	}
	
	// 阻抗
	if(params.coupling == 0 && params.high_low == 1)//DC50
	{
		_ctrlWord|=coupleCtrl_4094[0];
	}
	else if(params.coupling == 0 && params.high_low == 0)//DC1M
	{
		_ctrlWord|=coupleCtrl_4094[1];
		_isHigh = 1;
	}
	else if(params.coupling == 1 && params.high_low == 0)//AC1M
	{
		_ctrlWord|=coupleCtrl_4094[2];
		_isHigh  = 1;
	}
	else
	{
		return 0; //error
	}
	
	//衰减
	if(_isHigh)
	{
		if(params.att==1||params.att==0) //不衰减
		{
			_ctrlWord|=0;
		}
		else if(params.att==ATTLV2)
		{
			_ctrlWord|=impCtrlBit;
		}
		else if(params.att==ATTLV1)
		{
			_ctrlWord|=relayCtrlBit2;
		}
		else if(params.att==ATTLV1*ATTLV2)
		{
			_ctrlWord|=impCtrlBit|relayCtrlBit2;
		}
		else
		{
			return 0; //error
		}
	}
	else
	{
		if(params.att==1||params.att==0) //不衰减
		{
			_ctrlWord|=0;
		}
		else if(params.att==ATTLV1)
		{
			_ctrlWord|=impCtrlBit;
		}
		else if(params.att==ATTLV2)
		{
			_ctrlWord|=impCtrlBit|relayCtrlBit2;
		}
		else if(params.att==ATTLV1*ATTLV2)
		{
			_ctrlWord|=impCtrlBit|relayCtrlBit2;
		}
		else
		{
			return 0; //error
		}
	}
	
	
	ctrlWord[0]=_ctrlWord;
	return 1;
}
u8 AnalogChannelSet_Check_Len(u16 dataLen)
{
	if(dataLen<PACKAGE_CHANNELSET_DATA_BYTES+PACKAGE_CHANNELSET_INDEX_BYTES+PACKAGE_CHANNELSET_CHECK_AREA_BYTES+PACKAGE_CHANNELSET_FRAMEID_BYTES)
	{
		return 0;
	}
	if((dataLen-PACKAGE_CHANNELSET_INDEX_BYTES-PACKAGE_CHANNELSET_CHECK_AREA_BYTES-PACKAGE_CHANNELSET_FRAMEID_BYTES)%PACKAGE_CHANNELSET_DATA_BYTES!=0)
	{
		return 0;
	}
	return 1;
}
/*
u32 GetDACConfigWord(struct ParasDAC params,u8* dac_index)
{
	u32 ConfigWord;
	u8 high = offset_hz;
	u8 low = offset_lz;
	if(params.isBias==1)
	{
		 high = move_hz;
	   low = move_lz;
	}
	ConfigWord = 0x10300000;
	u8 dataType = params.high_low == 0 ? high : low;
	dac_index[0] = dacPortInfoTable[params.channelId-1][dataType][0] - 5;
	u8 dac_indexEx = dacPortInfoTable[params.channelId-1][dataType][2];
	u8 port = dacPortInfoTable[params.channelId-1][dataType][1];
	ConfigWord |= dac_indexEx << 24;
	ConfigWord |= port << 16;
	ConfigWord |= params.data;
	if(dac_index[0]==1){
		dac_index=dac_index; //test point
	}
	
	return ConfigWord;
}*/
void AnalogChannel_GetAll4094Word(u8 *pData,u8 channelId){
	//控制HC595/CD4094
	struct Paras595 params595;
	u8 gain = pData[0] ; 	//放大
	u8 att = pData[1] ;		//衰减
	u8 coupling = pData[2];
	u8 high_low = pData[3];
	u16 bandwidth = pData[8] + (pData[9]<<8);
	u32 ctrlWord595=0;
	params595.att = att;
	params595.bandwidth = bandwidth;
	params595.coupling = coupling;
	params595.gain = gain;
	params595.high_low = high_low;
	if(channelId == 1)
	{
		channelId=channelId;//test point
	}
	u8 result = Get4094CtrlWord(params595,&ctrlWord595);
	if(result==0){
		//参数错误
		return;
	}
	//Low32HC595_new |= (ctrlWord595 << 8*(channelId-1));
	Low32HC595 |= (ctrlWord595 << 8*(channelId-1));
	if(channelId == 4)
	{
		channelId=channelId;//test point
	}
	//Low32HC595 = Low32HC595_new;
}
void AnalogChannel_SetAll4094(u8 *pData){
	u8 channelId = pData[0];
	Low32HC595 = Low32HC595 & ((u32)1<<31);
	u8 gotChData = 0;
	for(int i=0; i<MAX_CHANNEL_NUM; i++)
	{
			if(((channelId>>i) & 0x01) == 1){
					AnalogChannel_GetAll4094Word(pData + 1 + gotChData * PACKAGE_CHANNELSET_DATA_BYTES,i+1);
					gotChData++;
			}
	}		
	CD_4094(High8HC595,1);
	CD_4094(Low32HC595,4);
	delay_ms(2);
}

void AnalogChannelSet(u8 *pData,u8 channelId)
{
	//if(channelId != 1) return;
	u8 gain = pData[0] ; 	//放大
	u8 high_low = pData[3];
	u16 bias = pData[4] + (pData[5]<<8);
	u16 offset = pData[6] + (pData[7]<<8);

	//控制字
	struct ParasDAC paramsDAC;
	
	//dataType: 0-ref,1-offset_lz,2-offset_hz,3-move_lz,4-move_hz
	u32 ConfigWord_bias;
	u32 ConfigWord_offset;
	u8 dac_index_bias;
	u8 dac_index_offset;

	//bias
	paramsDAC.high_low = high_low;
	paramsDAC.channelId = channelId;
	paramsDAC.data = bias;
	paramsDAC.isBias = 1;
	ConfigWord_bias = GetDACConfigWord(paramsDAC,&dac_index_bias);
	
	DAC_AD5628(ConfigWord_bias,dac_index_bias);
	//delay_ms(1);
	//return;

	//offset
	paramsDAC.high_low = high_low;
	paramsDAC.channelId = channelId;
	paramsDAC.data = offset;
	paramsDAC.isBias = 0;
	if(channelId == 1)
	{
		channelId = channelId;//test point
	}
	if(channelId == 2)
	{
		channelId = channelId;//test point
	}
	ConfigWord_offset = GetDACConfigWord(paramsDAC,&dac_index_offset);
	if(dac_index_offset>=3){
	dac_index_offset=dac_index_offset;//test point
	}
	DAC_AD5628(ConfigWord_offset,dac_index_offset);

	//gain 
	DSA_PE43711(LMH6401_ADDR_GAIN,gain,channelId);
}

void CMD0x22_Request_AnalogChannelSet_process(u8 *pData,u16 dataLen,u8 bIsContentBitInverted_Recv,u8 bIsContentBitInverted_SendBack)
{
	if(IsChannelSetting!=0)
	{
		return;
	}
	IsChannelSetting = 1;
#ifdef RUNNING_WHERE_AT_BOOT	
	Command_SendbackErrorMessage(Error0x02_CannotRunAtBoot,1);
#else
	memcpy(G_DebugData_AnalogChannel_LastRecvData,pData,dataLen);
	if(AnalogChannelSet_Check_Len(dataLen)==0)
	{ 
		IsChannelSetting=0;
		Command_SendbackErrorMessage(Error0x05_CMD_ParaLentghError,1);
		return;
	}
	//Calc
	u8 CRCStartIndex = dataLen - PACKAGE_CHANNELSET_FRAMEID_BYTES - PACKAGE_CHANNELSET_CHECK_AREA_BYTES;
	u8 SUMStartIndex = CRCStartIndex + PACKAGE_CHANNELSET_CRC32_BYTES;
	//u8 frameId[PACKAGE_CHANNELSET_FRAMEID_BYTES] ;
	u32 getCRC32 = pData[CRCStartIndex] + (pData[CRCStartIndex+1]<<8) + (pData[CRCStartIndex+2]<<16)+ (pData[CRCStartIndex+3]<<24);
	u16 getSUM16 =  pData[SUMStartIndex] + (pData[SUMStartIndex+1]<<8) ;
	
	u32 calcCRC32 = Helper_CRC_CalcBlockCRC8(pData,CRCStartIndex);
	u16 calcSUM16 = Helper_Sum16(pData,CRCStartIndex);
	
	if(getCRC32!=calcCRC32 || getSUM16!=calcSUM16)
	{
		IsChannelSetting=0;		
		Command_SendbackErrorMessage(Error0xFF_General,1);
		return;
	}
	//Calc End
	u8 gotChData = 0;
	u8 channelId = pData[0];
	AnalogChannel_SetAll4094(pData);

	for(int i=0; i<MAX_CHANNEL_NUM; i++)
	{
			if(((channelId>>i) & 0x01) == 1)
			{
					AnalogChannelSet(pData + 1 + gotChData * PACKAGE_CHANNELSET_DATA_BYTES,i+1);
					gotChData++;
			}
	}		
	//Call back
	u8 dataBytes=PACKAGE_CHANNELSET_FRAMEID_BYTES;

	for(u8 i=0;i<PACKAGE_CHANNELSET_FRAMEID_BYTES;i++)
	{
		USART_WR_BUF[i] =  pData[dataLen-PACKAGE_CHANNELSET_FRAMEID_BYTES+i];
	}
	 
	USART6_Send(CMD0x22_Request_AnalogChannelSet,dataBytes,bIsContentBitInverted_SendBack);	
	//end
	IsChannelSetting = 0;
#endif	
}

