3045db0ef6
- sx127x.h: 信道宏CH0~CH119, 基准433100000ul+500kHz步进(CH0=433.1MHz, CH119=492.6MHz) - sx127x.h: SX1276_CHANNEL_MAX 46 -> 120, LoraSetChannel范围检查自动跟随 - sx127x.c: gdwSx1276ChannelTbl信道表扩为120项 - sx127x.c: LoraSetFreqCent频率校验范围改为433.1MHz~492.6MHz(原470.1下限会拒绝CH0~CH73) - main.c: 频率校验失败回退默认值改为CH0(433.1MHz) - 注意: 信道号与窄频版(develop)语义不同, 同编号对应不同频率, 两种固件设备互不相通 - 默认信道CH8在宽频下为437.1MHz
531 lines
19 KiB
C
531 lines
19 KiB
C
#include "main.h"
|
||
#include "CatOneTask.h"
|
||
#include "EthTask.h"
|
||
#include "LoraTask.h"
|
||
#include "RS485Task.h"
|
||
#include "DebugCmd.h"
|
||
#include "Update.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
|
||
|
||
//网关MAC编码由Boot程序固定在0x4000(协议规定: VerInfo(1)+PrjNum(3)+GwNum(2))
|
||
bool MainDispEn = true;
|
||
|
||
static rt_thread_t Lora_Thread = RT_NULL;
|
||
static rt_thread_t Cat1_Thread = RT_NULL;
|
||
static rt_thread_t Eth_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");
|
||
}
|
||
|
||
|
||
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));
|
||
boot_para_t bootParam;
|
||
dev_boot_read_param(&bootParam);
|
||
rt_kprintf("AppFlag: 0x%08x\r\n", bootParam.AppFlag);
|
||
/*升级完成后Boot置AppFlag=APP_BOOT_UPGRADE_FLAG(每次升级均置位,不限首次)。
|
||
App启动时据此擦除参数分区(仅扇区0~1,非全片擦除)并恢复APP_START_FLAG;
|
||
随后ReadPara读到0xFF→SavFlag无效→自动加载默认参数,传感器重新注册。
|
||
须在下方升级异常检测之前处理,避免AppFlag!=APP_START_FLAG误触发全片擦除*/
|
||
if(bootParam.AppFlag == APP_BOOT_UPGRADE_FLAG) {
|
||
rt_kprintf("Upgrade done, erasing parameter partition...\r\n");
|
||
for(uint32_t Sector = GATEWEY_PARA_SAV_SECTOR; Sector < LOG_INFO_START_SECTOR; Sector++) {
|
||
SpiFlashEraseSector(Sector * SPIFLASH_SECTORSIZE);
|
||
}
|
||
bootParam.AppFlag = APP_START_FLAG;
|
||
dev_boot_write_param(bootParam);
|
||
}
|
||
/*检测升级异常(UpdateFlag仍为APP_UPDATE_FLAG 或 非首次且AppFlag无效)时擦外置Flash*/
|
||
if(bootParam.UpdateFlag == APP_UPDATE_FLAG
|
||
|| (bootParam.FirstRunFlag == 0 && bootParam.AppFlag != APP_START_FLAG)) {
|
||
rt_kprintf("Boot upgrade detected, erasing external Flash...\r\n");
|
||
SpiFlashEraseChip();
|
||
bootParam.UpdateFlag = 0;
|
||
dev_boot_write_param(bootParam);
|
||
}
|
||
|
||
bool NeedSavePara = false;
|
||
int ret = ReadPara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||
/*ReadPara返回-1表示CRC校验失败(参数镜像损坏)。原实现只检查SavFlag:
|
||
SavFlag位于结构体最前部,"部分损坏"的镜像(前部有效后部乱码)恰好保留合法
|
||
SavFlag,坏数据会被整体装入RAM——正是culs显示后面设备参数乱码的根源。
|
||
CRC失败必须回退默认参数,让传感器走重新注册流程*/
|
||
if(ret != 0) {
|
||
rt_kprintf("Para CRC Error, reset to default!\r\n");
|
||
}
|
||
if(ret != 0 || GateWay.ConfigPara.SavFlag != LOG_SAV_FLAG) {
|
||
/*CRC正常但SavFlag无效:flash参数为空(全新设备/曾执行res gxjt/Boot整片擦除后),
|
||
打印区分于CRC错误路径,便于现场排障判断走的是默认参数还是正常恢复*/
|
||
if(ret == 0)
|
||
rt_kprintf("Para empty, load default!\r\n");
|
||
NeedSavePara = true;
|
||
memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
|
||
GateWay.ConfigPara.SavFlag = LOG_SAV_FLAG;
|
||
/*通道/服务器等默认参数全部从Boot参数区(BootPara_t)获取, 由Boot直接配置*/
|
||
GateWay.ConfigPara.Much = (Channel_m)bootParam.Much;
|
||
GateWay.ConfigPara.Auch = (Channel_m)bootParam.Auch;
|
||
GateWay.ConfigPara.Duch = (Channel_m)bootParam.Duch;
|
||
GateWay.ConfigPara.CuchMask = bootParam.CuchMask;
|
||
GateWay.ConfigPara.LTENet.DestAddr[0] = bootParam.SvrAddr[0];
|
||
GateWay.ConfigPara.LTENet.DestAddr[1] = bootParam.SvrAddr[1];
|
||
GateWay.ConfigPara.LTENet.DestAddr[2] = bootParam.SvrAddr[2];
|
||
GateWay.ConfigPara.LTENet.DestAddr[3] = bootParam.SvrAddr[3];
|
||
GateWay.ConfigPara.LTENet.DestPort = bootParam.SvrPort;
|
||
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 = 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 = bootParam.LoraFreq;
|
||
|
||
GateWay.ConfigPara.OutageFlag = false;
|
||
}
|
||
else {
|
||
/*防御被"洗白"的脏数据(镜像部分损坏但CRC合法):对通讯单元表做语义校验,
|
||
清除无效条目,避免乱码条目占用注册槽位导致新设备注册不上*/
|
||
for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
|
||
CommUnitPara_t *CU = &GateWay.ConfigPara.CommUnitArray[i];
|
||
uint8_t RegByte;
|
||
memcpy(&RegByte, &CU->RegFlag, 1); //绕过编译器对bool取值0/1的假定,读取原始字节
|
||
bool EntryValid = (RegByte == 0 || RegByte == 1);
|
||
if(EntryValid && RegByte == 1) {
|
||
bool MacAllFF = true, MacAll00 = true;
|
||
for(int j = 0; j < 6; j++) {
|
||
if(CU->Mac[0][j] != 0xFF) MacAllFF = false;
|
||
if(CU->Mac[0][j] != 0x00) MacAll00 = false;
|
||
}
|
||
if(CU->SensorN == 0 || CU->SensorN > SENSOR_NUM_MAX || MacAllFF || MacAll00)
|
||
EntryValid = false;
|
||
}
|
||
if(!EntryValid) {
|
||
memset(CU, 0x00, sizeof(CommUnitPara_t));
|
||
NeedSavePara = true;
|
||
}
|
||
}
|
||
if(NeedSavePara)
|
||
rt_kprintf("CommUnit table dirty, cleaned!\r\n");
|
||
}
|
||
|
||
/*函数指针不允许从Flash恢复:正常加载路径下RS485Send来自旧固件写入Flash的
|
||
代码地址,固件升级后代码布局变化会使该指针失效(野指针)。每次开机统一重设*/
|
||
GateWay.ConfigPara.Rs485Ch1.RS485Send = RS485Ch1UartSend;
|
||
GateWay.ConfigPara.Rs485Ch2.RS485Send = RS485Ch2UartSend;
|
||
|
||
/*网关MAC编码从Boot参数区(BootPara_t.GwMac)获取, 由Boot从固定地址0x4000同步
|
||
(协议规定: Mac[0]=VerInfo, Mac[1:3]=PrjNum, Mac[4:5]=GwNum)*/
|
||
for(int i = 0; i < 6; i++) {
|
||
GateWay.ConfigPara.GwMac[i] = bootParam.GwMac[i];
|
||
}
|
||
|
||
/*参照hc32l170_app UpdateInit: 保证AppFlag=APP_START_FLAG, 使Boot下次直接跳转App*/
|
||
UpdateInit();
|
||
|
||
if(GateWay.ConfigPara.OutageFlag != true && GateWay.ConfigPara.OutageFlag != false)
|
||
GateWay.ConfigPara.OutageFlag = false;
|
||
|
||
GateWay.MuchRegFlag = false;
|
||
memset(GateWay.SvrMac, 0x00, 6);
|
||
|
||
if(ChannelIsActive(GateWay.ConfigPara, 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(ChannelIsActive(GateWay.ConfigPara, 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(LoraSetFreqCent(GateWay.ConfigPara.Lora.FreqCent) == false)
|
||
{
|
||
GateWay.ConfigPara.Lora.FreqCent = 433100000; //lora-wide: 回退到CH0
|
||
LoraSetFreqCent(GateWay.ConfigPara.Lora.FreqCent);
|
||
}
|
||
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;
|
||
LoraSetRegPreamble(GateWay.ConfigPara.Lora.RegPreamble);
|
||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||
}
|
||
|
||
/*原实现开机无条件回写参数:一方面无谓增加一次擦写磨损;另一方面若读出的
|
||
是坏数据,回写会重新计算CRC把脏数据"洗白"成永久合法,无法自愈。
|
||
仅在参数被重置或清洗过时才落盘*/
|
||
if(NeedSavePara)
|
||
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");
|
||
bool cat1Active = ChannelIsActive(GateWay.ConfigPara, CH_CAT1);
|
||
bool ethActive = ChannelIsActive(GateWay.ConfigPara, CH_ETH);
|
||
if(cat1Active) { DbgOrCat1Uart_Config(115200); CAT1_ON(); }
|
||
else { DBG_ON(); DbgOrCat1Uart_Config(500000); }
|
||
if(ethActive) { ETH_ON(); rt_thread_delay(1000); ETHReset(); }
|
||
}
|
||
|
||
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;
|
||
UploadSend(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();
|
||
|
||
//Cat1DBGOnOff(true);
|
||
|
||
|
||
GateWay.CommUnitRevCallBack = CommUnitAnalyze;
|
||
GateWay.MuchRevCallBack = MuchRevCallBack;
|
||
GateWay.AuchRevCallBack = AuchRevCallBack;
|
||
|
||
for(int i = 0; i < 6; i++) {
|
||
char name[8];
|
||
sprintf(name, "ChMQ%d", i);
|
||
GateWay.ChMQ[i] = rt_mq_create(name, 256, 5, RT_IPC_FLAG_FIFO);
|
||
}
|
||
|
||
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.EthTxMutex = rt_mutex_create("ethtxmtx", RT_IPC_FLAG_FIFO);
|
||
if(GateWay.EthTxMutex == RT_NULL) {
|
||
rt_kprintf("EthTx Mutex Create Failed!\r\n");
|
||
}
|
||
|
||
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 (Debug_Thread != RT_NULL)
|
||
rt_thread_startup(Debug_Thread);
|
||
else
|
||
return -1;
|
||
|
||
Cat1_Thread = rt_thread_create("Cat1", CatOne_Thread_Entry, &GateWay, 4096, 3, 20);
|
||
if (Cat1_Thread != RT_NULL)
|
||
rt_thread_startup(Cat1_Thread);
|
||
else
|
||
return -1;
|
||
|
||
Eth_Thread = rt_thread_create("Eth", Eth_Thread_Entry, &GateWay, 4096, 3, 20);
|
||
if (Eth_Thread != RT_NULL)
|
||
rt_thread_startup(Eth_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();
|
||
}
|
||
}
|
||
if(ChannelIsActive(GateWay.ConfigPara, CH_ETH)) EthOverHandler();
|
||
if(ChannelIsActive(GateWay.ConfigPara, CH_RS485_1) || ChannelIsActive(GateWay.ConfigPara, CH_RS485_2)
|
||
|| GateWay.ConfigPara.Rs485Ch1.UpgradeEnable || GateWay.ConfigPara.Rs485Ch2.UpgradeEnable)
|
||
RS485RxOverhandler();
|
||
DebugOrCat1RxOverhandler();
|
||
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(3000);
|
||
NVIC_SystemReset();
|
||
}
|
||
rt_thread_delay(1);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|