#ifndef	_DET_ENERGY_
#define _DET_ENERGY_

#include "apt32f102.h"
#include "apt32f102_gpio.h"

#define BT_NAME_DEFAULT 	"BLV_0000"
#define ENERGY_HEAD			0x8A			//校验头
#define DEV_TYPE			0xF4
#define ENERGY_TAIL			0xA8			//校验尾



#define REV_NONE	0x00
#define REV_OK 		0x01
#define REV_ERR		0x02

//发送读/写 寄存器状态机的返回
#define SEND_STATE_NONE	0x00
#define SEND_STATE_SUCC	0x01
#define SEND_STATE_FAIL	0x02

#define SEND_W		0x02//写寄存器指令发送
#define SEND_R		0x01//读寄存器指令发送
#define SEND_NONE	0x00//发送空闲
#define SEND_TIME	300

/*<  系统设置寄存器默认值    >*/
#define SYSCON_DEFAULT          0x0f04		//0x0a04      //开启A通道，关闭B通道，电压通道PGA = 1，电流通道PGA = 16       //2023-10-13
#define EMUCON1_DEFAULT         0x1103		//0x0001      //1，使能PFA 脉冲输出和有功电能寄存器累加；
#define EMUCON2_DEFAULT         0x0fff		//0x0465      //0x0001是EMUCON2的默认值，waveEn = 1,zxEn = 1，A通道电量寄存器，读后不清0，EPA_CB = 1；打开功率因素检测



/*<  寄存器    >*/
//8112/8110 reg define
#define REG_SYSCON_ADDR         0x00	//系统控制寄存器
#define REG_EMUCON1_ADDR        0x01	//计量控制寄存器1
#define REG_HFCONST_ADDR        0x02	//脉冲频率寄存器
#define REG_EMUCON2_ADDR        0x13	//计量控制寄存器2
#define REG_ANGLE_ADDR        	0x22	//相角寄存器  电流与电压之间的相角，通过命令选择：电流通道 A与电压通道的相角或电流通道 B 与电压通道的相角
#define REG_UFREQ_ADDR          0x23    //市电线性频率地址
#define REG_RMSIA_ADDR          0x24	//通道A电流有效值
#define REG_RMSIB_ADDR          0x25	//通道B电流有效值
#define REG_RMSU_ADDR           0x26	//电压有效值
#define REG_PF_ADDR             0x27	//功率因素寄存器，通过命令选择：通道A或通道B的功率因素
#define REG_ENERGY_PA_ADDR		0x28	//通道A有功电能，设置为读后不清零
#define REG_ENERGY_PB_ADDR		0x29	//通道B有功电能，设置为读后不清零
#define REG_POWER_PA_ADDR       0x2C	//通道A有功功率
#define REG_POWER_PB_ADDR       0x2D	//通道B有功功率

#define REG_POWER_PS_ADDR       0x2E
#define REG_SAGCYC_ADDR         0x17
#define REG_SAGLVL_ADDR         0x18
#define REG_OVLVL_ADDR          0x19
#define REG_OIALVL_ADDR         0x1a
#define REG_INT_ADDR          	0x1D
#define REG_IE_ADDR          	0x40
#define REG_IF_ADDR          	0x41
#define REG_RIF_ADDR          	0x42
#define REG_RDATA_ADDR          0x44


#define REG_CHECKSUM_ADDR		0x6f	//校表系数校验和
#define REG_RMS_IAC_ADDR		0x70	//电流通道A有效值转换系数
#define REG_RMS_IBC_ADDR		0x71	//电流通道B有效值转换系数
#define REG_RMS_UC_ADDR			0x72	//电压通道U有效值转换系数
#define REG_POWER_PAC_ADDR		0x73	//电流通道A有功功率转换系数
#define REG_POWER_PBC_ADDR		0x74	//电流通道B有功功率转换系数
#define REG_POWER_SC_ADDR		0x75	//视在功率转换系数
#define REG_ENERGY_AC_ADDR	    0x76	//A通道能量转换系数
#define REG_ENERGY_BC_ADDR		0x77	//B通道能量转换系数



#define REV_BUFFER_SIZE 	30
#define REG_SUM_MAX			15000000
#define REG_DEBUG_NUM		50			//过大的寄存器差值，要根据硬件的采集电阻确认
#define REG_DEBUG_CNT		7			//连续读错次数

#define REG_BTDEBUG_FLAG	0x06		//蓝牙正常打印标志

//发送状态
typedef enum
{
	HLW_IDLE = 0x00,	//空闲
	HLW_SEND_INIT,		//发送初始化
	HLW_WTREG,			//写寄存器
	HLW_SEND,			//发送读写
	HLW_WRITE_DIS,		//写失能
	
	HLW_WAIT,			//跳转等待
}DetState_IDX;


typedef enum
{
	READ_IDLE = 0x00,	//
	READ_U,				//	
	READ_IA,			//
	READ_IB,			//
	READ_EA,			//
	READ_EB,			//
	READ_PA,			//
	READ_PB,			//
	
}ReadValue_n;


//HLW8110发送/接收
typedef struct{
	U8_T SendBuff[REV_BUFFER_SIZE];		//发送缓冲区
	U8_T RevBuff[REV_BUFFER_SIZE];		//接收处理缓存
	U8_T SendLen;		        		//发送缓冲字节大小
	U8_T RevLen;						//接收缓冲
	
	U8_T State;							//发送状态机
	U8_T Pub_NextState;					//等待时间结束后要跳转的状态
	U8_T WR_flag;						//发送读\写命令的判断标志

	U8_T Resent;						//重发次数
	U8_T RevNum;						//回复校验状态,只有读寄存器才有回复，写寄存器后要读一下校验
	U8_T SendState;						//发送状态
	
	U32_T Pub_WaitTim;					//等待区的等待时间	
	
}DetUart_t;

//HLW8110寄存器
typedef struct
{
	//系数寄存器.只读
	U16_T	U16_RMSIAC_RegData; 			// A通道电流转换系数
	U16_T	U16_RMSIBC_RegData; 			// B通道电流转换系数
	U16_T	U16_RMSUC_RegData; 				// 电压通道转换系数
	U16_T	U16_PowerPAC_RegData; 			// A通道功率转换系数
	U16_T	U16_PowerPBC_RegData; 			// B通道功率转换系数
	U16_T	U16_PowerSC_RegData; 			// 视在功率转换系数,如果选择A通道，则是A通道视在功率转换系数。A和B通道只能二者选其一
	U16_T	U16_EnergyAC_RegData; 			// A通道有功电能(量)转换系数 
	U16_T	U16_EnergyBC_RegData; 			// A通道有功电能(量)转换系数
	U16_T	U16_CheckSUM_RegData; 			// 转换系数的CheckSum
	U16_T	CheckSUM_Data; 					// MCU转换系数计算出来的CheckSum
	
	//系统控制寄存器，需要写入
	U16_T	U16_Check_SysconReg_Data; 		//系统寄存器					
	U16_T	U16_Check_Emucon1Reg_Data; 		//计数1寄存器	
	U16_T	U16_Check_Emucon2Reg_Data; 		//计数2寄存器
	
	
	//电流、电压有效值寄存器，只读,第24位为符号位
	U32_T	U24_Voltage_RegData;			//电压有效值,单位:
	U32_T	U24_CurrentA_RegData;			//A通道电流有效值,单位:
	U32_T	U24_CurrentB_RegData;			//B通道电流有效值,单位:
	U32_T	U32_PowerA_RegData;				//A通道有功功率有效值,单位:
	U32_T	U32_PowerB_RegData;				//B通道有功功率有效值,单位:
	U32_T	U24_EnergyA_RegData;			//A通道有功电能有效值,单位:
	U32_T	U24_EnergyB_RegData;			//B通道有功电能有效值,单位:
	U32_T	U16_HFConst_RegData;			//脉冲频率寄存器值 - 用于计算能耗使用,本设备计算已经约去，如果本参数读取值不为4096则需要重写计算公式
	
}HLW8110_REG;




//HLW8110有效值寄存器值
typedef struct{
	
	U8_T tack_reset_flag;		//复位标志，1：复位
	U8_T EnergyA_reset_cnt;
	U8_T EnergyB_reset_cnt;
	U8_T Tack_State;			//设备执行任务状态机

	U8_T rWCh_Num;    			//读转换系数状态机
	U8_T rWSysCtrl;				//写系统控制寄存器状态机
	U8_T rDValue_State;			//读取电压电流有效值状态机
	
	U8_T SdSN;

	U8_T BT_SdBuff[20];
	U8_T BT_SdLen;
	U16_T BT_SendFlag;			//蓝牙发送标记	
	
	U16_T hfcount;

	
	U32_T det_V;				//电压，单位：10mV 
	U32_T det_ectA;				//电流A，单位：10mA
	U32_T det_engA;				//电量A
	U32_T det_powA;				//有功功率A,单位： mW
	U32_T det_ectB;				//电流B，单位：10mA
	U32_T det_engB;				//电量B
	U32_T det_powB;				//有功功率B,单位： mW



	U32_T Total_Eng;			//设备记录总能耗
	U32_T LastPhase_Eng;		//上次上报的总能耗
	U32_T LastSave_Total_Eng;	//设备上次记录能耗
	
	U32_T Total_Eng_B;			//设备记录总能耗
	U32_T LastPhase_Eng_B;		//上次上报的总能耗
	U32_T LastSave_Total_Eng_B;	//设备上次记录能耗	

	U32_T U32_EnergyA_RegData;					//A通道有功电能有效值寄存器累计值,单位:
	U32_T U32_EnergyA_RegData_LastRecord;		//上次d读取的A通道有功电能有效值寄存器值,单位:
	
	U32_T U32_EnergyB_RegData;					//B通道有功电能有效值寄存器累计值,单位:
	U32_T U32_EnergyB_RegData_LastRecord;		//上次读取到的B通道有功电能有效值寄存器值,单位:	
	
	
	F32_T V_K_Val;				//电压系数
	F32_T IA_K_Val;				//电流A系数
	F32_T IB_K_Val;				//电流B系数
	F32_T PA_K_Val;				//功率A系数
	F32_T PB_K_Val;				//功率B系数
	F32_T I_OffSetVal;			//电流偏差
	F32_T P_OffSetVal;			//功率偏差
	
	U32_T Collect_Tim;			//采集间隔，默认5秒钟
	U32_T Report_Tim;			//上报间隔，默认10分钟
	U32_T SaveFlash_Tim;		//保存时间，默认1小时
	
	U32_T Eng_Report_Tim;		//定时上报时间搓
	U32_T BT_Print_valid;			//蓝牙打印时间戳
	
	
}DetEng_Info;

extern DetEng_Info g_Eng;

void BLV_DetEnergy_Init(void);
void BLV_DetEnergy_Default(void);
U8_T HLW8110_RecvData_Processing(U8_T *RecvData,U16_T RecvLen);
void BLV_HLW8110_RWCMD_Packaging(U8_T ADDR_Reg,U16_T len,U32_T value);
void BLV_HLW8110_SendData_Tack(void);
void BLV_HLW8110_Tack(void);
void GetEnergy_Para(void);
void BLV_EngDetect_Tack(void);
void SaveFram_TEng(void);

void BLV_Energy_PassiveRep_Packing(U8_T cmd);
U8_T BLV_485Recv_Processing(U8_T *RecvData,U16_T RecvLen);
U8_T BT_Recv_Processing(U8_T *RecvData,U16_T RecvLen);
U8_T BT_Uart_Packing(U8_T *data,U8_T len,U8_T flag);
#endif

