/**
  ******************************************************************************
  * @file    embreg.c
  * @author  AndyChen
  * @version V1.0
  * @date    2015-xx-xx
  * @brief   
  ******************************************************************************
  * @attention
  *  
  ******************************************************************************
  */ 

/* Includes -------------------------------------------------------------------*/

#include "embreg.h"
#include "regmap.h"
#include "regdefine.h"
#include "fm25v02.h"
#include "RTC.h"
#include "para.h"
#include "data_write_local.h"
/* Private_Macros -------------------------------------------------------------*/



//寄存器地址间距
#define INDEX_BASE	100	

//Part1 和 Part2的地址分界点
#define PART12_SECTION_P	1049

//Part3 和 Part4的地址分界点
#define PART34_SECTION_P	1141

/* Private_TypesDefinitions ---------------------------------------------------*/

/* Private_Variables ----------------------------------------------------------*/

/* Private_Functions ----------------------------------------------------------*/

/**
  * @brief  读输入寄存器
  * @param  pucRegBuffer：返回数据指针
			usAddress	：输入寄存器起始地址
			usNRegs		：要读的寄存器数目		
  * @retval 错误代码
  */
eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
	eMBErrorCode eStatus = MB_ENOREG;

	return eStatus;	
}






/**
  * @brief  读/写保持寄存器
  * @param  pucRegBuffer：数据指针
			usAddress	：输入寄存器起始地址
			usNRegs		：要操作的寄存器数目	
			eMode		: 对保持寄存器的操作（读或写）
  * @retval 错误代码
  */
eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,eMBRegisterMode eMode )
{	
	u16 temp;
	u8 flag=0,i;
	float sound_set;
	uint16_t iRegIndex,uRegs;	
	uint16_t regStartAdress, regNum;
	eMBErrorCode eStatus = MB_ENOERR;
	u16 frameadd;
	volatile uint16_t *data_pointer;
	volatile void *regP=0;	
	volatile uint16_t my_regAddr,tempaddr;
	volatile uint16_t *bufferpointer;
	volatile uint16_t *newpointer,*oldpointer;
	u8 flowfix_flag,flowfix_user_flag;
	
	flowfix_flag = 0;
	flowfix_user_flag = 0;

	my_regAddr = usAddress - 1;
	uRegs = my_regAddr / INDEX_BASE;
	
	temp=usNRegs;
	if(uRegs>=10&&uRegs<20)
		frameadd=(my_regAddr-1000)*2+200;
	if(uRegs==0)
	  frameadd=my_regAddr*2;
		
	tempaddr = my_regAddr%1000;
	
	if( tempaddr == 0)
			return	MB_ENOREG;	
	
	//根据地址确定要访问的寄存器
	switch( uRegs )
	{
		//设备序列号寄存器
		case DEVSERIALNUM_FLAG:
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= DEVSERIALNUM_SADDR + DEVSERIALNUM_NREGS)
			{
				data_pointer= (void *)&regDevSerialNum;
				usAddress--;
			}
			else
			{
				eStatus=MB_ENOREG;
			}
			iRegIndex= usAddress %100;    //****************************************************//
			break;
		
		//测量设置寄存器Part 1 和Part 2
		case DEVCFGPARAM12_FLAG:			
			if(my_regAddr < PART12_SECTION_P)
			{
				regStartAdress = DEVCFGPARAM1_SADDR;
				regNum = DEVCFGPARAM1_NREGS;
				regP = &regDevCfgParam_p1;
				usAddress--;
			}
			else
			{
				regStartAdress = DEVCFGPARAM2_SADDR;
				regNum = DEVCFGPARAM2_NREGS;
				regP = &regDevCfgParam_p2;
				
				usAddress -= DEVCFGPARAM2_OFFSET;
			}
			
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= regStartAdress + regNum)
			{				
				data_pointer = regP;
			}
			else
			{
				eStatus = MB_ENOREG;
			}		
			iRegIndex= usAddress %100;    //****************************************************//			
			break;
		
		//设备配置参数寄存器Part 3 和Part 4
		case DEVCFGPARAM34_FLAG:			
			if(my_regAddr < PART34_SECTION_P)
			{
				regStartAdress = DEVCFGPARAM3_SADDR;
				regNum = DEVCFGPARAM3_NREGS;
				
				regP = &regDevCfgParam_p3;
				usAddress--;
			}
			else
			{
				regStartAdress = DEVCFGPARAM4_SADDR;
				regNum = DEVCFGPARAM4_NREGS;
				
				regP = &regDevCfgParam_p4;
				usAddress -= DEVCFGPARAM4_OFFSET;
			}
			
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= regStartAdress + regNum)
			{
				data_pointer = regP;
			}
			else
			{
				eStatus = MB_ENOREG;
			}		
			iRegIndex= usAddress %100;    //****************************************************//			
			break;
			
		case DEVCFGPARAM5_FLAG:			
			regStartAdress = DEVCFGPARAM4_SADDR;
			regNum = DEVCFGPARAM4_NREGS;
			
			regP = &regDevCfgParam_p4;
			usAddress -= DEVCFGPARAM4_OFFSET;
			
			
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= regStartAdress + regNum)
			{
				data_pointer = regP;
			}
			else
			{
				eStatus = MB_ENOREG;
			}	
			iRegIndex= (usAddress-1100)%200;    //******************临时的补救措施**************************//			
			break;	
		//设备配置参数寄存器Part 5
/*		case DEVCFGPARAM5_FLAG:
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= DEVCFGPARAM5_SADDR + DEVCFGPARAM5_NREGS)
			{
				data_pointer= (void *)&regDevCfgParam_p4;
				usAddress = usAddress - PART5_OFFSET;
			}
			else
			{
				eStatus=MB_ENOREG;
			}
			break;*/
			
		//流量计计量信息寄存器
		case FLOWMETERMSINfO_FLAG:
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= FLOWMETERMSINfO_SADDR + FLOWMETERMSINfO_NREGS)
			{
				data_pointer= (void *)&regFlowMeterMsInfo;
	  		usAddress--;
			}
			else
			{
				eStatus=MB_ENOREG;
			}
			iRegIndex= usAddress %100;    //****************************************************//
			break;
		
		//系统工作状态寄存器
		case SYSTEMWORKSTATUS_FLAG:
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= SYSTEMWORKSTATUS_SADDR + SYSTEMWORKSTATUS_NREGS)
			{
				data_pointer= (void *)&regworkstatus;
				usAddress--;
			}
			else
			{
				eStatus=MB_ENOREG;
			}
			
			iRegIndex= usAddress %100;    //****************************************************//
			break;	
			
				//调试寄存器      4701	
		case TEST_FLAG:
			//判断地址和寄存器数目合法性
			if(my_regAddr + usNRegs <= TEST_SADDR + TEST_NREGS)
			{
				data_pointer= (void *)&regTestInfo;
				usAddress--;
			}
			else
			{
				eStatus=MB_ENOREG;
			}
			iRegIndex= usAddress %100;    //****************************************************//
			break;	
			
			
		//非法地址
		default:
			eStatus=MB_ENOREG;
			break;
	}
	
	if(eStatus != MB_ENOREG)
	{		
	
		iRegIndex--;
		
		switch(eMode)
		{
			//读保持寄存器
			case MB_REG_READ:					
				while( usNRegs > 0 )
				{						
					
					if( (my_regAddr>=1175&&my_regAddr<=1180) || ( my_regAddr<1175 && (my_regAddr+usNRegs)>=1175) )
					{
						Get_Time();
						regDevCfgParam_p4.RTCtime_year	= calendar.year;        //RTC时间
						regDevCfgParam_p4.RTCtime_month	= calendar.month;       
						regDevCfgParam_p4.RTCtime_day	= calendar.date;         
						regDevCfgParam_p4.RTCtime_hour	= calendar.hour;        
						regDevCfgParam_p4.RTCtime_min	= calendar.min;        
						regDevCfgParam_p4.RTCtime_sec	= calendar.sec; 
					}
					//获取高位字节
					*pucRegBuffer++ = ( uint8_t )( *(data_pointer + iRegIndex) >> 8 );				
					
					//获取低位字节
					*pucRegBuffer++ = ( uint8_t )( *(data_pointer +iRegIndex) & 0xFF );				
					
					iRegIndex++;
					
					usNRegs--;
				}
				break;
				
			//写保持寄存器
			case MB_REG_WRITE:

				if(BT_status)
				{
					buffer_ins_g.system_para_a[0] = usNRegs;
					bufferpointer	=	(u16 *)&buffer_ins_g.system_para_a[1];
					*bufferpointer	=	my_regAddr;
					oldpointer		=	(u16 *)&buffer_ins_g.system_para_a[BUFFER_OLD_NUM];
					newpointer		=	(u16 *)&buffer_ins_g.system_para_a[BUFFER_NEW_NUM];
				}else
				{
					buffer_ins_g.system_para_a[0] = 0;
					bufferpointer	=	(u16 *)&buffer_ins_g.system_para_a[1];
					*bufferpointer	=	my_regAddr;
					oldpointer		=	(u16 *)&buffer_ins_g.system_para_a[BUFFER_OLD_NUM];
					newpointer		=	(u16 *)&buffer_ins_g.system_para_a[BUFFER_NEW_NUM];

				}
				while( usNRegs > 0 )
				{
					
					/*先保存原先的寄存器值*/
					
					*oldpointer = *(data_pointer + iRegIndex);
					*(data_pointer + iRegIndex) = *pucRegBuffer++ << 8;
					*(data_pointer + iRegIndex) |= *pucRegBuffer++;
					*newpointer = *(data_pointer + iRegIndex);
					oldpointer ++;
					newpointer ++;
					
					
 					if( (my_regAddr<=1180)&& (my_regAddr>=1175) )
					{
						 flag=1;
					}else if((my_regAddr>=1196)&&(my_regAddr<=1235))
					{
				/*后面的寄存器是不需要进行存储的*/
						
					}
					else
					{
						FM25V02_data_write(*(data_pointer + iRegIndex)&0xff, frameadd++);
						FM25V02_data_write(*(data_pointer + iRegIndex)>>8, frameadd++);
					}

					
					 
					if( (my_regAddr>=1101&&my_regAddr<=1140) )
					{
						flowfix_flag = 1;
					}else if((my_regAddr>=1196)&&(my_regAddr<=1235))
					{
						flowfix_user_flag = 1;
					}
					iRegIndex ++;
					usNRegs --;
				}
				if(flag)
					Time_Set(regDevCfgParam_p4.RTCtime_year,regDevCfgParam_p4.RTCtime_month,regDevCfgParam_p4.RTCtime_day,1,
				               regDevCfgParam_p4.RTCtime_hour,regDevCfgParam_p4.RTCtime_min,regDevCfgParam_p4.RTCtime_sec);

 				reg_change_dect(my_regAddr);
				
				if(my_regAddr == 1002)
				{
					sound_set = regDevCfgParam_p1.set_sound_speed;
					//通过判断计算的声速修改时间延迟。
					if(sound_set == 0)
					{

					}else
					{
						/*计算*/
// 						regDevCfgParam_p1.mid_a_compensate_time = (regDevCfgParam_p1.mid_distance / sound_set) - regTestInfo.midA + regDevCfgParam_p1.mid_a_compensate_time;
// 						FM25V02_data_write_float(MID_A_PROBE_ADD_TIME, regDevCfgParam_p1.mid_a_compensate_time);
// 						regDevCfgParam_p1.mid_b_compensate_time = (regDevCfgParam_p1.mid_distance / sound_set) - regTestInfo.midB + regDevCfgParam_p1.mid_b_compensate_time;
// 						FM25V02_data_write_float(MID_B_PROBE_ADD_TIME, regDevCfgParam_p1.mid_b_compensate_time);
						regDevCfgParam_p1.up_a_compensate_time = (regDevCfgParam_p1.up_distance / sound_set) - regTestInfo.time_A1 + regDevCfgParam_p1.up_a_compensate_time;
						FM25V02_data_write_float(UP_A_PROBE_ADD_TIME, 	regDevCfgParam_p1.up_a_compensate_time);
						regDevCfgParam_p1.up_b_compensate_time = (regDevCfgParam_p1.up_distance / sound_set) - regTestInfo.time_B1 + regDevCfgParam_p1.up_b_compensate_time;
						FM25V02_data_write_float(UP_B_PROBE_ADD_TIME, 	regDevCfgParam_p1.up_b_compensate_time);
						regDevCfgParam_p1.down_a_compensate_time = (regDevCfgParam_p1.down_distance / sound_set) - regTestInfo.time_A2 + regDevCfgParam_p1.down_a_compensate_time;
						FM25V02_data_write_float(DOWN_A_PROBE_ADD_TIME, regDevCfgParam_p1.down_a_compensate_time);
						regDevCfgParam_p1.down_b_compensate_time = (regDevCfgParam_p1.down_distance / sound_set) - regTestInfo.time_B2 + regDevCfgParam_p1.down_b_compensate_time;
						FM25V02_data_write_float(DOWN_B_PROBE_ADD_TIME, regDevCfgParam_p1.down_b_compensate_time);
					}
				}else if(my_regAddr == 1236)
				{
					if(regDevCfgParam_p4.password == regDevCfgParam_p4.userPassword)
					{
						regDevCfgParam_p4.confirmpassword = 1111;
					}else
					{
						regDevCfgParam_p4.confirmpassword = 2222;
					}
				}else if(my_regAddr == 1237)
				{
					if(regDevCfgParam_p4.superpassword == regDevCfgParam_p4.authUsrPassword)
					{
						regDevCfgParam_p4.confirmsuperpassword = 1111;
					}else
					{
						regDevCfgParam_p4.confirmsuperpassword = 2222;
					}

				}
				
				if(flowfix_flag == 1)
	     		{
					for(i=0;i<10;i++)
					{
						if(regDevCfgParam_p3.stdEquipmentFlow[i] != 0)
						{
							 regDevCfgParam_p2.flowCalibFactor[i]  = 1.0/(1+regDevCfgParam_p3.indicationError[i]/100);					
							 regDevCfgParam_p2.flowSegmentPoint[i] = regDevCfgParam_p3.stdEquipmentFlow[i]/regDevCfgParam_p2.flowCalibFactor[i];	
							 flowfixcount = i + 1;
						}
						else
						{
							 regDevCfgParam_p2.flowCalibFactor[i]=1;
							 regDevCfgParam_p2.flowSegmentPoint[i]=0;
							
						}	
					}


					for(i = 0; i < 10; i ++)
					{
						FM25V02_data_write_float((FLOW_CHANGE_K1_ADDR + (u16)(i * 4)),regDevCfgParam_p2.flowCalibFactor[i]);
						FM25V02_data_write_float((FLOW_CHANGE_L1_ADDR + (u16)(i * 4)),regDevCfgParam_p2.flowSegmentPoint[i]);

					}
							
					//flowfix_flag=0;			
		    	}else if(flowfix_user_flag == 1)
		    	{
					for(i = 0 ; i < 10; i ++)
					{
						if(regDevCfgParam_p4.user_flow[i] != 0)
						{
							 regDevCfgParam_p4.user_cal_error[i]  = 1.0/(1 + regDevCfgParam_p4.user_error[i]/100);					
							 regDevCfgParam_p4.user_cal_flow[i] = regDevCfgParam_p4.user_flow[i] / regDevCfgParam_p4.user_cal_error[i];	
							 flowfixcount_user = i + 1;
						}
						else
						{
						
							 regDevCfgParam_p4.user_cal_error[i] = 1;
							 regDevCfgParam_p4.user_cal_flow[i]	= 0;
							
						}	
					}


					for(i = 0; i < 10; i ++)
					{
						FM25V02_data_write_float((CAL_USER_ERROR_VALUE_E1_ADDR + (u16)(i * 4)), regDevCfgParam_p4.user_cal_error[i]);
						FM25V02_data_write_float((CAL_USER_REAL_FLOW_R1_ADDR + (u16)(i * 4)),  regDevCfgParam_p4.user_cal_flow[i]);

					}
					
				}

					
					
					
				
				break;		

			default:
				break;
		}
	}

	return eStatus;
}

/**
  * @brief  读/写线圈寄存器
  * @param  pucRegBuffer：数据指针
			usAddress	：寄存器起始地址
			usNCoils	：要操作的线圈数目	
			eMode		：操作模式
  * @retval 错误代码
  */
eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,eMBRegisterMode eMode )
{	
	return MB_ENOREG;
}

/**
  * @brief  读离散寄存器
  * @param  pucRegBuffer：返回数据指针
			usAddress	：寄存器起始地址
			usNDiscrete	：要读的寄存器数目		
  * @retval 错误代码
  */
eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{	
	return MB_ENOREG;
}

/******************* (C) COPYRIGHT 2015 AndyChen *******END OF FILE*************/
