#include <stdlib.h>
#include <math.h>
#include "main.h"
#include "CatOneTask.h"
#include "LoraTask.h"
#include "CatOneTask.h"
#include "RS485Task.h"
#include "DebugCmd.h"
#include "spiflash.h"


//雅下： 81-00-00-06-00-01
//			81-00-00-06-00-02
//			81-00-00-06-00-03
//			81-00-00-06-00-04
//			81-00-00-06-00-05
//			81-00-00-06-00-06
//			81-00-00-06-00-07
//			81-00-00-06-00-08
//			81-00-00-06-00-09
//			81-00-00-06-00-0A

static const uint8_t GateWayMac_Test[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x00};
static const uint8_t GateWayMac_BL1[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x01};
static const uint8_t GateWayMac_BL2[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x02};
static const uint8_t GateWayMac_BL3[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x03};
static const uint8_t GateWayMac_BL4[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x04};
static const uint8_t GateWayMac_BL5[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x05};
static const uint8_t GateWayMac_BL6[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x06};
static const uint8_t GateWayMac_BL7[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x07};
static const uint8_t GateWayMac_BL8[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x08};
static const uint8_t GateWayMac_BL9[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x09};
static const uint8_t GateWayMac_BL10[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x0A};
bool MainDispEn = true;

static rt_thread_t Lora_Thread = RT_NULL;
static rt_thread_t Cat1Eth_Thread = RT_NULL;
static rt_thread_t RS485Ch1_Thread = RT_NULL;
static rt_thread_t RS485Ch2_Thread = RT_NULL;
static rt_thread_t Debug_Thread = RT_NULL;

GateWayPara_t GateWay;

#define ARRAY_DIM(a) (sizeof(a) / sizeof((a)[0]))
//static int Battery_Level_Percent_Table[11] = {3000, 3650, 3700, 3740, 3760, 3795, 3840, 3910, 3980, 4070, 4150};
static int Battery_Level_Percent_Table[11] = {6000, 7300, 7400, 7480, 7520, 7590, 7680, 7820, 7960, 8140, 8300};
int toPercentage(int voltage)
{
	int i;
	if(voltage < Battery_Level_Percent_Table[0])
		return 0;
 
	for(i = 0; i<ARRAY_DIM(Battery_Level_Percent_Table); i++){
		if(voltage < Battery_Level_Percent_Table[i])
			return i*10 - (10UL * (int)(Battery_Level_Percent_Table[i] - voltage)) / 
			(int)(Battery_Level_Percent_Table[i] - Battery_Level_Percent_Table[i-1]);;
	}
 
	return 100;
}

/*****************************************************************************************
* 函数名称: MainDBGOnOff
* 功能描述: 主调试信息开关函数
* 参    数: OnOff,开关
* 返 回 值: 无
*****************************************************************************************/
void MainDBGOnOff(bool OnOff)
{
	MainDispEn = OnOff;
	if(OnOff)
		Debug_Printf("\r\nMain Display Enable!\r\n\r\n");
	else
		Debug_Printf("\r\nMain Display Disable!\r\n\r\n");
}

#if 0
uint32_t SDStartBlock;
uint8_t TestData[10 * 512];
uint8_t ADBuff[10 * 512];

void SDCardTest(void) 
{
	SDStartBlock = 0;
	SDCardReadBlocks(SDStartBlock, 10, TestData);
	if(TestData[0] != 0xAA) {
		SDCardErase(SDStartBlock, 10);
		memset(ADBuff, 0xAA, 10 * 512);
		SDCardWriteBlocks(SDStartBlock, 10, (uint8_t *)&ADBuff);
	}
	SDCardReadBlocks(SDStartBlock, 10, TestData);
}
#endif

void InfTest(void)
{
	uint8_t sData[10] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A};
	RS485_CH1_RX();
	RS485_CH1_POW_ON();
 	rt_thread_delay(100);
	RS485_CH1_POW_OFF();

	RS485_CH2_POW_ON();
	rt_thread_delay(100);
	RS485_CH2_POW_OFF();
	
	POWER_LED_OFF();
	POWER_LED_ON();
	LORA_RX_LED_SET();
	LORA_RX_LED_CLR();
	RS485_CH1_TX();
	RS485_CH2_RX();
	RS485Ch1_Config(500000);
	RS485Ch2_Config(500000);
	RS485Ch1UartSend(sData, 10);
	rt_thread_delay(100);
	
	RS485_CH2_TX();
	RS485_CH1_RX();
	RS485Ch2UartSend(sData, 10);
	rt_thread_delay(100);
//	SDCardTest();
}

void GateWayInit(void)
{
	LogHeader_t Header;
	uint32_t FlashID = SpiFlashReadId();
	Debug_Printf("FlashID: %08x\r\n", FlashID);
	
	memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
	int ret = ReadPara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	if(GateWay.ConfigPara.SavFlag != LOG_SAV_FLAG) {
		memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
		GateWay.ConfigPara.SavFlag = LOG_SAV_FLAG;
		GateWay.ConfigPara.Comm = CATONE_COMM;
//		memcpy(GateWay.ConfigPara.GwMac, GateWayMac, 6);
		GateWay.ConfigPara.SvrAddr[0] = 8;
		GateWay.ConfigPara.SvrAddr[1] = 137;
		GateWay.ConfigPara.SvrAddr[2] = 104;
		GateWay.ConfigPara.SvrAddr[3] = 4;
		GateWay.ConfigPara.SvrPort = 8007;
		GateWay.ConfigPara.CommUnitReadInterval = COMMUNIT_READ_SENSOR_INTERVAL_MAX;//非低功耗设备
		memset(GateWay.ConfigPara.CommUnitArray, 0x00, sizeof(CommUnitData_t) * COMMUNIT_NUM_MAX);
		GateWay.ConfigPara.Rs485Ch1.Enable = true;
		GateWay.ConfigPara.Rs485Ch1.CommUnitEnable = false;
		GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
		GateWay.ConfigPara.Rs485Ch1.UpgradeEnable = true;
		GateWay.ConfigPara.Rs485Ch1.Power = false;
		GateWay.ConfigPara.Rs485Ch2.Enable = true;
		GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
		GateWay.ConfigPara.Rs485Ch2.UpgradeEnable = false;
		GateWay.ConfigPara.Rs485Ch2.CommUnitEnable = false;
		GateWay.ConfigPara.Rs485Ch2.Power = true;
		
		GateWay.ConfigPara.Lora.OnOff = true;
		GateWay.ConfigPara.Lora.ucChannel = 8;
		GateWay.ConfigPara.Lora.ucPower = 20;
		GateWay.ConfigPara.Lora.SignalBw = 8;
		GateWay.ConfigPara.Lora.SpreadFactor = 9;
		GateWay.ConfigPara.Lora.ErrorCoding = 2;
		GateWay.ConfigPara.Lora.RegPreamble = 10;
		GateWay.ConfigPara.Lora.FreqCent = FREQ_CENT;
		GateWay.ConfigPara.OutageFlag = false;
		GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
	}
	
	if(GateWay.ConfigPara.OutageFlag != true && GateWay.ConfigPara.OutageFlag != false)
		GateWay.ConfigPara.OutageFlag = false;
	
	GateWay.SvrRegFlag = false;
	memset(GateWay.SvrMac, 0x00, 6);
	GateWay.ConfigPara.Rs485Ch1.RS485Send = RS485Ch1UartSend;
	GateWay.ConfigPara.Rs485Ch2.RS485Send = RS485Ch2UartSend;
	
	GateWay.ConfigPara.Rs485Ch1.Enable = true;
	GateWay.ConfigPara.Rs485Ch1.CommUnitEnable = false;
	GateWay.ConfigPara.Rs485Ch1.UpgradeEnable = true;
	GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
	GateWay.ConfigPara.Rs485Ch1.Power = false;
	GateWay.ConfigPara.Rs485Ch2.Enable = true;
	GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
	GateWay.ConfigPara.Rs485Ch2.CommUnitEnable = false;
	GateWay.ConfigPara.Rs485Ch2.UpgradeEnable = false;
	GateWay.ConfigPara.Rs485Ch2.Power = false;

	GateWay.ConfigPara.Lora.OnOff = true;
	GateWay.ConfigPara.Lora.ucChannel = 8;
	GateWay.ConfigPara.Lora.ucPower = 20;
	GateWay.ConfigPara.Lora.SignalBw = 8;
	GateWay.ConfigPara.Lora.SpreadFactor = 9;
	GateWay.ConfigPara.Lora.ErrorCoding = 2;
	GateWay.ConfigPara.Lora.RegPreamble = 10;
	GateWay.ConfigPara.Lora.FreqCent = FREQ_CENT;
	
#if MAC_ADDR_TYPE == 0
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_Test, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_DBG;
#elif MAC_ADDR_TYPE == 1
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL1, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
//	GateWay.ConfigPara.DebugChannel = DEBUG_CH_DBG;
#elif MAC_ADDR_TYPE == 2
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL2, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
//	GateWay.ConfigPara.DebugChannel = DEBUG_CH_DBG;
#elif MAC_ADDR_TYPE == 3
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL3, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 4
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL4, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 5
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL5, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 6
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL6, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 7
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL7, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 8
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL8, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 9
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL9, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#elif MAC_ADDR_TYPE == 10
	memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL10, 6);
	GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
#endif

#if MAC_ADDR_TYPE == 0//测试服务器
	GateWay.ConfigPara.SvrAddr[0] = 39;
	GateWay.ConfigPara.SvrAddr[1] = 106;
	GateWay.ConfigPara.SvrAddr[2] = 103;
	GateWay.ConfigPara.SvrAddr[3] = 147;
	GateWay.ConfigPara.SvrPort = 8080;
#elif MAC_ADDR_TYPE > 0
//	GateWay.ConfigPara.SvrAddr[0] = 39;
//	GateWay.ConfigPara.SvrAddr[1] = 106;
//	GateWay.ConfigPara.SvrAddr[2] = 103;
//	GateWay.ConfigPara.SvrAddr[3] = 147;
//	GateWay.ConfigPara.SvrPort = 8080;
	GateWay.ConfigPara.SvrAddr[0] = 103;
	GateWay.ConfigPara.SvrAddr[1] = 217;
	GateWay.ConfigPara.SvrAddr[2] = 192;
	GateWay.ConfigPara.SvrAddr[3] = 248;
	GateWay.ConfigPara.SvrPort = 12111;
#endif

	if(GateWay.ConfigPara.DebugChannel == DEBUG_CH_RS485_1) {
		GateWay.ConfigPara.Rs485Ch1.Enable = true;
		GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
	}
	if(GateWay.ConfigPara.Rs485Ch1.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch1.BaudRate > 921600)
		GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
	RS485Ch1_Config(GateWay.ConfigPara.Rs485Ch1.BaudRate);
	
	if(GateWay.ConfigPara.DebugChannel == DEBUG_CH_RS485_2) {
		GateWay.ConfigPara.Rs485Ch2.Enable = true;
		GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
	}
	if(GateWay.ConfigPara.Rs485Ch2.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch2.BaudRate > 921600)
		GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
	RS485Ch2_Config(GateWay.ConfigPara.Rs485Ch2.BaudRate);
	
	if(GateWay.ConfigPara.Rs485Ch1.Power)
		RS485_CH1_POW_ON();
	else
		RS485_CH1_POW_OFF();
	
	if(GateWay.ConfigPara.Rs485Ch2.Power) {
		RS485_CH2_POW_OFF();
		rt_thread_delay(1000);
		RS485_CH2_POW_ON();
	}
	else
		RS485_CH2_POW_OFF();
	
	if(GateWay.ConfigPara.Lora.OnOff == true) {
		LORA_POW_ON();
	}
	else {
		LORA_POW_OFF();
	}
	if(LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel) == false) {
		GateWay.ConfigPara.Lora.ucChannel = 8;
		LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel);
		//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	}
	if(LoraSetPower(GateWay.ConfigPara.Lora.ucPower) == false) {
		GateWay.ConfigPara.Lora.ucPower = 20;
		LoraSetPower(GateWay.ConfigPara.Lora.ucPower);
		//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	}
	if(LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw) == false) {
		GateWay.ConfigPara.Lora.SignalBw = 8;
		LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw);
		//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	}
	if(LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor) == false) {
		GateWay.ConfigPara.Lora.SpreadFactor = 9;
		LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor);
		//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	}
	if(LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding) == false) {
		GateWay.ConfigPara.Lora.ErrorCoding = 2;
		LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding);
		//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	}
	if(GateWay.ConfigPara.Lora.RegPreamble > 0xFE) {
		GateWay.ConfigPara.Lora.RegPreamble = 10;
		//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	}
	LoraSetRegPreamble(GateWay.ConfigPara.Lora.RegPreamble);
	
	WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
	
	LogInit();
	
	Header.LogEndAddr = 0;
	if(ReadLogNum() > 0) {
		int ret = ReadLog(&Header, NULL, 0);
		if(ret > 0) {
			GateWay.HistoryNum = ReadLogNum() - Header.LogIdx + 1;
			rt_kprintf("History Num: %d\r\n", GateWay.HistoryNum);
		}
		else {
			rt_kprintf("History Num: 0\r\n");
		}
	}
	else
		rt_kprintf("History Num: 0\r\n");
	if(GateWay.ConfigPara.Comm == CATONE_COMM) {
		CAT1_ON();
	}
	else {
		ETH_ON();
	}
}

void OutageUpdate(uint8_t AlarmType, bool AlarmState, uint8_t Batt)
{
	GateWayAlarmType_t *Alarm;
	uint8_t MegData[6],len;
	len = sizeof(GateWayAlarmType_t);
	MegData[0] = len & 0x00ff;;
	MegData[1] = (len >> 8) & 0x00ff;
	MegData[2] = NET_COMM_CMD_ALARM;
	
	Alarm = (GateWayAlarmType_t *)&MegData[3];
	Alarm->AlarmType = AlarmType;
	Alarm->AlarmState = AlarmState;
	Alarm->AlarmPara = Batt;
	CatOneEthSendQueue(MegData, 6);		//发送报警信息     
}

/*****************************************************************************************
* 函数名称: main
* 功能描述: 主函数
* 参    数: 无
* 返 回 值: 运行错误返回-1
*****************************************************************************************/
static	uint8_t LastBattery = 0xff;	//上一次电池电压
int main(void) 
{	
	uint16_t OneSecondDlyCnt = 0;
//	struct tm cTime;
	uint16_t PowerONLedDly = 2000;
	uint32_t SystemRseetDlyCnt = 0;
	uint32_t BatteryUpdateDlyCnt = 0;
	uint8_t AlarmType = 0;
	
	GateWayInit();
	
	rt_kprintf("\r\n\r\n");
	rt_kprintf("****************************************************\r\n");
	rt_kprintf("**                                                **\r\n");
	rt_kprintf("**                   GateWay                      **\r\n");
	rt_kprintf("**                SoftWare V%d.%d                   **\r\n", SOFTWARE_VERSION / 10, SOFTWARE_VERSION % 10);
	rt_kprintf("**                HardWare V%d.%d                   **\r\n", HARDWARE_VERSION / 10, HARDWARE_VERSION % 10);
	rt_kprintf("**         Compile: %s %s          **\r\n", __DATE__, __TIME__);
	rt_kprintf("**                                                **\r\n");
	rt_kprintf("****************************************************\r\n\r\n");
//	TimeGet(&cTime);
//	TimeShow(TimeTs());
	FeedDog();
	//rt_thread_delay(500);
	//InfTest();
	//FeedDog();
	
	//Cat1DBGOnOff(true);
	
	
	GateWay.CommUnitRevCallBack = CommUnitAnalyze;
	GateWay.SvrRevCallBack = Cat1EthRevCallBack;
	
	GateWay.NetSendData_MQ = rt_mq_create("NetSendMQ", 512, 10, RT_IPC_FLAG_FIFO);
	if(GateWay.NetSendData_MQ == RT_NULL) {
		rt_kprintf("CatOne MQ Create Failed!\r\n");
	}
	
	GateWay.LoraRev_MQ = rt_mq_create("LoraRevMQ", 256, 10, RT_IPC_FLAG_FIFO);
	if(GateWay.LoraRev_MQ == RT_NULL) {
		rt_kprintf("LoraRev MQ Create Failed!\r\n");
	}
	
	GateWay.UartRevMutex = rt_mutex_create("urmutex", RT_IPC_FLAG_FIFO);
	if(GateWay.UartRevMutex == RT_NULL) {
		rt_kprintf("UR Mutex Create Failed!\r\n");
	}
	
	GateWay.SvrRevCallBack = Cat1EthRevCallBack;
	
	RS485Ch1_Thread = rt_thread_create("RS485Ch1", RS485Ch1_Thread_Entry, &GateWay, 2048, 3, 20);
	if (RS485Ch1_Thread != RT_NULL)
		rt_thread_startup(RS485Ch1_Thread);
	else
		return -1;
	
	RS485Ch2_Thread = rt_thread_create("RS485Ch2", RS485Ch2_Thread_Entry, &GateWay, 2048, 3, 20);
	if (RS485Ch2_Thread != RT_NULL)
		rt_thread_startup(RS485Ch2_Thread);
	else
		return -1;
	
	Debug_Thread = rt_thread_create("DebugUart", Debug_Thread_Entry, &GateWay, 2048, 3, 20);
	if (RS485Ch2_Thread != RT_NULL)
		rt_thread_startup(Debug_Thread);
	else
		return -1;
		
	Cat1Eth_Thread = rt_thread_create("Cat1Eth", CatOne_Eth_Thread_Entry, &GateWay, 4096, 3, 20);
	if (Cat1Eth_Thread != RT_NULL)
		rt_thread_startup(Cat1Eth_Thread);
	else
		return -1;
	
	Lora_Thread = rt_thread_create("Lora", Lora_Thread_Entry, &GateWay, 1024, 3, 20);
	if (Lora_Thread != RT_NULL)
		rt_thread_startup(Lora_Thread);
	else
		return -1;
	
	while(1) {
		if(PowerONLedDly > 0) {
			PowerONLedDly--;
			if(PowerONLedDly == 1) {
				POWER_LED_OFF();
			}
		}
		EthRxOverhandler();
		RS485RxOverhandler();
		DebugRxOverhandler();
		if(OneSecondDlyCnt % 200 == 0) {
			FeedDog();
			LORA_RX_TOGGLE();
			POWER_TOGGLE();
		}
		OneSecondDlyCnt++;
		if(OneSecondDlyCnt == 1000) { 
			OneSecondDlyCnt = 0;
			
			if(GateWay.BatteryReadDlyCnt > 0) {
				GateWay.BatteryReadDlyCnt--;
				continue;
			}
			
			uint16_t ADValue = GetADCBuffPoint();
			//V = (AD * 3.3 / 4096) * (R1+R2) / R1; R1 = 200, R2 = 120
			//计算出常数为0.0021484375，扩大1000倍
			float Voltage = ADValue * 2.1484375;
			GateWay.Battery = toPercentage(Voltage);
			
			//上电判断电量
			if(LastBattery == 0xff) {
				LastBattery = GateWay.Battery;
			
				if(GateWay.ConfigPara.OutageFlag == true)	{	//有报警
					AlarmType = 1;
				}
				else {
					AlarmType = 0;
				}
				//BatteryUpdateDlyCnt = 2 * 60;
				BatteryUpdateDlyCnt = 10;
			}
			else {
				if(GateWay.ConfigPara.OutageFlag == false) {		//没有告警，判断电池电压是否降低
					if(GateWay.Battery <= LastBattery) {
						if(LastBattery <= 5) {
							GateWay.ConfigPara.OutageFlag = true;
							WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
							Debug_Printf("The power is cutted.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
							LastBattery = GateWay.Battery;
							AlarmType = 1;
							OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
							BatteryUpdateDlyCnt = 20 * 60;
						}
						else if((LastBattery - GateWay.Battery) > 2) {
							GateWay.ConfigPara.OutageFlag = true;
							WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
							LastBattery = GateWay.Battery;
							AlarmType = 1;
							Debug_Printf("The power is cutted.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
							OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
							BatteryUpdateDlyCnt = 20 * 60;
						}
					}
					else {		//充电，更新上一次电池电压
						LastBattery = GateWay.Battery;
					}
				}
				else {
					if(GateWay.Battery >= LastBattery) {
						if(LastBattery > 95) {
							GateWay.ConfigPara.OutageFlag = false;
							WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
							Debug_Printf("The power is restored.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
							LastBattery = GateWay.Battery;
							AlarmType = 1;
							OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
							BatteryUpdateDlyCnt = 90 * 60;
							AlarmType = 0;
						}
						else if(GateWay.Battery - LastBattery > 5) {
							GateWay.ConfigPara.OutageFlag = false;
							WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
							Debug_Printf("The power is restored.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
							LastBattery = GateWay.Battery;
							AlarmType = 1;
							OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
							BatteryUpdateDlyCnt = 90 * 60;
							AlarmType = 0;
						}
					}
					else {	//电池继续放电，更新上一次电池电压
						LastBattery = GateWay.Battery;
					}
				}
			}
			BatteryUpdateDlyCnt--;
			if(BatteryUpdateDlyCnt == 0) {
				if(GateWay.ConfigPara.OutageFlag)	{	//有报警
					BatteryUpdateDlyCnt = 20 * 60;
				}
				else {
					BatteryUpdateDlyCnt = 90 * 60;
				}
  			OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
			}
			//ADC_Start();
		}
		SystemRseetDlyCnt++;
		if(SystemRseetDlyCnt > (24 * 60 * 60 * 1000)) {
			SystemRseetDlyCnt = 0;
			Debug_Printf("The system resets periodically.\r\n");
			rt_thread_delay(10);
			NVIC_SystemReset();
		}
		rt_thread_delay(1);
	}
}



#if 0
static FATFS SDFatFs;
static FIL TestFile;
static uint8_t u8WorkBuffer[FF_MAX_SS];

void FSInit(void)
{
	FRESULT fRet;
	uint32_t u32WBNbr, u32RBNbr;
	char SDPath[] = "1:";
	MKFS_PARM opt;
	uint8_t u8ReadText[100];
	en_result_t enTestRet = Error;
	uint8_t u8WriteText[] = "This is a string used to test the FatFs";
	
	if (FR_OK != f_mount(&SDFatFs, (TCHAR const*)SDPath, 0U)) { 
		rt_kprintf("FatFs Initialization Error!\r\n"); 
	}
	else { 
		memset(&opt, 0, sizeof(MKFS_PARM));
		opt.fmt = (BYTE)FM_FAT32;
		/* Create a FAT file system (format) on the logical drive */
		if (FR_OK != f_mkfs((TCHAR const*)SDPath, &opt, u8WorkBuffer, sizeof(u8WorkBuffer))) { 
			rt_kprintf("FatFs Format Error!\r\n"); 
		} 
		else { 
			/* Create and Open a new text file object with write access */
			if (FR_OK != f_open(&TestFile, "1:Test.txt", ((BYTE)FA_CREATE_ALWAYS | (BYTE)FA_WRITE))) { 
				rt_kprintf("\"Test.txt\" file Open for write Error!\r\n"); 
			} 
			else { 
				/* Write data to the text file */
				fRet = f_write(&TestFile, u8WriteText, sizeof(u8WriteText), (void *)&u32WBNbr);
				if ((0UL == u32WBNbr) || (FR_OK != fRet)) { 
					rt_kprintf("\"Test.txt\" file Write or EOF Error!\r\n"); 
  				else { 
					/* Close the open text file */
					f_close(&TestFile);
					/* Open the text file object with read access */
					if (FR_OK != f_open(&TestFile, "1:Test.txt", (BYTE)FA_READ)) { 
						rt_kprintf("\"Test.txt\" file Open for read Error!\r\n"); 
					} 
					else { 
						memset(u8ReadText, 0, sizeof(u8ReadText));
						/* Read data from the text file */
						fRet = f_read(&TestFile, u8ReadText, sizeof(u8ReadText), (UINT*)(uint32_t)&u32RBNbr);
						if ((0UL == u32RBNbr) || (FR_OK != fRet)) { 
							rt_kprintf("\"Test.txt\" file Read or EOF Error!\r\n"); 
						} 
						else { 
							/* Close the open text file */
							f_close(&TestFile);
							/* Compare read data with the expected data */
							if (u32RBNbr == u32WBNbr) { 
								/* Check data value */
								if (0 == memcmp(u8WriteText, u8ReadText, u32RBNbr)) { 
									enTestRet = Ok;
								} 
							} 
						} 
					} 
				} 
			} 
		} 
	} 
	/* Unlink the micro SD disk I/O driver */
	f_mount(NULL, (TCHAR const*)SDPath, 0U);
	
	if(enTestRet != Ok) {
		rt_kprintf("Error!\r\n"); 
	}
	else {
		rt_kprintf("Ok!\r\n"); 
	}
}

#endif

