#include "LoraTask.h" #include "main.h" #include "CatOneTask.h" #include "DebugCmd.h" #define UC_OFFLINE_TIME_INTERVAL_MAX (2 * 60 * 60)//离线判断最大时间间隔,单位秒 static rt_sem_t LoraDioIRQ_Sem = RT_NULL; static rt_thread_t LoraIRQ_Thread = RT_NULL; static GateWayPara GateWay; void LoraSend(uint8_t* pucBuff, uint8_t ucLen) { Sx1276LoRaSendBuffer(pucBuff, ucLen); } //Lora接收消息统一放到消息队列,由接收任务处理 int LoraRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen) { uint8_t *sData; if(rLen > 255) return -1; sData = rt_malloc(rLen + 5); sData[0] = rLen; // Debug_Printf("Lora Rev: "); // for(int i = 0; i < rLen; i++) { // Debug_Printf("%02x ", rData[i]); // } // Debug_Printf("\r\n"); memcpy(&sData[1], rData, rLen); rt_mq_send(GateWay->LoraRev_MQ, sData, rLen + 1); rt_free(sData); return 0; } void LoraIRQ_Thread_Entry(void *parameter) { rt_err_t result; static uint16_t LoraErrCnt = 0; Debug_Printf("LoraRev Thread is running!\r\n"); while(1) { if(GateWay->ConfigPara.Lora.OnOff == false) { rt_thread_delay(100); continue; } result = rt_sem_take(LoraDioIRQ_Sem, 1000); if(result == RT_EOK) { IsrSx1276LoRaTxRx(GateWay); LoraErrCnt = 0; } else { LoraErrCnt++; if(LoraErrCnt > LORA_ERR_RESET_DLY_MAX) { //15分钟内没有收到lora数据重启lora模块 LoraErrCnt = 0; Debug_Printf("Lora Reset!\r\n"); Sx1276LoRaInit(LoraRevCallBack); } } } } static void LoRaSendBuffer(uint8_t* pucBuff, uint16_t ucLen) { if(GateWay->ConfigPara.Lora.OnOff == true) Sx1276LoRaSendBuffer(pucBuff, ucLen); } void Lora_Thread_Entry(void *parameter) { rt_err_t result; #ifndef LORA_LOWPOWER bool UnitCommSendFlag = false; uint8_t SendUnitCommIdx = 0; uint16_t UnitCommReadDelayCnt = 0; #endif uint8_t Payload[256]; uint8_t MegData[9]; GateWay = (GateWayPara)parameter; while(GateWay->ConfigPara.Lora.OnOff == false) { rt_thread_delay(100); } LoraDioIRQ_Sem = rt_sem_create("loradioirq_sem", 0, RT_IPC_FLAG_FIFO); if(LoraDioIRQ_Sem == RT_NULL) { Debug_Printf("CatOneIRQ Sem Create Failed!\r\n"); } LoraIRQ_Thread = rt_thread_create("LoraIRQ", LoraIRQ_Thread_Entry, NULL, 512, 3, 20); if (LoraIRQ_Thread != RT_NULL) rt_thread_startup(LoraIRQ_Thread); Sx1276LoRaInit(LoraRevCallBack); Debug_Printf("Lora Thread is running!\r\n"); #ifdef LORA_LOWPOWER while(1) { if(GateWay->ConfigPara.Lora.OnOff == false) { rt_thread_delay(100); continue; } result = rt_mq_recv(GateWay->LoraRev_MQ, Payload, 256, 1000); if(result == RT_EOK) { int ret = GateWay->CommUnitRevCallBack(GateWay, &Payload[1], Payload[0], LoRaSendBuffer); if(ret == 0xff) //注册信息 continue; } else { //离线判断 for(int i = 0; i < COMMUNIT_NUM_MAX; i++) { if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == true) { if(GateWay->ConfigPara.CommUnitArray[i].CommErrCnt < UC_OFFLINE_TIME_INTERVAL_MAX) { GateWay->ConfigPara.CommUnitArray[i].CommErrCnt++; } else if(GateWay->ConfigPara.CommUnitArray[i].CommStatus) { GateWay->ConfigPara.CommUnitArray[i].CommStatus = 0; MegData[0] = 7; MegData[1] = 0; MegData[2] = COMM_UNIT_CMD_READ; memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[i].Mac[0], 6); MegData[9] = GateWay->ConfigPara.CommUnitArray[i].CommStatus; Debug_Printf("The CommUnit is offline.Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n", GateWay->ConfigPara.CommUnitArray[i].Mac[0][0], GateWay->ConfigPara.CommUnitArray[i].Mac[0][1], GateWay->ConfigPara.CommUnitArray[i].Mac[0][2], GateWay->ConfigPara.CommUnitArray[i].Mac[0][3], GateWay->ConfigPara.CommUnitArray[i].Mac[0][4], GateWay->ConfigPara.CommUnitArray[i].Mac[0][5]); CatOneEthSendQueue(MegData, 10); //发送离线消息 } } } } } #else while(1) { if(UnitCommSendFlag == false && UnitCommReadDelayCnt >= GateWay->ConfigPara.CommUnitReadInterval) { if(SendUnitCommIdx < COMMUNIT_NUM_MAX) { if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RegFlag && GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[2] == 0x01) { GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RevNewDataFlag = false; Debug_Printf("Lora Read CommUnit: %02X:%02X:%02X:%02X:%02X:%02X\r\n", GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[1], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[2], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[3], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[4], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[5]); CommUnitCmdSend(GateWay, GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], COMM_UNIT_CMD_READ, NULL, 0, Sx1276LoRaSendBuffer); UnitCommSendFlag = true; } else { SendUnitCommIdx++; continue; } } else { SendUnitCommIdx = 0; UnitCommReadDelayCnt = 0; } } if(UnitCommReadDelayCnt < GateWay->ConfigPara.CommUnitReadInterval) UnitCommReadDelayCnt++; result = rt_mq_recv(GateWay->LoraRev_MQ, Payload, 256, 1000); if(result == RT_EOK) { int ret = GateWay->CommUnitRevCallBack(GateWay, &Payload[1], Payload[0], Sx1276LoRaSendBuffer); if(ret == 0xff) //注册信息 continue; if(UnitCommSendFlag && GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RevNewDataFlag) { UnitCommSendFlag = false; SendUnitCommIdx++; } } else if(UnitCommSendFlag) { //离线判断 GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt++; if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt == 10) { GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt = 0; if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus) { GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus = 0; MegData[0] = 7; MegData[1] = 0; MegData[2] = COMM_UNIT_CMD_READ; memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], 6); MegData[9] = GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus; CatOneEthSendQueue(MegData, 10); //发送离线消息 } } UnitCommSendFlag = false; SendUnitCommIdx++; } } #endif } void LoraTxRxIrqCallback(void) { rt_sem_release(LoraDioIRQ_Sem); } void LoraInit(void) { Sx1276LoRaInit(LoraRevCallBack); }