/****************************************************************************** * Include files ******************************************************************************/ #include #include "main.h" #include "UartDebug.h" #include "bsp.h" #include "Algorithm.h" #include "SGCP.h" #include "Update.h" #include "sx127x.h" #include "lsm6dsl_app.h" #include "mmc5983.h" AppDetect_t App; extern uint32_t LocalType; extern uint32_t CommWay; extern uint32_t DeviceSign; extern uint32_t AddNumber; extern uint8_t LocalMAC[6]; //本机MAC地址 extern uint8_t GatewayMAC[6]; //网关MAC地址,注册时全为0 extern uint8_t LocalDataPack[sizeof(SGCP.DevData.LaserTracing)]; //本机数据包 //本机数据包 bool MainDispEn = true; bool DataDispEn = true; /***************************************************************************************** * 函数名称: MainDBGOnOff * 功能描述: 主调试信息开关函数 * 参 数: OnOff,开关 * 返 回 值: 无 *****************************************************************************************/ void MainDBGOnOff(bool OnOff) { MainDispEn = OnOff; if(OnOff) DBG_LOG("\r\nMain Display Enable!\r\n\r\n"); else DBG_LOG("\r\nMain Display Disable!\r\n\r\n"); } /***************************************************************************************** * 函数名称: DataDBGOnOff * 功能描述: 数据信息开关函数 * 参 数: OnOff,开关 * 返 回 值: 无 *****************************************************************************************/ void DataDBGOnOff(bool OnOff) { DataDispEn = OnOff; if(OnOff) DBG_LOG("\r\nData Display Enable!\r\n\r\n"); else DBG_LOG("\r\nData Display Disable!\r\n\r\n"); } void Lsm6dDataProcessCallBack(float *Acc, float *Gy) { memcpy(App.Sensor.acce, Acc, 12); memcpy(App.Sensor.gy, Gy, 12); //MAIN_DBG_LOG("acc_X:%07.1f, acc_Y:%07.1f, acc_Z:%07.1f\r\n", App.Sensor.acce[X], App.Sensor.acce[Y],App.Sensor.acce[Z]); //MAIN_DBG_LOG("gy_X:%07.1f, gy_Y:%07.1f, gy_Z:%07.1f\r\n", App.Sensor.gy[X], App.Sensor.gy[Y],App.Sensor.gy[Z]); App.AccRead_EndFlag = true; } void MmcDataProcessCallBack(float *Mag) { memcpy(App.Sensor.mag, Mag, 12); //MAIN_DBG_LOG("mag_X:%07.1f, mag_Y:%07.1f, mag_Z:%07.1f\r\n", App.Sensor.mag[X], App.Sensor.mag[Y],App.Sensor.mag[Z]); App.MagRead_EndFlag = true; } static void AppInit(void) { memset(&App, 0x00, sizeof(App)); READ_APP_PARA((uint32_t *)&App.Para); #if(USE_BOOTLOADER) UpdateInit(); for(int i = 0; i < 6; i++) { LocalMAC[i] = *((volatile const uint8_t *)(0x00002800 + i)); } memcpy(&App.Para.BLPara.DevMac, &LocalMAC[0], 6); LocalType = (App.Para.BLPara.DevMac[0] | (App.Para.BLPara.DevMac[1] << 8)); //本机设备类型 CommWay = App.Para.BLPara.DevMac[2]; //本机通讯方式 DeviceSign = App.Para.BLPara.DevMac[3] & 0x80; //本机设备标志 AddNumber = ((App.Para.BLPara.DevMac[3] << 16)+ (App.Para.BLPara.DevMac[4] << 8) + App.Para.BLPara.DevMac[5]) - 0x800000; //本机地址编号,数字部分对应唯一地址编号 #else LocalType = LASER_TRACING; //本机设备类型 CommWay = LORA; //本机通讯方式 DeviceSign = MASTER; //本机设备标志 AddNumber = 0x000023 + DeviceSign;//本机地址编号,数字部分对应唯一地址编号 App.Para.BLPara.LoraFreq = CH0; LocalMAC[0] = LocalType & 0xFF; //本机MAC地址 LocalMAC[1] = (LocalType >> 8) & 0xFF; LocalMAC[2] = CommWay; LocalMAC[3] = (AddNumber >> 16) & 0xFF; LocalMAC[4] = (AddNumber >> 8) & 0xFF; LocalMAC[5] = AddNumber & 0xFF; #endif //09 00 01 00 00 00 if(App.Para.FactoryFlag != 0x00) { App.Para.FactoryFlag = 0x00; /*校准参数初始化*/ App.Para.CaliPara.PitchZero = 0; App.Para.CaliPara.RollZero = 0; App.Para.CaliPara.YawZero = 0; App.Para.Rs485Ch1.Enable = true; App.Para.Rs485Ch1.UpgradeEnable = true; App.Para.Rs485Ch1.Addr = 1; App.Para.Rs485Ch1.BaudRate = 9600; App.Para.Rs485Ch2.Enable = false; App.Para.Rs485Ch2.UpgradeEnable = false; App.Para.Rs485Ch2.Addr = 1; App.Para.Rs485Ch2.BaudRate = 500000; App.Para.Lora.OnOff = true; App.Para.Lora.ucChannel = 8; App.Para.Lora.ucPower = 20; App.Para.Lora.SignalBw = 8; App.Para.Lora.SpreadFactor = 9; App.Para.Lora.ErrorCoding = 2; App.Para.Lora.RegPreamble = 10; App.Para.BLPara.LoraFreq = CH0; App.Para.Layout.CollectTime = 10; App.Para.Layout.ReportInterval = 40; App.Para.Layout.ERInterval = 4; App.Para.Layout.ERTime = 40; } if(App.Para.BLPara.LoraFreq < 410000000 || App.Para.BLPara.LoraFreq > 525000000) App.Para.BLPara.LoraFreq = CH0; App.Para.Lora.FreqCent = App.Para.BLPara.LoraFreq; SX1276LoRaWriteFreq(App.Para.Lora.FreqCent); //Lora频率:433100000ul + 200000*N if(App.Para.Rs485Ch1.Addr > 16 || App.Para.Rs485Ch1.Addr < 1){ App.Para.Rs485Ch1.Addr = 1; } if(App.Para.Rs485Ch2.Addr > 16 || App.Para.Rs485Ch2.Addr < 1){ App.Para.Rs485Ch2.Addr = 1; } if(App.Para.Layout.CollectTime > 240 || App.Para.Layout.CollectTime < 1) { App.Para.Layout.CollectTime = 10; } if(App.Para.Layout.ReportInterval > 1440 || App.Para.Layout.ReportInterval < 10) { App.Para.Layout.ReportInterval = 40; } if(App.Para.Layout.ERInterval > 10 || App.Para.Layout.ERInterval < 2) { App.Para.Layout.ERInterval = 4; } if(App.Para.Layout.ERTime > 240 || App.Para.Layout.ERTime < 20) { App.Para.Layout.ERTime = 40; } SAVE_APP_PARA((uint32_t *)&App.Para); LpUart0Init(App.Para.Rs485Ch1.BaudRate);//低功耗串口初始化 LORAIntEnable(); LoraInit(); //< LORA芯片初始化 FeedDog(); Lsm6dslInit(); MMC5983Init(); MMC5983Stop(); Lsm6dsStop(); ACCandMMCIntEnable(); LPTimer0_OFF(); uint32_t seed = 0;//< 随机数初始化 seed = seed + LocalMAC[2]; seed = (seed << 8) + LocalMAC[3]; seed = (seed << 8) + LocalMAC[4]; seed = (seed << 8) + LocalMAC[5]; srand(seed); App.Nonce = rand(); SGCP.LoginOk = false; SGCP.LoginMess = false; SGCP.LaserOnOff = false; SGCP.MasterCaliOk = true; SGCP.DeviceReadDataOk = false; SGCP.TimingAcquisition = false; App.Login2Min30SCount = 0; App.Login30MinCount = 0; App.RepeLoginCount = 0; App.LoginFlag = false; App.Login_RTC = false; App.Login_LPTimer0 = true; //LPTimer0_ON((App.Nonce % 1200) + 300);//定时30s+随机2分钟,最小间隙100ms LPTimer0_ON(50);//5秒后注册 if(App.Para.LaserTimerMinutes == 0) App.Para.LaserTimerMinutes = 10; SGCP.LaserTimerMinutes = App.Para.LaserTimerMinutes; App.UploadFlag = false; App.Upload_LPTimer0 = false; App.Coll_N = 0; App.Repor_N = 0; App.ERInterval_N = 0; App.ERTime_N = 0; App.ERFlag = false; App.MagRead_EndFlag = false; App.AccRead_EndFlag = false; App.UpdateOk = false; App.CaliFlag = false; App.Status = APP_STATUS_ON; App.TD1mSDelayCnt = (App.Nonce % 2000) + 2000; } static void ReadDataLoopHandler(void) { switch (App.RDStatus) { case READDATA_STATUS_IDLE:{ break;} case READDATA_STATUS_UPDAING:{ DATA_DBG_LOG("<------------ Sensor Data Updaing ------------> \r\n"); App.UpdateOk = false; Lsm6dsStart(); MMC5983Start(); App.ReadData1mSDelayCnt = 2000; App.RDStatus = READDATA_STATUS_WAIT_UPDAING; break;} case READDATA_STATUS_WAIT_UPDAING:{ if(App.ReadData1mSDelayCnt <= 0){ if(App.AccRead_EndFlag == false) DATA_DBG_LOG("Lsm6dsl Get Data TimeOut...\r\n"); if(App.MagRead_EndFlag == false) DATA_DBG_LOG("MMC5983 Get Data TimeOut...\r\n"); App.RDStatus = READDATA_STATUS_DATA_HANDLE; } else if(App.MagRead_EndFlag == true && App.AccRead_EndFlag == true){ App.RDStatus = READDATA_STATUS_DATA_HANDLE; } break;} case READDATA_STATUS_DATA_HANDLE:{ if(App.MagRead_EndFlag == false || App.AccRead_EndFlag == false){ DATA_DBG_LOG("<------------ Sensor Data Upda End ------------> \r\n"); App.RDStatus = READDATA_STATUS_IDLE; App.UpdateOk = false; break; } App.MagRead_EndFlag = false; App.AccRead_EndFlag = false; IMU_Update(0, App.Sensor.acce, App.Sensor.mag, &App.AHRSData.Rad, &App.AHRSData.Deg); App.ConvertedData.Pitch = (int16_t)(App.AHRSData.Deg.pitch * 10); App.ConvertedData.Roll = (int16_t)(App.AHRSData.Deg.roll * 10); App.ConvertedData.Yaw = (int16_t)(App.AHRSData.Deg.yaw * 10); DATA_DBG_LOG("PitchAngle:%06.1f, RollAngle:%06.1f, YawAngle:%06.1f\r\n",App.AHRSData.Deg.pitch, App.AHRSData.Deg.roll, App.AHRSData.Deg.yaw); if(SGCP.MasterCaliOk == true) { SGCP.MasterCaliOk = false; App.CaliFlag = true; App.Para.CaliPara.PitchZero = App.ConvertedData.Pitch; App.Para.CaliPara.RollZero = App.ConvertedData.Roll; App.Para.CaliPara.YawZero = App.ConvertedData.Yaw; // App.Para.CaliPara.PitchZero = 0; // App.Para.CaliPara.RollZero = 0; // App.Para.CaliPara.YawZero = 0; SAVE_APP_PARA((uint32_t *)&App.Para); } if(App.CaliFlag == true && App.ERFlag == false) { int16_t PitchDiff,RollDiff; PitchDiff = App.ConvertedData.Pitch - App.Para.CaliPara.PitchZero; RollDiff = App.ConvertedData.Roll - App.Para.CaliPara.RollZero; if((PitchDiff > ERINTERVAL_VPT) || (RollDiff > ERINTERVAL_VPT)) { //触发紧急上报 App.ERFlag = true; DATA_DBG_LOG("PitchDiff=%04d, PitchDiff=%04d\r\n", PitchDiff,RollDiff); DATA_DBG_LOG("Start emergency reporting!\r\n"); DATA_DBG_LOG("ERInterval: %dMin, ERTime: %dMin\r\n", App.Para.Layout.ERInterval/2, App.Para.Layout.ERTime/2); } } SGCP.DevData.LaserTracing.PitchAngle = App.ConvertedData.Pitch; SGCP.DevData.LaserTracing.RollAngle = App.ConvertedData.Roll; SGCP.DevData.LaserTracing.YawAngle = App.ConvertedData.Yaw; #if (USE_VBAT_AD == 1) SGCP.DevData.LaserTracing.MasterDev.BatLevel = VBAT_Percentage; #else SGCP.DevData.LaserTracing.MasterDev.BatLevel = 0x00; #endif #if (SGCP_SELECT == 1 || SGCP_SELECT == 2) SX1276LoCalcRssiSnr(&SGCP.DevData.LaserTracing.MasterDev.RSSI, &SGCP.DevData.LaserTracing.MasterDev.Nsr);//获取信号强度 #else SGCP.DevData.LaserTracing.MasterDev.RSSI = 0x00; SGCP.DevData.LaserTracing.MasterDev.Nsr = 0x00; #endif memcpy(LocalDataPack, &SGCP.DevData.LaserTracing, sizeof(LocalDataPack)); DATA_DBG_LOG("<------------ Sensor Data Upda End ------------> \r\n"); //App.RDStatus = READDATA_STATUS_UPDAING;//持续工作 App.RDStatus = READDATA_STATUS_IDLE; App.UpdateOk = true; break;} } } static void AppLoopHandler(void) { switch(App.Status) { case APP_STATUS_IDLE:{ break;} case APP_STATUS_SLEEP:{ MAIN_DBG_LOG("Sleep...\r\n\n\n"); FeedDog(); EnterDeepSleep(); FeedDog(); WakeUpInit(); App.Status = APP_STATUS_ON; break;} case APP_STATUS_ON:{ if(App.TD1mSDelayCnt <= 0){ App.TD1mSDelayCnt = 300;//唤醒后待机时间 App.Status = APP_STATUS_ACTION; } break;} case APP_STATUS_OFF:{ LED_OFF(); App.Status = APP_STATUS_SLEEP; MAIN_DBG_LOG("Power Off...\r\n"); break;} case APP_STATUS_ACTION:{ if(SGCP.InStatus != IN_STATUS_IDLE){ break; } else if(SGCP.LoginOk == false && App.LoginFlag == true && SGCP.GWStatus == GW_STATUS_IDLE)//设备注册 { PrintfMess(); App.LoginFlag = false; LPTimer0_OFF();//关闭低功耗定时器 SGCP.GWStatus = GW_STATUS_LOGIN;//注册 App.Status = APP_STATUS_WAIT_LOGIN; } else if(SGCP.TimingAcquisition == true && App.RDStatus == READDATA_STATUS_IDLE)//设备数据获取 { PrintfMess(); SGCP.TimingAcquisition = false; App.RDStatus = READDATA_STATUS_UPDAING; App.Status = APP_STATUS_ACTION; App.TD1mSDelayCnt = 1000; } else if(SGCP.LoginOk == true && App.UploadFlag == true && SGCP.GWStatus == GW_STATUS_IDLE && App.UpdateOk == true) { PrintfMess(); App.UploadFlag = false; LPTimer0_OFF();//关闭低功耗定时器 SGCP.GWStatus = GW_STATUS_UPLOAD_SENSOR;//上传 App.Status = APP_STATUS_WAIT_UPLOAD; } else if(SGCP.LaserOnOff == true && SGCP.LaserTimerMinutes > 0 && SGCP.LaserTimerCount == 0 && SGCP.GWStatus == GW_STATUS_IDLE) { SGCP.LaserOnOff = false; SGCP.GWStatus = GW_STATUS_LASER_STARES; } else if(App.RDStatus == READDATA_STATUS_IDLE && SGCP.GWStatus == GW_STATUS_IDLE && SGCP.InStatus == IN_STATUS_IDLE && SGCP.TimingAcquisition == false && App.TD1mSDelayCnt == 0 && App.ReadData1mSDelayCnt == 0 && SGCP.LaserOnOff == false && App.AttTestMode == false) { //App.Status = APP_STATUS_ACTION; App.Status = APP_STATUS_OFF; } break;} case APP_STATUS_WAIT_LOGIN:{ if(SGCP.LoginMess == true) { if(SGCP.LoginOk == false) { App.Login2Min30SCount++; if(App.Login2Min30SCount >= 3) { PrintfMess(); MAIN_DBG_LOG("Number of registration failures:%d\r\n",App.Login2Min30SCount); MAIN_DBG_LOG("Login RTC Open\r\n"); App.Login2Min30SCount = 0; App.Login30MinCount = 0; App.Login_RTC = true;//启动30分注册定时器 } else { PrintfMess(); App.Login_LPTimer0 = true; LPTimer0_ON((App.Nonce % 1200) + 300);//定时30s+随机2分钟,最小间隙100ms //LPTimer0_ON(100);//定时10s MAIN_DBG_LOG("Number of registration failures:%d\r\n",App.Login2Min30SCount); MAIN_DBG_LOG("Login LPTimer0 Open\r\n"); } } else if(SGCP.LoginOk == true) { App.Login2Min30SCount = 0; App.Login30MinCount = 0; App.Upload45S10SCount = 0; App.UploadFlag = true; App.RDStatus = READDATA_STATUS_UPDAING; } SGCP.LoginMess = false; App.TD1mSDelayCnt = 1000; App.Status = APP_STATUS_ACTION; } break;} case APP_STATUS_WAIT_UPLOAD:{ if(SGCP.UploadMess == true) { if(SGCP.UploadOk == false) { App.Upload45S10SCount++; if(App.Upload45S10SCount >= 3) { PrintfMess(); MAIN_DBG_LOG("Number of failed uploads:%d\r\n",App.Upload45S10SCount); MAIN_DBG_LOG("Resend registration information.\r\n"); App.Upload45S10SCount = 0; SGCP.LoginOk = false; App.LoginFlag = true; } else { PrintfMess(); App.Upload_LPTimer0 = true; LPTimer0_ON((App.Nonce % 100) + 450);//随机延时100~10000ms+45秒后重新发送 //LPTimer0_ON(100);//定时10s MAIN_DBG_LOG("Number of failed uploads:%d\r\n",App.Upload45S10SCount); MAIN_DBG_LOG("Upload LPTimer0 Open\r\n"); } } else if(SGCP.UploadOk == true) { App.Upload45S10SCount = 0; } SGCP.UploadMess = false; App.TD1mSDelayCnt = 1000; App.Status = APP_STATUS_ACTION; } break;} } } static void App1mSRoutine(void) { if(App.TD1mSDelayCnt > 0) App.TD1mSDelayCnt--; if(App.ReadData1mSDelayCnt > 0) App.ReadData1mSDelayCnt--; App.FeedDogDlyCnt++; if(App.AttTestMode == true && App.AttTestCnt > 0) App.AttTestCnt--; } void FeedDogHandler(void) { if(App.FeedDogDlyCnt >= 200) { FeedDog(); App.FeedDogDlyCnt = 0; } } void SystemResetHandler(void) { //系统定时重启 if(App.SysResetTimeCnt > SYSTEM_TIMING_LOGIN) { delay_ms(5); SystemReset(); while(1); } } /** ****************************************************************************** ** \brief Main function of project ** ** \return uint32_t return value, if needed ** ** This sample ** ******************************************************************************/ int32_t main(void) { BspInit(); delay_ms(3000);//上电延时,等待从设备启动 AppInit(); DBG_LOG("\r\n\r\n"); DBG_LOG("****************************************************\r\n"); DBG_LOG("** **\r\n"); DBG_LOG("** LaserTracing **\r\n"); DBG_LOG("** SoftWare V:%d.%d **\r\n", SOFTWARE_VERSION / 10, SOFTWARE_VERSION % 10); DBG_LOG("** HardWare V:%d.%d **\r\n", HARDWARE_VERSION / 10, HARDWARE_VERSION % 10); DBG_LOG("** Compile: %s %s **\r\n", __DATE__, __TIME__); DBG_LOG("** **\r\n"); DBG_LOG("****************************************************\r\n\r\n"); //09 00 01 00 00 00 while (1) { #if(USE_VBAT_AD == 1) ADCLoopHandler(); #endif #if(USE_WDT == 1) FeedDogHandler(); #endif #if(USE_DEBUG == 1) DebugLoopHandler(); #endif Lsm6dslLoopHandler(); MMC5983LoopHandler(); ReadDataLoopHandler(); GwRevLoopHandler(); InRevLoopHandler(); AppLoopHandler(); #if(USE_DEBUG == 1) if(App.AttTestMode == true) { if(App.AttTestCnt == 0) { App.AttTestCnt = 200; SGCP.TimingAcquisition = true; } if(App.UpdateOk == true) { App.UpdateOk = false; DBG_LOG("Pitch:%.1f Roll:%.1f Yaw:%.1f\r\n", App.ConvertedData.Pitch / 10.0, App.ConvertedData.Roll / 10.0, App.ConvertedData.Yaw / 10.0); } } #endif } } /******************************************************************************* * 中断回调函数 ******************************************************************************/ void SysTick_CallBack(void) { App1mSRoutine(); SGCP1mSRoutine(); Debug1mSRoutine(); Lsm6dsl1mSRoutine(); MMC59831mSRoutine(); } void RtcIRQHander(void) { //SGCP.TimingAcquisition = true; //30S更新一次数据 if(SGCP.LoginOk == true) { App.RepeLoginCount++; if(App.RepeLoginCount >= SYSTEM_TIMING_LOGIN){ MAIN_DBG_LOG("24h Repetition Login\r\n"); App.RepeLoginCount = 0; SGCP.LoginOk = false;//24h重复注册 App.Login2Min30SCount = 0; App.Login30MinCount = 0; App.Login_RTC = false;//关闭30分注册定时器 App.Login_LPTimer0 = true; LPTimer0_ON((App.Nonce % 1200) + 300);//定时30s+随机2分钟,最小间隙100ms MAIN_DBG_LOG("Login LPTimer0 Open\r\n"); } App.Coll_N++; if(App.Coll_N >= App.Para.Layout.CollectTime) { App.Coll_N = 0; SGCP.TimingAcquisition = true; //定时更新数据 } if(App.ERFlag == true) { App.ERInterval_N++; App.ERTime_N++; if(App.ERInterval_N >= App.Para.Layout.ERInterval) { App.ERInterval_N = 0; App.UploadFlag = true; } if(App.ERTime_N >= App.Para.Layout.ERTime) { App.ERTime_N = 0; App.ERFlag = false; SGCP.MasterCaliOk = true;//紧急上报时间结束,重新校准参数 } } else{ App.Repor_N++; if(App.Repor_N >= App.Para.Layout.ReportInterval) { App.Repor_N = 0; App.UploadFlag = true; } } } if(App.Login_RTC == true) { App.Login30MinCount++; if(App.Login30MinCount >= ERR_TIMING_LOGIN)//30分钟重置注册错误信息 { PrintfMess(); App.Login30MinCount = 0; App.Login_RTC = false;//关闭30分注册定时器 MAIN_DBG_LOG("Login RTC Close\r\n"); App.Login_LPTimer0 = true; LPTimer0_ON((App.Nonce % 1200) + 300);//定时30s+随机2分钟,最小间隙100ms //LPTimer0_ON(100);//定时10s MAIN_DBG_LOG("Login LPTimer0 Open\r\n"); } } if(SGCP.LaserOnOff == true && SGCP.LaserTimerCount > 0) { SGCP.LaserTimerCount--; } } void LPTimer0IRQHander(void) { if(App.Login_LPTimer0 == true) { App.Login_LPTimer0 = false; App.LoginFlag = true; } if(App.Upload_LPTimer0 == true) { App.Upload_LPTimer0 = false; App.UploadFlag = true; } }