/*--------------------------------------------------------------------------------------
*  @file     TypeDefine.c
*  @author   ZhangJing
*  @version  base on stm32f0x   
*  @date     2015.09.11
*  @brief    公共变量、函数定义
---------------------------------------------------------------------------------------*/
#include <string.h>
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "TypeDefine.h"
#include "Driver.h"
#include "LCDSetup.h"
#include "DrawLCDGUI.h"
#include "ControlSystem.h"
#include "History.h"
#include "ParameterSet.h"
#include "SystemAlarm.h"
#include "FM31256.h"
//#include "ZigbeeNet.h"
#include "FlashSetup.h"
#include "ProgramData.h" // add by wulianwei

TaskSchedulerFlagFrame	TaskSchedulerFlag;//任务调度标志
TaskSchedulerTimerFrame	TaskSchedulerTimer;//任务调度定时器

KeyTypeFrame	KeyScanStatus;//按键扫描状态
KeyFlagFrame	KeyActionFlag;//按键动作标志
KeyScanQtyFrame	KeyScanQty;	//按键扫描次数
KeyFlagFrame	MoreKeyActionFlag;//多键组合动作标志

bool motorWorkState = MOTOR_WORK_OFF;//电机工作状态 

TimeFrame	displayTimeBuf;//显示时间
RTDFrame	realTimeData;//实时数据
uint8_t		dateLimit = 0;//日期分为29，30，31

VerifyInfoSetFrame	verifyInfo;//病人住院信息确认
SetParamFrame	setParamInfo;//参数设置信息
RunParamFrame runParamInfo;//运行参数，因为有两页参数设置相同的参数，所以要有个运行参数
AlarmFrame alarmRecord;//报警信息存储

SetTimeType emSetTimeChoose;//时间设置选择
TimeFrame	displayTimeBuf;//显示时间
TimeFrame	setTimeBuf;//显示时间

uint8_t	setPasswordBuf[3] = {1,2,0};//密码设置--设置密码界面变量，通用密码改为120
uint8_t	verifyPasswordBuf[3] = {0,0,0};//确认密码--设置密码界面变量

EvaluateTransfuseType emEvaluateTransfuseChoose;//随访评价选择类型
EvaluateTransfuseFrame	evaluateTransfuseValue;//随访评价中的数据

EngineeringModeType emEngineeringMode1Choose;//工程控制画面1设置选择类型
EngineeringModeType emEngineeringMode3Choose;//工程控制画面3设置选择类型
EngineeringModeFrame EngineeringModeValue;//工程模式中的数据

PictureEnterType emPictureRunState = FirstEnter;//页面运行状态，是首次进入，还是有数据更新

SpeakerWorkType HornWorkStep;	//喇叭工作类型
SpeakerWorkType speakerWorkStep;//蜂鸣器工作类型
SpeakerWorkType speakerWorkStep = emSpeakerNoneWork;//蜂鸣器工作步骤
SpeakerType sysPromptToneType = SoundOff;//系统提示音类型
SpeakerType	SysHornToneType;
uint8_t	sysPromptToneCounts = 0;//提示音响的次数

uint8_t testDispCounts = 0;//测试页面数据次数
extern uint16_t	inputDose_bf;				//已输入量备份
extern uint8_t SetParametersAgain ;		//运行过程中重新设置参数标志
uint8_t FirstSurplusDose = 0;		//堵塞时首次量剩余量
uint8_t PCASurplusDose = 0;			//堵塞时PCA量剩余量


/*********************************************************************************
*  Function:	Delay_ms						                                                           
*  Object:		Inserts a delay time.
*  输入:			nCount: specifies the delay time length (time base 1 ms).
*  输出:			无	                                     
*  备注:			              
**********************************************************************************/
void Delay_ms(uint32_t nCount)
{
	TaskSchedulerTimer.delayTimer = nCount;

	while(TaskSchedulerTimer.delayTimer != 0)
	{
	}
}


/***************************************
*  
*  Function:	void ReadInputTotalDose(void)		                                                           
*  Object:		从FM31256中读取输入总量的历史数据
*  输入:			无
*  输出:			无	                                     
*  备注:			
***************************************/
void ReadInputTotalDose(void)
{
	uint8_t InputTotalDoseBuff[4];
	//Read_Multi31256RAM( HISTORY31256_DATA_InputTotalDose, InputTotalDoseBuff, 4 );
	FlashReadOperate( InputTotalDoseBuff,4,HISTORY31256_DATA_InputTotalDose );
	realTimeData.InputTotalDose=0;
	realTimeData.InputTotalDose=(((uint32_t)InputTotalDoseBuff[0]<<24) + ((uint32_t)InputTotalDoseBuff[1]<<16) + ((uint32_t)InputTotalDoseBuff[2]<<8) + ((uint32_t)InputTotalDoseBuff[3]));
}

/*********************************************************************************
*  Function:	SystemSWInit			                                                           
*  Object:		系统软件初始化
*  输入:			无
*  输出:			无	                                     
*  备注:			1、开机系统进行初始化时将全局变量进行初始化 
*							2、读取FM31256中存储的参数
*							3、读取存储的历史数据第一条
**********************************************************************************/
void SystemSWInit( void )
{		
	uint8_t InputTotalDoseBuff[4];

	(void) memset (&realTimeData, 0, sizeof(realTimeData));	//将realTimeData数据清零
	(void) memset (&setParamInfo, 0, sizeof(setParamInfo));	//将setParamInfo数据清零
	(void) memset (&paramRecordBuf, 0, sizeof(paramRecordBuf));	//将paramRecordBuf数据清零
	(void) memset (&historyRecordBuf, 0, sizeof(paramRecordBuf));	//将historyRecordBuf数据清零
	(void) memset (&historyRecord, 0, sizeof(historyRecord));	//将historyRecord数据清零

	/*按键工作状态，用来判断消抖*/
	KeyScanStatus.keyPower = emKeyActionWait;
	KeyScanStatus.keyPS = emKeyActionOff;
	KeyScanStatus.keyAirout = emKeyActionOff;
	KeyScanStatus.keyEnter = emKeyActionOff;
	KeyScanStatus.keyPlus = emKeyActionWait;
	KeyScanStatus.keyMinus = emKeyActionOff;
	KeyScanStatus.keyRunPause = emKeyActionOff;
	KeyScanStatus.keyPCA = emKeyActionOff;
	
	/*用计数方式扫描按键按下状态，按键分为长按短按连续按下*/
	KeyScanQty.keyEnter = 0;
	KeyScanQty.keyRunPause = 0;
	KeyScanQty.keyPlus = 0;
	KeyScanQty.keyMinus = 0;
	KeyScanQty.keyPower = 0;
	KeyScanQty.keyAirout = 0;
	KeyScanQty.keyPS = 0;
	KeyScanQty.keyPCA = 0;
	
	/*按键扫描消抖时长，全部消抖都为定长，按消抖次数(KeyScanQty)判断是长按还是短按*/
	TaskSchedulerTimer.powerKeyScanTimer = 0;//上电时不让有消抖处理，否则会出现开机误操作的情况
	TaskSchedulerTimer.enterKeyScanTimer = KEY_TIMER_SCAN;
	TaskSchedulerTimer.runPauseKeyScanTimer = KEY_TIMER_SCAN;
	TaskSchedulerTimer.airoutKeyScanTimer = KEY_TIMER_SCAN;
	TaskSchedulerTimer.psKeyScanTimer = KEY_TIMER_SCAN;
	TaskSchedulerTimer.plusKeyScanTimer = KEY_TIMER_SCAN;
	TaskSchedulerTimer.minusKeyScanTimer = KEY_TIMER_SCAN;	
	TaskSchedulerTimer.pcaKeyScanTimer = KEY_TIMER_SCAN;
	
	/*任务标志位初始化*/
	TaskSchedulerFlag.initFinishFlag = TASK_FLAG_WAIT;
	TaskSchedulerFlag.zigbeeRecvFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.zigbeeXmitFlag = TASK_FLAG_CLEAR;	
	TaskSchedulerFlag.zigbeeComReadFlag = TASK_FLAG_WAIT;			
	TaskSchedulerFlag.zigbeeInNetFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.zigbeeETXmitFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.historyRequestFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.historyReponseFlag = TASK_FLAG_CLEAR;	
	TaskSchedulerFlag.pressureConvertFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.forceConvertFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.fromSlaveRecvFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.toSlaveXmitFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.motorRunFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.motorStopFlag = TASK_FLAG_SET;//默认是置位状态
	TaskSchedulerFlag.motorSelfTestFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.ipnutFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.timeReadFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.lockDispFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.hostXmitFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.unlockPasswordFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.rtdUpdateFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.speakerFlag = TASK_FLAG_SET;//TASK_FLAG_CLEAR;
	TaskSchedulerFlag.silenceFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.pcaLockFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.pcaCountDispFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.pcaLockTimeFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.batLowPrepareFlag = TASK_FLAG_CLEAR;
//	TaskSchedulerFlag.autoPowerOffFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.sysPowerOffFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.callFunctionFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.lcdBlackFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.lcdFlashFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.lcdBlackFlashFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.sysStandbyFlag = TASK_FLAG_WAIT;
	TaskSchedulerFlag.limitJudgeFlag = TASK_FLAG_SET;
	TaskSchedulerFlag.sensorPWHallFlag = TASK_FLAG_SET;//传感器电源-霍尔打开
	TaskSchedulerFlag.sensorPWPressureFlag = TASK_FLAG_SET;//传感器电源-压力打开
	TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压打开
	TaskSchedulerFlag.testDispFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.batteryVoltHeaderFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.PCAOneTimeFlag = TASK_FLAG_WAIT;
	TaskSchedulerFlag.IrregularShutdownFlag = TASK_FLAG_CLEAR;
    TaskSchedulerFlag.JamSelfcheckingFlag = TASK_FLAG_WAIT;//堵塞自检标志等待
    TaskSchedulerFlag.PasswordTimeOverFlag = TASK_FLAG_WAIT;
	TaskSchedulerFlag.LimitBeginsTime = 0;	//极限T1计时
	TaskSchedulerFlag.EnterDelayFlag = TASK_FLAG_CLEAR;//enter按键长按开始延时标志
	TaskSchedulerFlag.HistoryDontSetFlag = TASK_FLAG_CLEAR;//住院号未设置
	TaskSchedulerFlag.AirOutFlag = TASK_FLAG_CLEAR;//排气标志清除
	TaskSchedulerFlag.AlarmInitFlag = TASK_FLAG_CLEAR;
	TaskSchedulerFlag.pcaCountFlashFlag = TASK_FLAG_CLEAR;//PCA计数闪烁标志用来进行闪烁计时使用
	TaskSchedulerFlag.PCATimerFlashFlag = TASK_FLAG_CLEAR;//PCA锁时闪烁标志
	
	/********固定频率刷新，也跟随电机停止刷新*********/
	TaskSchedulerFlag.LcdLogoFlag = TASK_FLAG_CLEAR;//屏幕上方标志分时闪烁进入刷新标志
	TaskSchedulerFlag.PCATimerFlashFlag1 = TASK_FLAG_CLEAR;//屏幕中PCA锁时时间闪烁刷新标志
	TaskSchedulerFlag.lcdFlashFlag1 = TASK_FLAG_CLEAR;//PCA有无效次数闪烁刷新标志
	TaskSchedulerFlag.MqttSendFlag = TASK_FLAG_SET;//Mqtt发送标志 add by wulianwei
	/****************************************/
	
	
	TaskSchedulerTimer.delayTimer = 0;
	TaskSchedulerTimer.EnterDelayTimer = EnterDelay_TIMER;
	TaskSchedulerTimer.pcaLockTimer = 0;
	TaskSchedulerTimer.initFinishTimer = TRI_SECOND_TIMER;
	TaskSchedulerTimer.rtdXmitTimer = TASK_TIMER_XMIT_RTD;
	TaskSchedulerTimer.timeReadTimer = ONE_SECOND_TIMER;
	TaskSchedulerTimer.pressureConvertTimer = TASK_TIMER_PRES_CONV;	
//	TaskSchedulerTimer.dispAutoJumpTimer = DISP_TIME_AUTO_JUMP;
	TaskSchedulerTimer.lockDispTimer = DISP_TIME_LOCK_JUMP;		
	TaskSchedulerTimer.sysRunTestTimer = SYS_RUN_TEST_TIMER;
	TaskSchedulerTimer.alarmCollectTimer = ALARM_COLLECT_TIMER;
	TaskSchedulerTimer.totalDoseOneHourTimer = ONE_HOUR_TIMER;
	TaskSchedulerTimer.motorSignalCollectTimer = MOTOR_TESTSELF_TIMER;
	TaskSchedulerTimer.motorSelfTestTimer = MOTOR_TESTSELF_TIMER;//电机自检时间
	TaskSchedulerTimer.motorStopTimer = InfusionStopTimer;//电机停止等待时间
	TaskSchedulerTimer.hostXmitTimer = ONE_MSEC_TIMER;
	TaskSchedulerTimer.lockPassWordTimer = THREE_MINUTE_TIMER;
	TaskSchedulerTimer.batLowPrepareDispTimer = ONE_SECOND_TIMER;
	TaskSchedulerTimer.universalTimer = TWO_SECOND_TIMER;//通用计时
	TaskSchedulerTimer.speakerTimer = ONE_SECOND_TIMER;//蜂鸣器计时
	TaskSchedulerTimer.speakerWaitTimer = THIRTY_SECOND_TIMER;//蜂鸣器等待计时
//	TaskSchedulerTimer.autoPowerOffTimer = THIRTY_MINUTE_TIMER;//自动关机计时
	TaskSchedulerTimer.lcdBlackCloseTimer = FIFTEEN_SECOND_TIMER;//TWO_SECOND_TIMER;//LCD背光关闭计时
	TaskSchedulerTimer.alarmLCDFlashTimer = TEN_SECOND_TIMER;//报警LCD闪屏次数显示计时
	TaskSchedulerTimer.sysStandbyTimer = TEN_SECOND_TIMER;//系统休眠计时
	TaskSchedulerTimer.hostPowerSaveTimer = TEN_SECOND_TIMER;//主芯片节能计时
	TaskSchedulerTimer.batteryVoltTimer = FIFTEEN_SECOND_TIMER;//电池电压采集计时
	TaskSchedulerTimer.pcaOneHourTimer = ONE_HOUR_TIMER;//有效次数>2次在1小时内疼痛不足报警
    TaskSchedulerTimer.JamSelfcheckingTimer = FIVE_MINUTE_TIMER;//堵塞自检计时5min
	TaskSchedulerTimer.PainAssessmentUploadTimer = ONE_SECOND_TIMER;//疼痛评价确认上传时间，假时间
	TaskSchedulerFlag.StartToRunDontSend = SendWait;//长数据包发送等待标志
	
	TaskSchedulerTimer.pcaCountsFlashTimer = THREE_MSEC_TIMER;//PCA计数闪烁计时，
	TaskSchedulerTimer.ModuleInitTimer = FIFTEEN_SECOND_TIMER; //TCP检测计时 add by wulianwei
	TaskSchedulerTimer.MQTTSendTimer = TASK_TIMER_XMIT_RTD;// mqtt数据发送定时 add by wulianwei
	pca_count = 0;			//开机或者重新设值参数一小时内PCA按压次数清零
	
    /*报警记录清零*/
    AlarmRecord.MechanicalFault = ALARM_OFF;
    AlarmRecord.NonePillCase = ALARM_OFF;
    AlarmRecord.BubbleFault = ALARM_OFF;
    AlarmRecord.LineLost = ALARM_OFF;
    AlarmRecord.JamFault = ALARM_OFF;
    AlarmRecord.MaxFault = ALARM_OFF;
    AlarmRecord.InputTotal = ALARM_OFF;
	sysAlarmFlag.Zhentongxiaoguo = ALARM_OFF;
	
	SysHornToneType = SoundWate;
    
	SysAlarmJudge.JamFaultJudgeFlag = TASK_FLAG_CLEAR;
	SysAlarmJudge.BubbleFaultJudgeFlag = TASK_FLAG_CLEAR;
	SysAlarmJudge.NonePillCaseJudgeFlag = TASK_FLAG_CLEAR;
	SysAlarmJudge.VoltLowestJudgeFlag = TASK_FLAG_CLEAR;
	SysAlarmJudge.JamFaultJudgeCounts = 0;
	SysAlarmJudge.BubbleFaultJudgeCounts = 0;
	SysAlarmJudge.NonePillCaseJudgeCounts = 0;
	SysAlarmJudge.VoltLowestJudgeCounts = 0;
	
	emSetTimeChoose = Year;	
	verifyInfo.modifyInfoType = HOSPITALNO_SELECTED;
	setParamInfo.emModifyParam = TotalDose;
	
	emEvaluateTransfuseChoose = Pruritus;//随访评价选项
	emEngineeringMode3Choose = DeviceIDChoose;
	emEngineeringMode1Choose = SickroomQty;
	
	TotalDoesChange0 = 0;//工程模式输注总量变化1变0
	TotalDoesChange1 = 0;//工程模式输注总量变化0变1
	
	realTimeData.stateRun = SelfTest;//StartWork;//系统运行状态-开始工作
	realTimeData.ctlSlaveRun = StartWork;//从机运行状态-开始工作
	sysPromptToneType = SoundOff;
	
	emDisplayPicture = ClearDisp;
	emCurrentPicture = ClearDisp;
	emSysWorkStep = EnterPowerON;
	
	displayTimeBuf.year = 2021;
	displayTimeBuf.month = 1;
	displayTimeBuf.date = 1;
	displayTimeBuf.hour = 0;
	displayTimeBuf.minute = 0;
	displayTimeBuf.seconds = 0;	
	
	realTimeData.batteryVolt = 255;
	
	LCDInit();
	LCDClear( GRAY0 );
 	GetCurDateTimeFromRTC();//上电1s以后再读时间，否则影响开机速度

	FlashReadOperate( paramRecordBuf,2,((uint32_t)0x0806407E) );
	if(paramRecordBuf[0] == 0x0A)
	{
		ReadParameterRecord();//读出参数
	}
	else 
	{
		WriteInitParameterRecord();
		ReadParameterRecord();//读出参数
		InputTotalDoseBuff[0]=00;
		InputTotalDoseBuff[1]=00;
		InputTotalDoseBuff[2]=00;
		InputTotalDoseBuff[3]=00;
		FlashWriteOperate( InputTotalDoseBuff,4,HISTORY31256_DATA_InputTotalDose );
		WriteInitProgramData();//初始化程序参数, add by wulianwei
	}
	
//	ReadParameterRecord();//读出参数
	ReadHistoryRecordQTY();//读出历史数据现有数量
	if(historyRecordQTY>=10)
	{
		if(historyRecordPointer == 0)
		{
			historyRecord.readIndex = (historyRecordQTY-1);
		}
		else 
		{
			historyRecord.readIndex = historyRecordPointer-1;
		}
	}
	else 
	{
		historyRecord.readIndex = (historyRecordQTY-1);
	}
//	historyRecord.readIndex = (historyRecordQTY-1); //师进赏修改为读出历史数据为最新的一条 2020.4.2
	ReadHistoryRecord();//读一条历史数据	
	ReadInputTotalDose();//读取FM31256中存储的输入总量数据
	
	ReadProgramData();// 读出程序参数 add by wulianwei
	(*classification)++;//输注次数加一 add by wulianwei
	if( EngineeringModeValue.networkState ==  ENGINEERINGMODE_OFF )
	{
		registInfo->flag='N'; //设置设备未注册
	}
	WriteProgramData();
	
	
}

/*********************************************************************************
*  Function:	RunParamUpdate			                                                           
*  Object:		运行参数更新
*  输入:			无
*  输出:			无	                                     
*  备注:			1、为避免在运行中会对设置参数修改，在运行前对实时运行数据进行装载更新 
*							2、emSysWorkStep工作步骤必须在参数设置时
**********************************************************************************/
void RunParamUpdate( void )
{
	if( emSysWorkStep == EnterSetParam )
	{
		runParamInfo.totalDose = setParamInfo.totalDose * 10;
		runParamInfo.firstDose = setParamInfo.firstDose * 10;
		runParamInfo.continueDose = setParamInfo.continueDose1;
		runParamInfo.limitDose = setParamInfo.limitDose1;
		runParamInfo.superaddition = setParamInfo.superaddition1;
		runParamInfo.lockTime = setParamInfo.lockTime1;
		realTimeData.firstDose = setParamInfo.firstDose * 10;
		realTimeData.surplusDose = setParamInfo.totalDose * 10;				
 		//realTimeData.inputDose = ( setParamInfo.totalDose * 10 - realTimeData.surplusDose );
		realTimeData.inputDose = inputDose_bf;   //20170415  
		realTimeData.superaddition = 0;
	}
}
