初始版本

This commit is contained in:
2026-06-22 09:19:00 +08:00
parent 85a1478489
commit 0723faf209
240 changed files with 131805 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
#include "ADS1231.h"
extern float Temperature;
void ADS1231_Open(void)
{
PDWN1_SET();
PDWN2_SET();
PDWN3_SET();
PDWN4_SET();
}
void ADS1231_HighSpeedSet(void)
{
SPEED1_SET();
SPEED2_SET();
SPEED3_SET();
SPEED4_SET();
}
void ADS1231_LowSpeedSet(void)
{
SPEED1_RESET();
SPEED2_RESET();
SPEED3_RESET();
SPEED4_RESET();
}
uint32_t GpioAGetDout(en_pin_t enPin)
{
return *(uint32_t *)((uint32_t)(&M4_PORT->PIDRA)) & (enPin);
}
uint32_t GpioBGetDout(en_pin_t enPin)
{
return *(uint32_t *)((uint32_t)(&M4_PORT->PIDRB)) & (enPin);
}
bool ADS1231_Read(uint32_t *r_data, uint8_t channel) {
uint8_t i;
uint32_t data = 0;
switch(channel) {
case 0:
if(GpioAGetDout(DRDY_DOUT1_PIN) != 0)
return false;
for(i = 0; i < 24; i++) {
SCLK1_SET();
data <<= 0x01;
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK1_RESET();
if(GpioAGetDout(DRDY_DOUT1_PIN) != 0)
data |= 0x01;
}
SCLK1_SET();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK1_RESET();
break;
case 1:
if(GpioAGetDout(DRDY_DOUT2_PIN) != 0)
return false;
for(i = 0; i < 24; i++) {
SCLK2_SET();
data <<= 0x01;
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK2_RESET();
__NOP(); __NOP();
if(GpioAGetDout(DRDY_DOUT2_PIN) != 0)
data |= 0x01;
}
SCLK2_SET();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK2_RESET();
break;
case 2:
if(GpioBGetDout(DRDY_DOUT3_PIN) != 0)
return false;
for(i = 0; i < 24; i++) {
SCLK3_SET();
data <<= 0x01;
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK3_RESET();
if(GpioBGetDout(DRDY_DOUT3_PIN) != 0 )
data |= 0x01;
}
SCLK3_SET();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK3_RESET();
break;
case 3:
if(GpioBGetDout(DRDY_DOUT4_PIN) != 0 )
return false;
for(i = 0; i < 24; i++) {
SCLK4_SET();
data <<= 0x01;
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK4_RESET();
if(GpioBGetDout(DRDY_DOUT4_PIN) != 0 )
data |= 0x01;
}
SCLK4_SET();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
SCLK4_RESET();
break;
default:
return false;
}
if(data <= 0x00ffffff) {
if(data > 0x007fffff)
*r_data = data|0xff000000;
else
*r_data = data;
}
else
return false;
return true;
}
View File
+709
View File
@@ -0,0 +1,709 @@
#include "CatOneTask.h"
#include "Public.h"
#include "DebugCmd.h"
static rt_sem_t CatOneRev_Sem = RT_NULL;
static rt_sem_t CatOneIRQ_Sem = RT_NULL;
static rt_sem_t EthIRQ_Sem = RT_NULL;
static rt_thread_t Cat1Rev_Thread = RT_NULL;
static uint8_t CAT1DispEn = false;
static CatOne_t CatOne;
static char CatOneEthRxBuff[CAT_ONE_REV_LEN_MAX];
static uint16_t CatOneEthRxLen;
static uint8_t CatOneEthTxBuff[CAT_ONE_REV_LEN_MAX];
static uint16_t CatOneEthTxLen;
static uint8_t Payload[CAT_ONE_REV_LEN_MAX];
static char CommUnitSendASCII[CAT_ONE_REV_LEN_MAX * 2];
static uint8_t EthRevTimeOutCnt;
static uint16_t CatSendErrCnt = 0;
#define CAT1_DBG_LOG(...) { if(CAT1DispEn) Debug_Printf(__VA_ARGS__);}
//#define CAT1_DBG_ARRAY(ARRAY, SIZE) { if(CAT1DispEn) {DBG_ARRAY(ARRAY,SIZE)}}
#define CATONE_RESET_DELAY_TIME_MAX (5 *60 * 1000)
const char *CatOneATCmdStr[16] = {
"NULL",
"AT\r\n", //开机检测
"ATE0\r\n", //关回显
"AT+CPIN?\r\n", //识卡
// "AT+CIMI\r\n", //IMEI
"AT+CGSN=1\r\n",
"AT+LCCID\r\n", //读卡号
"AT+CEREG?\r\n", //查询注册状态
"AT+CGPADDR=1\r\n", //查询IP地址
"AT+CSQ\r\n", //查询信号强度
"AT+LDNSGIP=gxjt.cui635.cn\r\n",
"AT+LBS=0\r\n", //获取基站定位信息
"AT+LIPOPEN=", //设置TCP服务器地址和端口,AT+LIPOPEN="TCP","114.55.52.96",6803
"AT+LIPSEND=", //发送数据, AT+LIPSEND=0,1,20,"31313131313131323232323232"
"AT+LIPCLOSE=0\r\n",//断开连接
"AT+LBSPARA=http://locator-aep.xiot.senthink.com:80/locator/v0.1/locate,B84E427D95B1DF4A3F49B18DDF714C72\r\n",
"AT+CCLK?\r\n", //获取时间
};
void Cat1DBGOnOff(bool OnOff)
{
CAT1DispEn = OnOff;
if(OnOff)
rt_kprintf("\r\nCat1 Display Enable!\r\n\r\n");
else
rt_kprintf("\r\nCat1 Display Disable!\r\n\r\n");
}
const CatOneATCMD_m CatOneModeSetCmdArray[] = {
CAT_ONE_AT_NULL,
CAT_ONE_AT,
CAT_ONE_ATE0,
//CAT_ONE_LBSPARA,
CAT_ONE_LCCID,
CAT_ONE_IMEI,
CAT_ONE_CPIN,
CAT_ONE_CEREG,
CAT_ONE_CSQ,
//CAT_ONE_LDNSGIP,
//CAT_ONE_LBS,
CAT_ONE_CCLK,
CAT_ONE_AT_CMD_END
};
//CatOneRetStatus_m CatOneSend(uint8_t *sData, uint16_t sLen)
//{
// rt_err_t result;
//
// if(CatOne.Status != CAT_ONE_IDEL && CatOne.Status != CAT_ONE_WAIT_SEND)
// return CAT_ONE_RET_ERR;
//
// //CatOne.Status = CAT_ONE_RESET;
// result = rt_mq_send(CatOneRev_MQ, sData, sLen);
// if(result != RT_EOK) {
// CAT1_DBG_LOG("CatOne MQ Send ERR...\r\n");
// return CAT_ONE_RET_ERR;
// }
// CAT1_DBG_LOG("CatOne Send Message: \r\n", sData);
// return CAT_ONE_RET_OK;
//}
void CatOneStop(void)
{
CatOne.Status = CAT_ONE_OFF;
}
void CatOneGetLocationInfo(int *Longitude, int *Latitude)
{
if(CatOne.LBSFlag) {
*Longitude = CatOne.Longitude;
*Latitude = CatOne.Latitude;
}
else {
*Longitude = 0;
*Latitude = 0;
}
}
void CatOneGetIMEIAndSIM(char *Imei, char *Sim)
{
memcpy(Imei, CatOne.IMEI, 15);
memcpy(Sim, CatOne.SIM, 20);
}
//返回true-busy, false-Idle
bool CatOneGetStatus(void)
{
if(CatOne.Status == CAT_ONE_IDEL)
return false;
return true;
}
void CatOneReset(void)
{
CatOne.Status = CAT_ONE_RESET;
}
void CatTimeSync(char *Data)
{
struct tm sTimet;
time_t sTime;
char *p;
p = strchr(Data, '\"');
if(p == NULL)
return;
int ret = sscanf(p, "\"%d/%d/%d,%d:%d:%d+",
&sTimet.tm_year, &sTimet.tm_mon, &sTimet.tm_mday,
&sTimet.tm_hour, &sTimet.tm_min, & sTimet.tm_sec);
if(ret != 6) {
int ret = sscanf(p, "\"%d/%d/%d,%d:%d:%d-",
&sTimet.tm_year, &sTimet.tm_mon, &sTimet.tm_mday,
&sTimet.tm_hour, &sTimet.tm_min, & sTimet.tm_sec);
if(ret != 6)
return;
}
sTimet.tm_isdst = 0;
if(sTimet.tm_year < 23)
return;
sTimet.tm_year += 100;
if(sTimet.tm_mon > 12 && sTimet.tm_mon == 0)
return;
sTimet.tm_mon--;
sTime = mktime(&sTimet);
TimeSync(sTime);
CAT1_DBG_LOG("Set Time:");
TimeShow(TimeTs());
}
void CatOneAtCmdAnalyze(char *RxBuff)
{
char *p;
int ret;
CatOne.ATCmdRet = CAT_ONE_RET_OK;
CAT1_DBG_LOG(RxBuff);
switch(CatOne.AtCmd) {
case CAT_ONE_AT:
case CAT_ONE_ATE0:
case CAT_ONE_LIPSEND:
case CAT_ONE_LDNSGIP:
case CAT_ONE_LBSPARA:
if(strstr(RxBuff, "OK") == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
break;
case CAT_ONE_IMEI:
if(strstr(RxBuff, "OK") == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
p = strstr(RxBuff, "+CGSN");
if(p == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
p = strchr(p, '"');
if(p != NULL) {
memcpy(CatOne.IMEI, p+1, 15);
}
else {
memset(CatOne.IMEI, 0, 15);
}
// ret = sscanf(p, "+CGSN: \"%s\"\r\n", CatOne.IMEI);
// if(ret != 1) {
// memset(CatOne.IMEI, 0, 15);
// }
CatOne.IMEI[15] = 0;
break;
case CAT_ONE_CCLK:
if(strstr(RxBuff, "+CCLK") != NULL) {
CatTimeSync(RxBuff);
}
break;
case CAT_ONE_LCCID:
if(strstr(RxBuff, "OK") == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
p = strstr(RxBuff, "+LCCID");
if(p == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
memset(CatOne.SIM, 0, 32);
ret = sscanf(p, "+LCCID: %s\r\n", CatOne.SIM);
if(ret != 1) {
memset(CatOne.SIM, 0, 32);
}
break;
case CAT_ONE_LBS:
p = strstr(RxBuff, "+LBS");
if(p != NULL) {
double Longitude, Latitude;
int ret = sscanf(p, "+LBS: %lf,%lf\r\n", &Longitude, &Latitude);
if(ret == 2) {
CatOne.LBSFlag = true;
CatOne.Longitude = Longitude * 100000;
CatOne.Latitude = Latitude * 100000;
}
}
break;
case CAT_ONE_LIPOPEN:
if(strstr(RxBuff, "OK") != NULL) {
CatOne.Status = CatOne.NextStatus;
CatOne.CatOne1mSDelayCnt = 10 * 1000;
return;
}
else {
if(strstr(RxBuff, "LIPOPEN: 0,1") != NULL) {
CAT1_DBG_LOG("Cat1 successfully to connect to the server.\r\n\r\n");
CatOne.TcpConnFlag = true;
CatOne.Status = CatOne.NextStatus;
rt_sem_release(CatOneRev_Sem);
}
else if(strstr(RxBuff, "LIPOPEN: 0,0") != NULL) {
CAT1_DBG_LOG("Cat1 failed to connect to the server.\r\n\r\n");
CatOne.TcpConnFlag = false;
CatOne.Status = CAT_ONE_OFF;
}
return;
}
case CAT_ONE_CPIN:
if(strstr(RxBuff, "READY") == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
break;
case CAT_ONE_CEREG:
if(strstr(RxBuff, "CEREG: 0,1") == NULL) {
CatOne.CatOne1mSDelayCnt = 3000;
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
break;
case CAT_ONE_CGPADDR:
if(strstr(RxBuff, "+CGPADDR") == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
break;
case CAT_ONE_CSQ:
if(strstr(RxBuff, "+CSQ") == NULL) {
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
break;
case CAT_ONE_LTPCLOSE:
if(strstr(RxBuff, "CLOSE OK") != NULL) {
break;
}
else if(strstr(RxBuff, "ERROR") != NULL) {
break;
}
else if(strstr(RxBuff, "OK") != NULL){
break;
}
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
break;
case CAT_ONE_AT_NULL:
p = strstr(RxBuff, "+LIPURC");
if(p != NULL) {
char rData[120];
uint8_t hData[60];
int rLen, hLen, ret;
if(strstr(p, "+LIPURC: 0,0") != NULL) {
CAT1_DBG_LOG("TCP connection disconnected.\r\n\r\n");
CatOne.TcpConnFlag = false;
CatOne.Status = CAT_ONE_OFF;
return;
}
ret = sscanf(p, "+LIPURC: 0,1,%d,%s\r\n", &rLen, rData);
if(ret == 2) {
if(rLen < 24)
return;
memset(hData, 0x00, 60);
hLen = AsciiToHex(rData, hData, rLen);
CatSendErrCnt = 0;
CatOne.GateWay->SvrRevCallBack(CatOne.GateWay, hData, hLen);
}
else {
return;
}
//CatOne.Status = CAT_ONE_CLOSE_TCP;
rt_sem_release(CatOneRev_Sem);
return;
}
default:
CatOne.ATCmdRet = CAT_ONE_RET_ERR;
}
if(CatOne.ATCmdRet == CAT_ONE_RET_OK) {
CatOne.Status = CatOne.NextStatus;
if(CatOne.AtCmd == CAT_ONE_LIPSEND)
CatOne.CatOne1mSDelayCnt = 5 * 1000;
else
CatOne.CatOne1mSDelayCnt = 10;
CatOne.AtCmd = CAT_ONE_AT_NULL;
rt_sem_release(CatOneRev_Sem);
}
}
void CatOneAtCmdSend(CatOneATCMD_m Cmd, uint32_t Dly, CatOneStatus_m NextStatus)
{
CatOne.AtCmd = Cmd;
if(CatOne.AtCmd == CAT_ONE_LIPSEND) {
HexToAscii(CatOneEthTxBuff, CommUnitSendASCII, CatOneEthTxLen);
sprintf(CatOne.CatOneSendBuff,"AT+LIPSEND=0,1,%d,\"%s\"\r\n",CatOneEthTxLen * 2, CommUnitSendASCII);
}
else if(CatOne.AtCmd == CAT_ONE_LIPOPEN) {
sprintf(CatOne.CatOneSendBuff,"AT+LIPOPEN=\"TCP\",\"%d.%d.%d.%d\",%d\r\n",
CatOne.GateWay->ConfigPara.SvrAddr[0],
CatOne.GateWay->ConfigPara.SvrAddr[1],
CatOne.GateWay->ConfigPara.SvrAddr[2],
CatOne.GateWay->ConfigPara.SvrAddr[3],
CatOne.GateWay->ConfigPara.SvrPort);
}
else {
strcpy(CatOne.CatOneSendBuff, CatOneATCmdStr[CatOne.AtCmd]);
}
CAT1_DBG_LOG(CatOne.CatOneSendBuff);
EthRevTimeOutCnt = 0;
EthOrCat1UartSend((uint8_t *)CatOne.CatOneSendBuff, strlen(CatOne.CatOneSendBuff));
CatOne.CatOne1mSDelayCnt = Dly;
CatOne.Status = CAT_ONE_WAIT_REV;
CatOne.NextStatus = NextStatus;
}
int GateWayRegister(uint8_t *TxBuff)
{
uint8_t UnitCommCnt = 0;
uint8_t *p = &TxBuff[2];
uint8_t len = 1;
if(CatOne.GateWay->ConfigPara.Rs485Ch1.CommUnitEnable && CatOne.GateWay->ConfigPara.Rs485Ch1.Enable) {
UnitCommCnt++;
memcpy(&p[len], CatOne.GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac, 6);
len += 6;
}
if(CatOne.GateWay->ConfigPara.Rs485Ch2.CommUnitEnable && CatOne.GateWay->ConfigPara.Rs485Ch2.Enable) {
UnitCommCnt++;
memcpy(&p[len], CatOne.GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac, 6);
len += 6;
}
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(CatOne.GateWay->ConfigPara.CommUnitArray[i].RegFlag) {
memcpy(&p[len], CatOne.GateWay->ConfigPara.CommUnitArray[i].Mac, 6);
len += 6;
UnitCommCnt++;
}
}
TxBuff[0] = len;
TxBuff[1] = NET_COMM_CMD_REG;
TxBuff[2] = UnitCommCnt;
return len + 2;
}
void CatOneLoopHandler(void)
{
static rt_err_t result;
uint16_t ret;
switch(CatOne.Status){
case CAT_ONE_IDEL:
rt_thread_delay(1);
if(CatOne.ResetDelayCnt > 0) {
CatOne.ResetDelayCnt--;
}
else {
CatOne.Status = CAT_ONE_RESET;
}
break;
case CAT_ONE_WAIT_REV:
result = rt_sem_take(CatOneRev_Sem, CatOne.CatOne1mSDelayCnt);
if(result != RT_EOK) {
if(CatOne.AtCmdResendCnt > 0) {
CatOne.AtCmdResendCnt--;
CatOneAtCmdSend(CatOne.AtCmd, 2000, CatOne.NextStatus);
CAT1_DBG_LOG("Cat1 Ret TimeOut, ReSend(%d)...\r\n", CatOne.AtCmdResendCnt);
}
else { //3次错误,关机
CAT1_DBG_LOG("Cat1 error, Close!\r\n");
if(CatOne.AtCmd == CAT_ONE_LIPSEND)
CatOne.Status = CAT_ONE_CLOSE_TCP;
else
CatOne.Status = CAT_ONE_OFF;
}
}
break;
case CAT_ONE_INIT:
CatOne.AtCmdIdx++;
if(CatOneModeSetCmdArray[CatOne.AtCmdIdx] != CAT_ONE_AT_CMD_END) {
if(CatOneModeSetCmdArray[CatOne.AtCmdIdx] == CAT_ONE_CEREG)
CatOne.AtCmdResendCnt = 30;
else
CatOne.AtCmdResendCnt = 3;
CatOneAtCmdSend(CatOneModeSetCmdArray[CatOne.AtCmdIdx], 1000, CAT_ONE_INIT);
}
else {
CatOne.Status = CAT_ONE_TCP_CONN;
CatOne.CatOne1mSDelayCnt = 0;
CatOne.AtCmdIdx = 0;
CatOne.AtCmd = CAT_ONE_AT_NULL;
}
break;
case CAT_ONE_TCP_CONN:
CatOneAtCmdSend(CAT_ONE_LIPOPEN, 2000, CAT_ONE_WAIT_CONN);
break;
case CAT_ONE_WAIT_CONN:
if(CatOne.TcpConnFlag) {
if(CatOne.GateWay->SvrRegFlag == false)
CatOne.Status = CAT_ONE_REG_SVR;
else
CatOne.Status = CAT_ONE_WAIT_SEND;
}
break;
case CAT_ONE_REG_SVR: //注册服务器
ret = GateWayRegister(CatOneEthTxBuff);
rt_mq_send(CatOne.GateWay->NetSendData_MQ, CatOneEthTxBuff, ret);
CatOne.Status = CAT_ONE_WAIT_SEND;
break;
case CAT_ONE_WAIT_SEND:
result = rt_mq_recv(CatOne.GateWay->NetSendData_MQ, Payload, CAT_ONE_REV_LEN_MAX, 1000);
if(result == RT_EOK) {
CatOneEthTxLen = NetCommOrgData(CatOne.GateWay, Payload, CatOneEthTxBuff);
CatOne.Status = CAT_ONE_SEND_DATA;
}
else {
if(CatOne.Status == CAT_ONE_RESET || CatOne.Status == CAT_ONE_OFF) //外部命令执行,状态改变
return;
if(!CatOne.TcpConnFlag) {
CatOne.Status = CAT_ONE_OFF;
}
else {
CatSendErrCnt++;
if(CatSendErrCnt > LORA_CAT_ERR_RESET_DLY_MAX + 10) {
CatOne.Status = CAT_ONE_RESET;
CAT1_DBG_LOG("Cat1 has no data for a long time, Reset!\r\n");
CatSendErrCnt = 0;
break;
}
CatOne.Status = CAT_ONE_WAIT_SEND;
}
}
break;
case CAT_ONE_SEND_DATA:
CatOne.AtCmdResendCnt = 1;
CatOneAtCmdSend(CAT_ONE_LIPSEND, 5000, CAT_ONE_REV_DATA);
break;
case CAT_ONE_REV_DATA:
result = rt_sem_take(CatOneRev_Sem, CatOne.CatOne1mSDelayCnt);
if(result != RT_EOK) {
if(CatOne.TcpConnFlag == false) {
CAT1_DBG_LOG("Cat1 Rec Server Data Timeout!\r\n");
break;
}
}
if(CatOne.GateWay->SvrRegFlag == false) //设备没注册,关闭4G,等待下一次重新注册
CatOne.Status = CAT_ONE_OFF;
else
CatOne.Status = CAT_ONE_WAIT_SEND;
break;
case CAT_ONE_CLOSE_TCP:
CatOne.AtCmdResendCnt = 1;
CatOneAtCmdSend(CAT_ONE_LTPCLOSE, 1000, CAT_ONE_OFF);
break;
case CAT_ONE_OFF:
//CAT1_POW_OFF();
CAT1_RESET_SET();
CAT1_PWR_KEY_CLR();
rt_thread_delay(3000);
CAT1_PWR_KEY_SET();
CatSendErrCnt = 0;
CAT1_DBG_LOG("Cat1 Power Off!\r\n");
CatOne.Status = CAT_ONE_IDEL;
CatOne.ResetDelayCnt = CATONE_RESET_DELAY_TIME_MAX;
break;
case CAT_ONE_RESET:
CatSendErrCnt = 0;
CAT1_DBG_LOG("Cat1 Reset!\r\n");
CAT1_RESET_CLR();
CAT1_PWR_KEY_SET();
//CAT1_POW_ON();
rt_thread_delay(50);
CAT1_RESET_SET();
CAT1_PWR_KEY_CLR();
rt_thread_delay(1000);
CAT1_PWR_KEY_SET();
CatOne.Status = CAT_ONE_INIT;
CatOne.AtCmdIdx = 0;
rt_thread_delay(1000);
break;
}
}
void EthLoopHandler(void)
{
rt_err_t result;
if(CatOne.GateWay->SvrRegFlag == false) {
if(CatOne.RegisterDelayCnt == 0) {
CatOne.RegisterDelayCnt = REGISTER_INTERVAL_MAX * 10;
uint8_t ret = GateWayRegister(CatOneEthTxBuff);
rt_mq_send(CatOne.GateWay->NetSendData_MQ, CatOneEthTxBuff, ret);
}
else {
CatOne.RegisterDelayCnt--;
}
}
result = rt_mq_recv(CatOne.GateWay->NetSendData_MQ, Payload, CAT_ONE_REV_LEN_MAX, 100);
if(result == RT_EOK) {
CatOneEthTxLen = NetCommOrgData(CatOne.GateWay, Payload, CatOneEthTxBuff);
HexToAscii(CatOneEthTxBuff, CommUnitSendASCII, CatOneEthTxLen);
EthRevTimeOutCnt = 0;
EthOrCat1UartSend((uint8_t *)CommUnitSendASCII, CatOneEthTxLen * 2);
CommUnitSendASCII[CatOneEthTxLen * 2] = 0;
//Debug_Printf("%s\r\n",CommUnitSendASCII);
}
}
bool CatOneEthSendQueue(uint8_t *sData, uint16_t sLen)
{
if(CatOne.GateWay->SvrRegFlag == false)
return false;
rt_mq_send(CatOne.GateWay->NetSendData_MQ, sData, sLen);
return true;
}
static void CatOneInit(GateWayPara GateWay)
{
memset(&CatOne, 0x00, sizeof(CatOne_t));
CatOne.Status = CAT_ONE_RESET;
CatOne.GateWay = GateWay;
CatOne.CatOneRevCallBack = GateWay->SvrRevCallBack;
}
void CatOneEthRev_Thread_Entry(void *parameter)
{
rt_err_t result;
char RxBuffTemp[CAT_ONE_REV_LEN_MAX];
uint8_t HexData[CAT_ONE_REV_LEN_MAX / 2];
GateWayPara GateWay = (GateWayPara)parameter;
rt_kprintf("CatOneTthRev Thread is running!\r\n");
while(1) {
if(GateWay->ConfigPara.Comm == CATONE_COMM) {
result = rt_sem_take(CatOneIRQ_Sem, 500);
if(result == RT_EOK) {
memcpy(RxBuffTemp, CatOneEthRxBuff, CatOneEthRxLen);
RxBuffTemp[CatOneEthRxLen] = 0;
CatOneAtCmdAnalyze(RxBuffTemp);
memset(CatOneEthRxBuff, 0x00, CAT_ONE_REV_LEN_MAX);
CatOneEthRxLen = 0;
}
//CatOneEthRxLen = 0;
}
else if(GateWay->ConfigPara.Comm == ETH_COMM) {
result = rt_sem_take(EthIRQ_Sem, 500);
if(result == RT_EOK) {
memcpy(RxBuffTemp, CatOneEthRxBuff, CatOneEthRxLen);
memset(HexData, 0x00, CatOneEthRxLen / 2);
uint8_t ret = AsciiToHex(RxBuffTemp, HexData, CatOneEthRxLen);
if(ret > 0)
GateWay->SvrRevCallBack(GateWay, HexData, ret);
memset(CatOneEthRxBuff, 0x00, CAT_ONE_REV_LEN_MAX);
CatOneEthRxLen = 0;
}
//CatOneEthRxLen = 0;
}
}
}
void CatOne_Eth_Thread_Entry(void *parameter)
{
GateWayPara GateWay = (GateWayPara)parameter;
CatOneRev_Sem = rt_sem_create("cat1r_sem", 0, RT_IPC_FLAG_FIFO);
if(CatOneRev_Sem == RT_NULL) {
rt_kprintf("CatOne Sem Create Failed!\r\n");
}
EthIRQ_Sem = rt_sem_create("eth_sem", 0, RT_IPC_FLAG_FIFO);
if(EthIRQ_Sem == RT_NULL) {
rt_kprintf("Eth Sem Create Failed!\r\n");
}
CatOneIRQ_Sem = rt_sem_create("cat1_sem", 0, RT_IPC_FLAG_FIFO);
if(CatOneIRQ_Sem == RT_NULL) {
rt_kprintf("CatOneIRQ Sem Create Failed!\r\n");
}
CatOneInit(GateWay);
ETH_RESET_CLR();
rt_thread_delay(10);
ETH_RESET_SET();
Cat1Rev_Thread = rt_thread_create("Cat1Rev", CatOneEthRev_Thread_Entry, parameter, 3000, 3, 20);
if (Cat1Rev_Thread != RT_NULL) {
rt_thread_startup(Cat1Rev_Thread);
}
else {
rt_kprintf("CatOneRev Thread Create Failed! Exit...\r\n");
return;
}
rt_kprintf("CatOne Thread is running\r\n");
while(1) {
//rt_mutex_take(GateWay->UartRevMutex, RT_WAITING_FOREVER);
if(GateWay->ConfigPara.Comm == CATONE_COMM)
CatOneLoopHandler();
else if(GateWay->ConfigPara.Comm == ETH_COMM)
EthLoopHandler();
else
rt_thread_delay(1);
//rt_mutex_release(GateWay->UartRevMutex);
}
}
void EthOrCat1RxIrqCallback(uint8_t rData)
{
if(EthRevTimeOutCnt == 0)
CatOneEthRxLen = 0;
if(CatOneEthRxLen < CAT_ONE_REV_LEN_MAX) {
CatOneEthRxBuff[CatOneEthRxLen++] = rData;
}
EthRevTimeOutCnt = 3;
}
void EthRxOverhandler(void)
{
if(EthRevTimeOutCnt > 0)
EthRevTimeOutCnt--;
if(CatOneEthRxLen > 5 && EthRevTimeOutCnt == 0) {
EthRevTimeOutCnt = 20;
if(CatOne.GateWay->ConfigPara.Comm == CATONE_COMM)
rt_sem_release(CatOneIRQ_Sem);
else
rt_sem_release(EthIRQ_Sem);
}
}
void CatReadImeiOrSim(char *Imei, char *Sim)
{
if(Imei != NULL) {
memcpy(Imei, CatOne.IMEI, 15);
Imei[15] = 0x00;
}
if(Sim != NULL) {
memcpy(Sim, CatOne.SIM, 20);
Sim[20] = 0x00;
}
}
File diff suppressed because it is too large Load Diff
+87
View File
@@ -0,0 +1,87 @@
#include "encryption.h"
//从机加密表
const unsigned char EPT_Table[32][6] = {
{1, 6, 4, 2, 3, 5}, {2, 4, 6, 3, 5, 1}, {3, 5, 6, 2, 1, 4}, {5, 3, 2, 1, 4, 6},
{4, 2, 3, 1, 5, 6}, {6, 3, 5, 1, 4, 2}, {3, 5, 2, 6, 4, 1}, {2, 5, 4, 3, 1, 6},
{2, 4, 1, 5, 3, 6}, {4, 6, 1, 3, 2, 5}, {4, 2, 1, 5, 6, 3}, {3, 2, 6, 5, 1, 4},
{2, 6, 5, 1, 4, 3}, {6, 4, 3, 1, 2, 5}, {1, 6, 3, 2, 4, 5}, {5, 3, 4, 6, 2, 1},
{5, 3, 1, 2, 6, 4}, {1, 4, 2, 6, 5, 3}, {3, 5, 2, 1, 4, 6}, {6, 1, 4, 2, 3, 5},
{4, 1, 2, 5, 3, 6}, {4, 2, 6, 3, 5, 1}, {2, 6, 1, 4, 3, 5}, {4, 3, 1, 5, 6, 2},
{5, 1, 2, 4, 6, 3}, {6, 5, 1, 3, 4, 2}, {2, 1, 6, 3, 5, 4}, {1, 5, 6, 3, 4, 2},
{3, 6, 5, 4, 2, 1}, {1, 2, 6, 3, 5, 4}, {4, 6, 5, 3, 2, 1}, {5, 3, 4, 2, 6, 1}
};
//从机解密表:
const unsigned char DPT_Table[32][5] ={
{1, 4, 2, 3, 5}, {2, 4, 3, 5, 1}, {3, 5, 2, 1, 4}, {5, 3, 2, 1, 4},
{4, 2, 3, 1, 5}, {3, 5, 1, 4, 2}, {3, 5, 2, 4, 1}, {2, 5, 4, 3, 1},
{2, 4, 1, 5, 3}, {4, 1, 3, 2, 5}, {4, 2, 1, 5, 3}, {3, 2, 5, 1, 4},
{2, 5, 1, 4, 3}, {4, 3, 1, 2, 5}, {1, 3, 2, 4, 5}, {5, 3, 4, 2, 1},
{5, 3, 1, 2, 4}, {1, 4, 2, 5, 3}, {3, 2, 1, 4, 5}, {1, 4, 5, 2, 3},
{4, 1, 2, 5, 3}, {4, 2, 3, 5, 1}, {2, 1, 4, 3, 5}, {4, 3, 1, 5, 2},
{5, 1, 2, 4, 3}, {5, 1, 3, 4, 2}, {2, 1, 3, 5, 4}, {1, 5, 3, 4, 2},
{3, 5, 4, 2, 1}, {1, 2, 3, 5, 4}, {4, 5, 3, 2, 1}, {5, 3, 4, 2, 1}
};
//数据位加密表:
const unsigned char EPT_D[32] = {
0x23, 0x4c, 0x92, 0x38, 0x52, 0xa4, 0x9a, 0x61,
0x86, 0xc8, 0x70, 0x16, 0x32, 0x58, 0x62, 0x83,
0xa5, 0x16, 0x1c, 0x49, 0x48, 0xc1, 0x8c, 0x91,
0xd0, 0x2c, 0x49, 0x42, 0xc1, 0x8c, 0x98, 0xd0
};
/****************************************************************/
/* 加密函数 */
/* */
/*函数入口: *data,未加密的普通协议数据 */
/* */
/*函数出口: *EPT_data,生成的加密协议 */
/****************************************************************/
void Encrypt_Code(unsigned char *data, unsigned char *EPT_data) {
unsigned char Edata[6];
unsigned char i = 0;
unsigned char check;
unsigned char ept_byte;
check = (data[0]+data[1]+data[2]+data[3]+data[4]+data[5]) % 0xff;
ept_byte = check % 32;
for (i = 0; i < 6; i++) {
Edata[i] = ((~(data[i] & EPT_D[ept_byte])) & EPT_D[ept_byte]) | (data[i] & (~EPT_D[ept_byte]));
}
for (i = 0; i < 6; i++) {
EPT_data[i] = Edata[EPT_Table[ept_byte][i]-1];
}
EPT_data[6] = ((~(check & 0xaa)) & 0xaa) | (check & 0x55);
}
/****************************************************************/
/* 解密函数 */
/* */
/*函数入口: *EPT_data,需要解密的加密协议 */
/* */
/*函数出口: *DPT_data,生成的普通协议 */
/****************************************************************/
void Decrypt_Code(unsigned char *EPT_data,unsigned char *DPT_data) {
unsigned char data[5];
unsigned char i = 0;
unsigned char check;
unsigned char ept_byte;
check = ((~(EPT_data[5]&0xaa))&0xaa)|(EPT_data[5]&0x55);
ept_byte = check % 32;
for(i=0;i<5;i++) {
data[i] = ((~(EPT_data[i]&EPT_D[ept_byte]))&EPT_D[ept_byte])|(EPT_data[i]&(~EPT_D[ept_byte]));
}
for(i=0;i<5;i++) {
DPT_data[DPT_Table[ept_byte][i]-1] = data[i];
}
DPT_data[5] = check;
}
+188
View File
@@ -0,0 +1,188 @@
#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;
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;
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;
GateWayPara GateWay;
static uint16_t LoraErrCnt = 0;
GateWay = (GateWayPara)parameter;
Debug_Printf("LoraRev Thread is running\r\n");
while(1) {
result = rt_sem_take(LoraDioIRQ_Sem, 1000);
if(result == RT_EOK) {
IsrSx1276LoRaTxRx(GateWay);
LoraErrCnt = 0;
}
else {
LoraErrCnt++;
if(LoraErrCnt > LORA_CAT_ERR_RESET_DLY_MAX) { //15分钟内没有收到lora数据重启lora模块
LoraErrCnt = 0;
Debug_Printf("Lora Reset\r\n");
Sx1276LoRaInit(LoraRevCallBack);
}
}
}
}
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
GateWayPara GateWay;
uint8_t Payload[256];
uint8_t MegData[9];
GateWay = (GateWayPara)parameter;
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, GateWay, 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) {
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;
}
else { //离线判断
for(int i = 0; i < COMMUNIT_MUM_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] = COMM_UNIT_CMD_READ;
memcpy(&MegData[2], GateWay->ConfigPara.CommUnitArray[i].Mac, 6);
MegData[8] = 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],
GateWay->ConfigPara.CommUnitArray[i].Mac[1],
GateWay->ConfigPara.CommUnitArray[i].Mac[2],
GateWay->ConfigPara.CommUnitArray[i].Mac[3],
GateWay->ConfigPara.CommUnitArray[i].Mac[4],
GateWay->ConfigPara.CommUnitArray[i].Mac[5]);
CatOneEthSendQueue(MegData, 9); //发送离线消息
}
}
}
}
}
#else
while(1) {
if(UnitCommSendFlag == false && UnitCommReadDelayCnt >= GateWay->ConfigPara.CommUnitReadInterval) {
if(SendUnitCommIdx < COMMUNIT_MUM_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, 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] = COMM_UNIT_CMD_READ;
memcpy(&MegData[2], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac, 6);
MegData[8] = GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus;
CatOneEthSendQueue(MegData, 9); //发送离线消息
}
}
UnitCommSendFlag = false;
SendUnitCommIdx++;
}
}
#endif
}
void LoraTxRxIrqCallback(void)
{
rt_sem_release(LoraDioIRQ_Sem);
}
void LoraInit(void)
{
Sx1276LoRaInit(LoraRevCallBack);
}
+905
View File
@@ -0,0 +1,905 @@
#include "main.h"
#include "Public.h"
#include "RS485Task.h"
#include "LoraTask.h"
#include "spiflash.h"
#include "CatOneTask.h"
#include <stdlib.h>
//传感器对应的数据长度
const uint8_t SensorTypeDataLen[] = {
0, //0x0000-保留
26, //0x0001-应力场检测单元
10, //0x0002-渗透压检测单元
14, //0x0003-弹性波导检测单元
10, //0x0004-介电质普检测单元
6, //0x0005-微振动
6, //0x0006-三维连续变形检测单元
0, //0x0007-保留
36, //0x0008-应力场(地磁)检测单元
16, //0x0009-渗透压(地磁)检测单元
20, //0x000A-弹性波导(地磁)检测单元
16, //0x000B-介电质普(地磁)检测单元
12, //0x000C-三维连续变形(地磁)检测单元
14, //0x000D-二维应力场检测单元
24, //0x000E-裂缝检测单元
0, //0x000F-6维力敏
8, //0x0010-姿态检测单元
4, //0x0011-激光位移检测单元
24, //0x0012-裂缝检测单元别名
};
/*****************************************************************************************
* 函数名称: CRC_Modbus
* 功能描述: CRC16计算函数
* 参 数: wBase, 多项式
Para,校验数据入口
Data, 校验数据长度入口
* 返 回 值: crc16校验值
*****************************************************************************************/
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length)
{
uint16_t crc = 0xffff;
uint16_t index,i;
for(index = 0 ; index < length;index++) {
crc ^= para[index];
for(i = 0; i < 8; i++) {
if(crc & 1) {
crc >>= 1;
crc ^= wBase;
}
else
crc >>= 1;
}
}
return crc;
}
/*****************************************************************************************
* 函数名称: HexToAscii
* 功能描述: HEX转换为ASCII字符串函数
* 参 数: HexData, 16进制数据入口
ASCData,转换后的ASCII数据
sLen, 需要转的16进制数据长度
* 返 回 值: 无
*****************************************************************************************/
void HexToAscii(uint8_t *HexData, char *ASCData, uint8_t sLen)
{
uint8_t temp;
for(int i = 0; i < sLen; i++) {
temp = (HexData[i] >> 4) & 0x0f;
if(temp < 10)
temp += '0';
else
temp = (temp - 10) + 'A';
ASCData[i * 2] = temp;
temp = HexData[i] & 0x0f;
if(temp < 10)
temp += '0';
else
temp = (temp - 10) + 'A';
ASCData[i * 2 + 1] = temp;
}
ASCData[sLen * 2] = 0;
}
/*****************************************************************************************
* 函数名称: AsciiToHex
* 功能描述: AscII字符串转换为16进制数组
* 参 数: ASCData, AscII字符串入口
HexData,转换后的数据
sLen, 需要转的字符串长度
* 返 回 值: 无
*****************************************************************************************/
uint8_t AsciiToHex(char *ASCData, uint8_t *HexData, uint8_t sLen)
{
char chr;
uint8_t HexLen = 0;
if(sLen % 2 == 1)
return 0;
for(int i = 0; i < sLen; i++) {
chr = ASCData[i];
if(chr >= '0' && chr <= '9') {
HexData[HexLen] |= chr - '0';
}
else if(chr >= 'A' && chr <= 'F') {
HexData[HexLen] |= chr - 'A' + 0x0A;
}
else if(chr >= 'a' && chr <= 'f') {
HexData[HexLen] |= chr - 'a' + 0x0A;
}
if(i % 2 == 0) {
HexData[HexLen] <<= 4;
}
else {
HexLen++;
}
}
return HexLen;
}
/*****************************************************************************************
* 函数名称: ReadHistoryData
* 功能描述: 读取历史数据
* 参 数: rData,输入数据
rLen, 输入数据长度
* 返 回 值: 无
*****************************************************************************************/
int ReadHistoryData(LogHeader LogH, uint8_t **Data, int Idx)
{
return ReadLog(LogH, Data, Idx);
}
/*****************************************************************************************
* 函数名称: NetCommOrgData
* 功能描述: 上报数据组织
* 参 数: SvrMac,服务器MAC地址
MegData, 消息队列数据
OutData, 输出数据出口
* 返 回 值: 数据长度
*****************************************************************************************/
int NetCommOrgData(GateWayPara GateWay, uint8_t *MegData, uint8_t *OutData)
{
uint8_t PayloadLen, Cmd, *Meg;
uint16_t check;
uint8_t Len;
PayloadLen = MegData[0];
Cmd = MegData[1];
Meg = &MegData[2];
NetCommFrameHeader NCHeader = (NetCommFrameHeader)OutData;
NCHeader->Header = 0x7A;
memcpy(NCHeader->GWMac, GateWay->ConfigPara.GwMac, 6);
memcpy(NCHeader->SvrMac, GateWay->SvrMac, 6);
NCHeader->Cmd = Cmd;
NCHeader->Timestamp = TimeTs();
NCHeader->PacketNum = 1;
NCHeader->PacketIdx = 1;
NCHeader->PayloadLen = PayloadLen;
Len = sizeof(NetCommFrameHeader_t);
memcpy(&OutData[Len], Meg, NCHeader->PayloadLen);
Len += NCHeader->PayloadLen;
check = CRC_Modbus(0xA001, OutData, Len);
OutData[Len++] = check & 0x00ff;
OutData[Len++] = (check >> 8) & 0x00ff;
return Len;
}
/*****************************************************************************************
* 函数名称: CheckCommUnitReg
* 功能描述: 检查设备是否注册
* 参 数: GateWay,网关句柄
CommUnitMac, 待检查的设备MAC
* 返 回 值: 已注册返回true,没注册返回false
*****************************************************************************************/
int CheckCommUnitReg(GateWayPara GateWay, uint8_t *CommUnitMac)
{
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(memcmp(GateWay->ConfigPara.CommUnitArray[i].Mac, CommUnitMac, 6) == 0)
return i;
}
return -1;
}
/*****************************************************************************************
* 函数名称: CommUnitSendCmd
* 功能描述: 网关下发通讯单元指令函数
* 参 数: GateWay, 网关句柄
CommUnitMac,通讯单元MAC地址
Cmd, 命令字
Payload, 下发数据
PayloadLen 下发数据长度
* 返 回 值: 无
*****************************************************************************************/
void CommUnitCmdSend(GateWayPara GateWay, uint8_t *CommUnitMac, CommUnitCmd_m Cmd, uint8_t *Payload, uint16_t PayloadLen, SendData Send)
{
uint8_t SendBuff[50];
uint8_t SendLen;
if(PayloadLen > 10)
return;
CommUnitFrameHeader CUHeader = (CommUnitFrameHeader)SendBuff;
CUHeader->Header = 0x7B;
memcpy(CUHeader->GWMac, GateWay->ConfigPara.GwMac, 6);
if(CommUnitMac == NULL) {
memset(CUHeader->DevMac, 0x00, 6);
CUHeader->DevType = 0x0000;
}
else {
int ret = CheckCommUnitReg(GateWay, CommUnitMac);
if(ret < 0)
return;
memcpy(CUHeader->DevMac, CommUnitMac, 6);
CUHeader->DevType = GateWay->ConfigPara.CommUnitArray[ret].CUType;
}
CUHeader->Cmd = Cmd;
CUHeader->PayloadLen = PayloadLen;
SendLen = sizeof(CommUnitFrameHeader_t);
if(PayloadLen > 0) {
memcpy(&SendBuff[SendLen], Payload, PayloadLen);
SendLen += PayloadLen;
}
uint16_t crc16 = CRC_Modbus(0xA001, SendBuff, SendLen);
SendBuff[SendLen++] = crc16 & 0x00ff;
SendBuff[SendLen++] = (crc16 >> 8) & 0x00ff;
if(Send != NULL) {
Send(SendBuff, SendLen);
}
}
/*****************************************************************************************
* 函数名称: RS485OrgData
* 功能描述: 下发传感器指令函数
* 参 数: GWMac,网关mac地址
CUPara, 通讯单元参数
sData, 数据入口
* 返 回 值: 数据长度
*****************************************************************************************/
int CommUintOrgData(GateWayPara GateWay, CommUnitPara CUPara, CommUnitData CUData, uint8_t *sData)
{
uint8_t Len = 0;
uint8_t SensorN = 0;
Len = 2;
memcpy(&sData[2], CUPara->Mac, 6);
Len += 6;
sData[Len++] = CUPara->CommStatus;
sData[Len++] = CUPara->BatLevel;
sData[Len++] = CUPara->SensorN;
for(int i = 0; i < SENSOR_NUM_MAX; i++) {
if(CUPara->SensorType[i] != 0x0000) {
sData[Len++] = CUPara->SensorType[i] & 0x00ff;
sData[Len++] = (CUPara->SensorType[i] >> 8) & 0x00ff;
SensorN++;
}
if(SensorN >= CUPara->SensorN)
break;
}
SensorN = 0;
for(int i = 0; i < SENSOR_NUM_MAX; i++) {
if(CUPara->SensorType[i] != 0x0000) {
switch(CUPara->SensorType[i]) {
case STRAIN_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(StrainSensorType_t));
Len += sizeof(StrainSensorType_t);
break;
case PRESSURE_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(PressureSensorType_t));
Len += sizeof(PressureSensorType_t);
break;
case SONAR_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(SonarSensorType_t));
Len += sizeof(SonarSensorType_t);
break;
case CAP_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(CapSensorType_t));
Len += sizeof(CapSensorType_t);
break;
case VIBRATE_SENSOR:
break;
case DEFM_3D_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(Defm3DSensorType_t));
Len += sizeof(Defm3DSensorType_t);
break;
case STRAIN_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(StrainMagSensorType_t));
Len += sizeof(StrainMagSensorType_t);
break;
case PRESSURE_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(PressureMagSensorType_t));
Len += sizeof(PressureMagSensorType_t);
break;
case SONAR_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(SonarMagSensorType_t));
Len += sizeof(SonarMagSensorType_t);
break;
case CAP_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(CapMagSensorType_t));
Len += sizeof(CapMagSensorType_t);
break;
case DEFM_3D_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(Defm3DMagSensorType_t));
Len += sizeof(Defm3DMagSensorType_t);
break;
case STRAIN_2_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(Strain2SensorType_t));
Len += sizeof(Strain2SensorType_t);
break;
case CRACK_2_SENSOR:
case CRACK_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(CrackSensorType_t));
Len += sizeof(CrackSensorType_t);
break;
case SIX_DIM_SENSOR:
break;
case POSTURE_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(PostureSensorType_t));
Len += sizeof(PostureSensorType_t);
break;
case LASER_DISTANCE_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(LaserDistanceSensorType_t));
Len += sizeof(LaserDistanceSensorType_t);
break;
}
SensorN++;
}
if(SensorN >= CUPara->SensorN)
break;
}
sData[0] = Len - 2;
sData[1] = NET_COMM_CMD_UPDATE;
return Len;
}
void DebugDisplaySensorData(int SensorIdx, uint16_t SensorType, uint8_t *SensorData)
{
switch(SensorType) {
case STRAIN_SENSOR: {
StrainSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(StrainSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Strain1=%d, Strain2=%d, Strain3=%d, Strain4=%d, Strain5=%d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
Sensor.Strain1, Sensor.Strain2, Sensor.Strain3, Sensor.Strain4, Sensor.Strain5);
break;
}
case STRAIN_SENSOR_MAG: {
StrainMegSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(StrainMegSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Megx=%04d, Megy=%04d, Megz=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.MegX, Sensor.MegY, Sensor.MegZ);
MAIN_DBG_LOG(" Strain1=%05d, Strain2=%05d, Strain3=%05d, Strain4=%05d, Strain5=%05d, Strain6=%05d\r\n",
Sensor.Strain1, Sensor.Strain2, Sensor.Strain3, Sensor.Strain4, Sensor.Strain5, Sensor.Strain6);
break;
}
case PRESSURE_SENSOR:{
PressureSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(PressureSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Press=%d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.Pressure);
break;
}
case SONAR_SENSOR:{
SonarSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(SonarSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Sonar1=%04d, Sonar2=%04d, Sonar3=%04d, Sonar4=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
Sensor.Sonar1, Sensor.Sonar2, Sensor.Sonar3, Sensor.Sonar4);
break;
}
case CAP_SENSOR:{
CapSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(CapSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Cap1=%04d, Cap2=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
Sensor.Capacitance1, Sensor.Capacitance2);
break;
}
case VIBRATE_SENSOR:
break;
case DEFM_3D_SENSOR:{
Defm3DSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Defm3DSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ);
break;
}
case STRAIN_2_SENSOR: {
Strain2SensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Strain2SensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Strain1=%d, Strain2=%d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.Strain1, Sensor.Strain2);
break;
}
case CRACK_2_SENSOR:
case CRACK_SENSOR: {
CrackSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(CrackSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: AccxL=%04d, AccyL=%04d, AcczL=%04d, MegxL=%04d, MegyL=%04d, MegzL=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX_L, Sensor.AccY_L, Sensor.AccZ_L, Sensor.MagX_L, Sensor.MagY_L, Sensor.MagZ_L);
MAIN_DBG_LOG(" AccxR=%04d, AccyR=%04d, AcczR=%04d, MegxR=%04d, MegyR=%04d, MegzR=%04d\r\n",
Sensor.AccX_R, Sensor.AccY_R, Sensor.AccZ_R, Sensor.MagX_R, Sensor.MagY_R, Sensor.MagZ_R);
break;
}
case POSTURE_SENSOR: {
PostureSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(PostureSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Pitch=%04d, Roll=%04d, VibStr=%04d, Temper=%04d\r\n",
SensorIdx, SensorType, Sensor.PitchAngle, Sensor.RollAngle, Sensor.VibrationStrength, Sensor.Temperature);
break;
}
case LASER_DISTANCE_SENSOR: {
LaserDistanceSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(LaserDistanceSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Distance=%d\r\n", SensorIdx, SensorType, Sensor.Distance);
break;
}
case DEFM_3D_SENSOR_MAG: {
Defm3DMegSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Defm3DMegSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Megx=%04d, Megy=%04d, Megz=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.MegX, Sensor.MegY, Sensor.MegZ);
break;
}
default:
break;
}
}
/*****************************************************************************************
* 函数名称: CommUnitAnalyze
* 功能描述: 通讯单元数据解析,使用于LORA和RS485通讯
* 参 数: rData,输入数据
rLen, 输入数据长度
* 返 回 值: 返回接收到的通讯单元序号,错误返回-1
*****************************************************************************************/
int CommUnitAnalyze(GateWayPara GateWay, uint8_t *rData, uint16_t rLen, SendData Response)
{
uint16_t check, crc16;
int CommUnitIdx;
uint16_t PayLoadLen;
uint8_t *PayLoad;
uint8_t *MegData;
uint16_t len;
uint8_t *Data;
uint16_t CommUintLen;
CommUnitFrameHeader CUHeader = (CommUnitFrameHeader)rData;
PayLoad = &rData[sizeof(CommUnitFrameHeader_t)];
if(CUHeader->Header != 0x7B)
return -1;
check = CRC_Modbus(0xA001, rData, rLen - 2);
crc16 = rData[rLen - 2] | (rData[rLen - 1] << 8);
if(check != crc16)
return -1;
CommUnitIdx = CheckCommUnitReg(GateWay, CUHeader->DevMac);
if(CommUnitIdx < 0) {
if(CUHeader->Cmd != COMM_UNIT_CMD_REG)
return -1;
}
switch(CUHeader->Cmd) {
case COMM_UNIT_CMD_REG:
if(PayLoad[0] > SENSOR_NUM_MAX) {
return -1;
}
if(CommUnitIdx >= 0) { //设备存在
MAIN_DBG_LOG("CommUnit has already been registered! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
uint8_t ret = 1;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CommErrCnt = 0;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
return CommUnitIdx;
}
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == false) {
CommUnitIdx = i;
memcpy(GateWay->ConfigPara.CommUnitArray[i].Mac, CUHeader->DevMac, 6);
GateWay->ConfigPara.CommUnitArray[i].CUType = CUHeader->DevMac[0] | (CUHeader->DevMac[1] << 8);
GateWay->ConfigPara.CommUnitArray[i].RegFlag = true;
MAIN_DBG_LOG("CommUnit register succeed!\r\n");
MAIN_DBG_LOG("Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
GateWay->ConfigPara.CommUnitArray[i].SensorN = PayLoad[0];
MAIN_DBG_LOG("SensorN: %d ", GateWay->ConfigPara.CommUnitArray[i].SensorN);
memcpy(GateWay->ConfigPara.CommUnitArray[i].SensorType, &PayLoad[1], CUHeader->PayloadLen - 1);
MAIN_DBG_LOG("Sensor Type: ");
for(int j = 0; j < GateWay->ConfigPara.CommUnitArray[i].SensorN; j++) {
MAIN_DBG_LOG("0x%04x, ", GateWay->ConfigPara.CommUnitArray[i].SensorType[j]);
}
MAIN_DBG_LOG("\r\n");
GateWay->ConfigPara.CommUnitArray[i].CommErrCnt = 0;
GateWay->ConfigPara.CommUnitArray[i].ConfigFlag = true;
GateWay->ConfigPara.CommUnitArray[i].CollectInterval = LW_DEV_COLLECT_INTERVAL_MAX;
GateWay->ConfigPara.CommUnitArray[i].ReportInterval = LW_DEV_REPORT_INTERVAL_MAX;
GateWay->ConfigPara.CommUnitArray[i].ERInterval = LW_DEV_ER_INTERVAL_MAX;
GateWay->ConfigPara.CommUnitArray[i].ERTime = LW_DEV_ER_TIME_MAX;
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
uint8_t ret = 1;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
if(GateWay->SvrRegFlag) { //网关已注册,向服务发送新设备添加指令
PayLoadLen = GateWay->ConfigPara.CommUnitArray[i].SensorN * 2 + 7;
len = PayLoadLen + 6;
MegData = rt_malloc(len);
MegData[0] = len;
MegData[1] = NET_COMM_CMD_ADD_UNIT;
memcpy(&MegData[2], CUHeader->DevMac, 6);
memcpy(&MegData[8], PayLoad, CUHeader->PayloadLen);
CatOneEthSendQueue(MegData, len + 2);
rt_free(MegData);
}
return 0xff;
}
}
MAIN_DBG_LOG("CommUnit register failed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
break;
case COMM_UNIT_CMD_CAIL:
if(*PayLoad == 0) {
MAIN_DBG_LOG("CommUnit calibrate failed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
}
else {
MAIN_DBG_LOG("CommUnit calibrate succeed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
}
break;
case COMM_UNIT_CMD_READ:
if(PayLoad[1] > SENSOR_NUM_MAX) {
return CommUnitIdx;
}
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CommStatus = true;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].RevNewDataFlag = true;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CommErrCnt = 0;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].BatLevel = PayLoad[0];
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN = PayLoad[1];
memset(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType, 0x00, sizeof(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType));
memcpy(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType, &PayLoad[2], GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN * 2);
len = 0;
Data = &PayLoad[GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN * 2 + 2];
int16_t Rssi;
int8_t Snr;
SX1276LoCalcRssiSnr(&Rssi, &Snr);
MAIN_DBG_LOG("Rssi:%d, Snr:%d\r\n", Rssi, Snr);
MAIN_DBG_LOG("CommUnit Mac:%02X-%02X-%02X-%02X-%02X-%02XBatLevel: %d%, SensorN: %d\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5],
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].BatLevel, GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN);
for(int i = 0; i < GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN; i++) {
memcpy(GateWay->CUDataArray[CommUnitIdx].Data[i], &Data[len], SensorTypeDataLen[GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType[i]]);
//显示传感器数据
DebugDisplaySensorData(i, GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType[i], GateWay->CUDataArray[CommUnitIdx].Data[i]);
len += SensorTypeDataLen[GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType[i]];
}
#ifdef LORA_LOWPOWER
{
uint32_t ctime = TimeTs();
// if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag == true) {
LPDevConfigPara_t Config;
Config.CollectInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval;
Config.ReportInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval;
Config.ERInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval;
Config.ERTime = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime;
Config.TimeStamp = ctime;
MAIN_DBG_LOG("CI:%d, RI:%d, EI:%d, ET:%d\r\n", Config.CollectInterval, Config.ReportInterval, Config.ERInterval, Config.ERTime);
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&Config, sizeof(LPDevConfigPara_t), Response);
// }
// else
// CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&ctime, 4, Response);
}
#endif
MegData = rt_malloc(512);
CommUintLen = CommUintOrgData(GateWay, &GateWay->ConfigPara.CommUnitArray[CommUnitIdx], &GateWay->CUDataArray[CommUnitIdx], MegData);
AddLog(&MegData[2], CommUintLen);
CatOneEthSendQueue(MegData, CommUintLen);
rt_free(MegData);
default:
break;
}
return CommUnitIdx;
}
/*****************************************************************************************
* 函数名称: Cat1RevCallBack
* 功能描述: 4G接收回调函数
* 参 数: rData,数据输入接口
rLen, 数据长度输入接口
* 返 回 值: 无
*****************************************************************************************/
int Cat1EthRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen)
{
uint16_t check,crc16;
uint8_t *Data;
uint8_t *MegData;
uint8_t sLen;
uint8_t CommUintMac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
NetCommFrameHeader NCHeader = (NetCommFrameHeader)rData;
uint16_t FrameLen = sizeof(NetCommFrameHeader_t) + NCHeader->PayloadLen;
if(FrameLen > CAT_ONE_REV_LEN_MAX)
return -1;
check = CRC_Modbus(0xA001, rData, FrameLen);
crc16 = rData[FrameLen] | (rData[FrameLen + 1] << 8);
Data = &rData[sizeof(NetCommFrameHeader_t)];
if(check != crc16)
return -1;
uint32_t cTime = TimeTs();
if(abs((int)(NCHeader->Timestamp - cTime)) > 2) {
TimeSync(NCHeader->Timestamp);
GateWay->TimeSyncFlag = true;
SensorCommPara_t SCPara;
SCPara.Cmd = RS485_SENSOR_CMD_TIME_SYNC;
SCPara.SensorAddr = 0x00;
SCPara.SensorType = 0x00;
SCPara.CmdParaLen = 4;
SCPara.CmdPara = (uint8_t *)&NCHeader->Timestamp;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable)
RS485CmdSend(GateWay, 1, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, GateWay->ConfigPara.Rs485Ch1.RS485Send);
}
if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable)
RS485CmdSend(GateWay, 2, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, GateWay->ConfigPara.Rs485Ch2.RS485Send);
}
//校准其他通讯网关
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, Sx1276LoRaSendBuffer);
}
switch(NCHeader->Cmd) {
case NET_COMM_CMD_REG:
if(*Data == 1) { //注册成功
GateWay->SvrRegFlag = true;
memcpy(GateWay->SvrMac, NCHeader->SvrMac, 6);
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
MAIN_DBG_LOG("Gateway Registered...\r\n");
}
else {
GateWay->SvrRegFlag = false;
memset(GateWay->SvrMac, 0x00, 6);
MAIN_DBG_LOG("Gateway Register Failed....\r\n");
}
break;
case NET_COMM_CMD_CAIL:
//应答服务器
MegData = rt_malloc(3);
MegData[0] = 1;
MegData[1] = NET_COMM_CMD_CAIL;
MegData[2] = 1;
sLen = 3;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
//开始校准
if(memcmp(CommUintMac, Data, 6) == 0) { //校准所有传感器
SensorCommPara_t SCPara;
SCPara.Cmd = RS485_SENSOR_CMD_CAIL;
SCPara.SensorAddr = 0x00;
SCPara.SensorType = 0x00;
SCPara.CmdParaLen = 0;
SCPara.CmdPara = NULL;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable)
RS485CmdSend(GateWay, 1, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch1.RS485Send);
}
if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable)
RS485CmdSend(GateWay, 2, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch2.RS485Send);
}
//校准其他通讯网关
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, Sx1276LoRaSendBuffer);
}
else {
int ret = CheckCommUnitReg(GateWay, CommUintMac);
if(ret < 0)
return -1;
if(GateWay->ConfigPara.CommUnitArray[ret].CUType != DEV_TYPE_EXT_COMMUNIT)
return -1;
if(GateWay->ConfigPara.CommUnitArray[ret].Mac[1] == 1) {
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, Sx1276LoRaSendBuffer);
}
else if(GateWay->ConfigPara.CommUnitArray[ret].Mac[1] == 2) {
if(GateWay->ConfigPara.Rs485Ch1.Enable && !GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) {
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch1.RS485Send);
}
else if(GateWay->ConfigPara.Rs485Ch2.Enable && !GateWay->ConfigPara.Rs485Ch2.CommUnitEnable) {
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch2.RS485Send);
}
}
}
break;
case NET_COMM_CMD_UPDATE:
MAIN_DBG_LOG("Received server response.....\r\n");
break;
case NET_COMM_CMD_READ_GW_INFO: {
MegData = rt_malloc(255);
int SensorCnt = 0;
sLen = 3;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) {
SensorCnt++;
memcpy(&MegData[sLen], GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac, 6);
sLen += 6;
}
}
if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable) {
SensorCnt++;
memcpy(&MegData[sLen], GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac, 6);
sLen += 6;
}
}
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(GateWay->ConfigPara.CommUnitArray[i].RegFlag) {
SensorCnt++;
memcpy(&MegData[sLen], GateWay->ConfigPara.CommUnitArray[i].Mac, 6);
sLen += 6;
}
}
MegData[sLen++] = GateWay->Battery;
MegData[sLen++] = GateWay->HistoryNum & 0x00ff;
MegData[sLen++] = (GateWay->HistoryNum >> 8) & 0x00ff;
MegData[sLen++] = (GateWay->HistoryNum >> 16) & 0x00ff;
MegData[sLen++] = (GateWay->HistoryNum >> 24) & 0x00ff;
MegData[0] = sLen - 2;
MegData[1] = NET_COMM_CMD_READ_GW_INFO;
MegData[2] = SensorCnt;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
break;
}
case NET_COMM_CMD_READ_UNIT_INFO: {
MegData = rt_malloc(40);
sLen = 2;
CommUnitPara CUnit;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) {
if(memcmp(GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac, Data, 6) == 0)
CUnit = &GateWay->ConfigPara.Rs485Ch1.CUData.Para;
}
}
else if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable) {
if(memcmp(GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac, Data, 6) == 0)
CUnit = &GateWay->ConfigPara.Rs485Ch2.CUData.Para;
}
}
else {
int ret = CheckCommUnitReg(GateWay, Data);
if(ret < 0)
return -1;
CUnit = &GateWay->ConfigPara.CommUnitArray[ret];
}
if(CUnit->SensorN > 16)
return -1;
memcpy(&MegData[sLen], CUnit->Mac, 6);
sLen += 6;
MegData[sLen++] = CUnit->SensorN;
//memcpy(&MegData[sLen], CUnit->SensorType, CUnit->SensorN * 2);
//sLen += CUnit->SensorN * 2;
uint8_t Sensor = 0;
for(int i = 0; i < SENSOR_NUM_MAX; i++) {
if(CUnit->SensorType[i] != 0x0000) {
MegData[sLen++] = CUnit->SensorType[i] & 0x00ff;
MegData[sLen++] = (CUnit->SensorType[i] >> 8) & 0x00ff;
Sensor++;
}
if(Sensor >= CUnit->SensorN)
break;
}
MegData[0] = sLen - 2;
MegData[1] = NET_COMM_CMD_READ_UNIT_INFO;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
break;
}
case NET_COMM_CMD_HIS_DATA: {
uint32_t *StartIdx, *EndIdx;
StartIdx = (uint32_t *)Data;
EndIdx = (uint32_t *)&Data[4];
if(*StartIdx > GateWay->HistoryNum)
return -1;
if(*EndIdx == 0) {
*EndIdx = GateWay->HistoryNum;
}
LogHeader_t LogH;
LogH.LogEndAddr = 0;
for(int i = *StartIdx; i < *EndIdx; i++) {
uint8_t *HisData;
int ret = ReadHistoryData(&LogH, &HisData, i);
if(HisData != NULL) {
MegData = rt_malloc(ret + 10);
MegData[0] = ret - 1 + 4;
MegData[1] = NET_COMM_CMD_HIS_DATA;
memcpy(&MegData[2], (uint8_t *)&LogH.LogIdx, 4);
sLen = 6;
memcpy(&MegData[sLen], HisData, 6);
sLen += 6;
memcpy(&MegData[sLen], &HisData[7], ret - 7);
sLen += ret - 7;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
rt_free(HisData);
rt_thread_delay(10);
}
else {
continue;
}
}
}
case NET_COMM_CMD_ADD_UNIT:
if(*Data == 1) { //录入成功
MAIN_DBG_LOG("Adding CommUnit succeeded...\r\n");
}
else {
MAIN_DBG_LOG("Adding CommUnit Failed...\r\n");
}
break;
case NET_COMM_CMD_LP_DEV_CONFIG: {
SvrDownLPDevConfigPara_t *LPDevConfig;
LPDevConfig = (SvrDownLPDevConfigPara_t *)Data;
int ret = memcmp(CommUintMac, LPDevConfig->CommDevAddr, 6);
if(ret == 0) {
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(GateWay->ConfigPara.CommUnitArray[i].RegFlag) {
GateWay->ConfigPara.CommUnitArray[i].CollectInterval = LPDevConfig->CollectInterval;
GateWay->ConfigPara.CommUnitArray[i].ReportInterval = LPDevConfig->ReportInterval;
GateWay->ConfigPara.CommUnitArray[i].ERInterval = LPDevConfig->ERInterval;
GateWay->ConfigPara.CommUnitArray[i].ERTime = LPDevConfig->ERTime;
GateWay->ConfigPara.CommUnitArray[i].ConfigFlag = true;
}
}
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
}
else {
int CommUnitIdx = CheckCommUnitReg(GateWay, LPDevConfig->CommDevAddr);
if(CommUnitIdx >= 0) {
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval = LPDevConfig->CollectInterval;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval = LPDevConfig->ReportInterval;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval = LPDevConfig->ERInterval;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime = LPDevConfig->ERTime;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
}
}
break;
}
default:
break;
}
return 0;
}
+546
View File
@@ -0,0 +1,546 @@
#include "main.h"
#include "RS485Task.h"
#include "Public.h"
#include "spiflash.h"
#include "CatOneTask.h"
#include "DebugCmd.h"
//#define RS485_DBG_LOG(...) { if(RS485DispEn) Debug_Printf(__VA_ARGS__);}
//static uint8_t RS485DispEn = false;
SensorCommPara_t SComm1Para;
SensorCommPara_t SComm2Para;
const uint8_t RS485SensorCmdPayLoadLen[RS485_SENSOR_CMD_END] = {0, 0, 0, 1, 0};
/*****************************************************************************************
* 函数名称: SavSensorData
* 功能描述: 记录传感器数据
* 参 数: SensorIdx, 传感器序号
Para,传感器结构指针
Data, 传感器数据
Len, 传感器数据长度
* 返 回 值: 无
*****************************************************************************************/
static void SavSensorData(uint8_t SensorIdx, CommUnitData CUData, uint8_t *Data, uint8_t Len)
{
if(Data == NULL) {
memset(CUData->Data[SensorIdx], 0x00, SENSOR_DATA_LEN_MAX);
}
else {
memcpy(CUData->Data[SensorIdx], Data, Len);
}
}
/*****************************************************************************************
* 函数名称: RS485Analyze
* 功能描述: 记录传感器数据
* 参 数: SCPara, 传感器发送参数
Para, 传感器结构指针
rData, 传感器数据入口
rLen, 传感器数据长度
* 返 回 值: 无
*****************************************************************************************/
void RS485Analyze(GateWayPara GateWay, SensorCommPara SCPara, CommUnit Para, uint8_t *rData, uint8_t rLen)
{
uint16_t crc16;
uint8_t *Payload;
crc16 = (rData[rLen - 1] << 8)|rData[rLen - 2];
uint16_t Check = CRC_Modbus(0xA001, rData, rLen - 2);
if(crc16 != Check)
return;
FrameHeader Header = (FrameHeader)rData;
if(Header->Cmd != RS485_SENSOR_CMD_QUERY) {
if(Header->SlvAddr != SCPara->SensorAddr || Header->DevType != Para->Para.SensorType[SCPara->SensorAddr - 1])
return;
}
Payload = &rData[sizeof(FrameHeader)];
if(Header->PayloadLen == 0)
return;
if(Header->SlvAddr == 0 || Header->SlvAddr > SENSOR_NUM_MAX)
return;
SCPara->SensorErrCnt[Header->SlvAddr - 1] = 0;
switch(Header->Cmd) {
case RS485_SENSOR_CMD_SET_ADDR:
if(*Payload == 1) {
MAIN_DBG_LOG("Sensor%d Addr Set succeed!\r\n", Header->SlvAddr);
}
else {
MAIN_DBG_LOG("Sensor%d Addr Set failed!\r\n", Header->SlvAddr);
}
break;
case RS485_SENSOR_CMD_CAIL:
if(*Payload == 1) {
MAIN_DBG_LOG("Sensor%d calibration succeeded!\r\n", Header->SlvAddr);
}
else {
MAIN_DBG_LOG("Sensor%d calibration succeeded!\r\n", Header->SlvAddr);
}
break;
case RS485_SENSOR_CMD_QUERY:
if(Para->Para.SensorN < 16) {
Para->Para.SensorN++;
Para->Para.SensorType[SCPara->SensorAddr - 1] = rData[6] | (rData[7] << 8);
MAIN_DBG_LOG("Found Sensor%d, Type: %d!\r\n", Header->SlvAddr, Para->Para.SensorType[SCPara->SensorAddr - 1]);
}
break;
case RS485_SENSOR_CMD_READ: {
memcpy(Para->SensorData.Data[SCPara->SensorAddr - 1], &rData[sizeof(FrameHeader_t)], Header->PayloadLen);
if(SCPara->SendFlag)
SCPara->ReadSensorCnt++;
DebugDisplaySensorData(Header->SlvAddr, Header->DevType, &rData[sizeof(FrameHeader_t)]);
}
default:
break;
}
}
/*****************************************************************************************
* 函数名称: RS485SensorCmdSend
* 功能描述: 下发传感器指令函数
* 参 数: Para,通讯参数入口
* 返 回 值: 无
*****************************************************************************************/
static void RS485SensorCmdSend(GateWayPara GateWay, SensorCommPara SensorComm)
{
uint8_t sData[50];
uint8_t sLen;
if(SensorComm->Cmd >= RS485_SENSOR_CMD_END)
return;
FrameHeader Header = (FrameHeader)sData;
Header->Header = 0x7A;
Header->SlvAddr = SensorComm->SensorAddr;
Header->Cmd = SensorComm->Cmd;
Header->DevType = SensorComm->SensorType;
Header->PayloadLen = SensorComm->CmdParaLen;
sLen = sizeof(FrameHeader_t);
if(SensorComm->CmdParaLen > 0) {
memcpy(&sData[sLen], SensorComm->CmdPara, SensorComm->CmdParaLen);
sLen += SensorComm->CmdParaLen;
}
uint16_t Check = CRC_Modbus(0xA001, sData, sLen);
sData[sLen++] = Check & 0xff;
sData[sLen++] = (Check >> 0x08) & 0x00ff;
if(SensorComm == &SComm1Para)
GateWay->ConfigPara.Rs485Ch1.RS485Send(sData, sLen);
else
GateWay->ConfigPara.Rs485Ch2.RS485Send(sData, sLen);
}
/*****************************************************************************************
* 函数名称: RS485SensorCmdSend
* 功能描述: 下发传感器指令函数
* 参 数: CommUintAddr 通讯单元地址
Para,通讯参数入口
* 返 回 值: 无
*****************************************************************************************/
void RS485CmdSend(GateWayPara GateWay, uint8_t CommUintAddr, SensorCommPara SensorComm)
{
SensorCommPara SC;
if(CommUintAddr)
SC = &SComm1Para;
else
SC = &SComm2Para;
SC->Cmd = SensorComm->Cmd;
SC->CmdPara = SensorComm->CmdPara;
SC->CmdParaLen = SensorComm->CmdParaLen;
SC->SensorAddr = SensorComm->SensorAddr;
SC->SensorType = SensorComm->SensorType;
RS485SensorCmdSend(GateWay, SC);
}
/*****************************************************************************************
* 函数名称: RS485LoopHandler
* 功能描述: RS485循环处理函数
* 参 数: GateWay, 网关参数句柄
RS485Ch, RS485通道句柄
SCPara RS485通讯句柄
* 返 回 值: 无
*****************************************************************************************/
static uint8_t CommUintData[512];
int test = 0;
void RS485LoopHandler(GateWayPara GateWay, RS485Para RS485Ch, SensorCommPara SCPara)
{
uint8_t RxBuffTemp[RS485_RX_BUFF_LEN_MAX];
uint8_t RxLenTemp;
uint16_t CommUintLen;
rt_err_t result;
uint8_t MegData[9];
int ret;
if(RS485Ch->Enable == false) {
rt_thread_delay(10);
return;
}
if(RS485Ch->CommUnitEnable) { //使用内置通讯单元
if(RS485Ch->QuerySensorFlag == true) { //开机查找传感器
if(SCPara->SensorCnt < SENSOR_NUM_MAX) {
rt_thread_delay(50);
SCPara->Cmd = RS485_SENSOR_CMD_QUERY;
SCPara->SensorAddr = SCPara->SensorCnt + 1;
SCPara->SensorType = 0;
SCPara->CmdParaLen = RS485SensorCmdPayLoadLen[RS485_SENSOR_CMD_QUERY];
SCPara->CmdPara = NULL;
//rt_mutex_take(GateWay->UartRevMutex, RT_WAITING_FOREVER);
SCPara->RS485TimeOutCnt = 0;
SCPara->RS485RxLen = 0;
RS485SensorCmdSend(GateWay, SCPara);
SCPara->SendFlag = true;
SCPara->SensorCnt++;
if(SCPara->SensorCnt >= SENSOR_NUM_MAX) {
SCPara->ReadSensorInterval = 2;
SCPara->SensorCnt = 0;
SCPara->ReadSensorCnt = 0;
RS485Ch->QuerySensorFlag = false;
}
}
}
else if(RS485Ch->CUData.Para.SensorN > 0){
SCPara->SendFlag = false;
if(SCPara->ReadSensorInterval > 0) {
SCPara->ReadSensorInterval--;
}
else {
if(SCPara->ReadSensorCnt >= RS485Ch->CUData.Para.SensorN || SCPara->SensorCnt >= SENSOR_NUM_MAX) {
SCPara->SensorCnt = 0;
SCPara->ReadSensorCnt = 0;
SCPara->ReadSensorInterval = GateWay->ConfigPara.CommUnitReadInterval * 5;
RS485Ch->CUData.Para.BatLevel = GateWay->Battery;
CommUintLen = CommUintOrgData(GateWay, &RS485Ch->CUData.Para, &RS485Ch->CUData.SensorData, CommUintData);
AddLog(&CommUintData[2], CommUintLen - 2);
CatOneEthSendQueue(CommUintData, CommUintLen);
if(RS485Ch == &GateWay->ConfigPara.Rs485Ch1) {
MAIN_DBG_LOG("InCommUint1 Send Meg...\r\n");
}
else {
MAIN_DBG_LOG("InCommUint2 Send Meg...\r\n");
}
SCPara->SensorCnt = 0;
}
else {
if(RS485Ch->CUData.Para.SensorType[SCPara->SensorCnt] != 0) {
rt_thread_delay(50);
SCPara->Cmd = RS485_SENSOR_CMD_READ;
SCPara->SensorAddr = SCPara->SensorCnt + 1;
SCPara->SensorType = RS485Ch->CUData.Para.SensorType[SCPara->SensorCnt];
SCPara->CmdParaLen = RS485SensorCmdPayLoadLen[RS485_SENSOR_CMD_READ];
SCPara->CmdPara = NULL;
//rt_mutex_take(GateWay->UartRevMutex, RT_WAITING_FOREVER);
RS485SensorCmdSend(GateWay, SCPara);
SCPara->SendFlag = true;
}
SCPara->SensorCnt++;
}
}
}
}
else { //读取外置通讯单元
if(SCPara->RS485CommUnitReadTimeDelay >= (GateWay->ConfigPara.CommUnitReadInterval * 5) && SCPara->SendFlag == false) {
if(SCPara->SendUnitCommIdx < COMMUNIT_MUM_MAX) {
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].RegFlag &&
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[2] == 0x02) {
Debug_Printf("RS485Ch%d Read CommUnit: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
((SCPara == &SComm1Para) ? 1 : 2),
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0],
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[1],
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[2],
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[3],
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[4],
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[5]);
CommUnitCmdSend(GateWay, GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac, COMM_UNIT_CMD_READ, NULL, 0, RS485Ch->RS485Send);
SCPara->SendFlag = true;
}
else {
SCPara->SendUnitCommIdx++;
return;
}
}
else {
SCPara->SendUnitCommIdx = 0;
SCPara->RS485CommUnitReadTimeDelay = 0;
}
}
}
if(SCPara->RS485CommUnitReadTimeDelay < (GateWay->ConfigPara.CommUnitReadInterval * 5))
SCPara->RS485CommUnitReadTimeDelay++;
result = rt_sem_take(SCPara->RS485Rev_Sem, 200);
if(result == RT_EOK) {
memcpy(RxBuffTemp, SCPara->RS485RxBuff, SCPara->RS485RxLen);
RxLenTemp = SCPara->RS485RxLen;
// memset(SCPara->RS485RxBuff, 0x00, RS485_RX_BUFF_LEN_MAX);
SCPara->RS485RxLen = 0;
if(RxBuffTemp[0] == 0x7A && RS485Ch->CommUnitEnable) { //内置通讯单元数据解析
if(SCPara->SendFlag == false) {
SCPara->RS485RxLen = 0;
return;
}
RS485Analyze(GateWay, SCPara, &RS485Ch->CUData, RxBuffTemp, RxLenTemp);
//rt_mutex_release(GateWay->UartRevMutex);
}
else if(RxBuffTemp[0] == 0x7B && RS485Ch->CommUnitEnable == false){ //读取外部通讯单元数据解析
if(SCPara == &SComm1Para)
ret = GateWay->CommUnitRevCallBack(GateWay, RxBuffTemp, RxLenTemp, GateWay->ConfigPara.Rs485Ch1.RS485Send);
else
ret = GateWay->CommUnitRevCallBack(GateWay, RxBuffTemp, RxLenTemp, GateWay->ConfigPara.Rs485Ch2.RS485Send);
if(ret == 0xff) { //注册信息
SCPara->RS485RxLen = 0;
return;
}
if(SCPara->SendFlag && GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].RevNewDataFlag) {
SCPara->SendUnitCommIdx++;
}
else {
SCPara->RS485RxLen = 0;
return;
}
}
else { //调试命令解析
DebugAnalyze(GateWay, RxBuffTemp, RxLenTemp);
}
SCPara->RS485RxLen = 0;
SCPara->SendFlag = false;
}
else {
if(RS485Ch->CommUnitEnable) {
//rt_mutex_release(GateWay->UartRevMutex);
if(SCPara->SendFlag == true) { //&& RS485Ch->CUData.Para.SensorN > 0 && RS485Ch->QuerySensorFlag == false){
if(RS485Ch == &GateWay->ConfigPara.Rs485Ch1) {
test++;
MAIN_DBG_LOG("InCommUint1, Sensor %d Comm Error, Cmd %d...\r\n", SCPara->SensorAddr, SCPara->Cmd);
}
else {
MAIN_DBG_LOG("InCommUint2, Sensor %d Comm Error, Cmd %d...\r\n", SCPara->SensorAddr, SCPara->Cmd);
}
SCPara->SensorErrCnt[SCPara->SensorAddr - 1]++;
if(SCPara->SensorErrCnt[SCPara->SensorAddr - 1] >= 5)
SavSensorData(SCPara->SensorAddr - 1, &RS485Ch->CUData.SensorData, NULL, 0);
}
}
else if(SCPara->SendFlag){
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommErrCnt++;
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommErrCnt == 10) {
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommErrCnt = 0;
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommStatus) {
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommStatus = 0;
MegData[0] = 7;
MegData[1] = COMM_UNIT_CMD_READ;
memcpy(&MegData[2], GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac, 6);
MegData[8] = GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommStatus;
CatOneEthSendQueue(MegData, 9); //发送离线消息
}
}
SCPara->SendUnitCommIdx++;
}
SCPara->SendFlag = false;
}
}
/*****************************************************************************************
* 函数名称: RS485Ch1_Thread_Entry
* 功能描述: RS485通道1任务函数
* 参 数: 任务参数入口
* 返 回 值: 无
*****************************************************************************************/
void RS485Ch1_Thread_Entry(void *parameter)
{
uint8_t InCommUnitMac[6] = {0x01, 0x80, 0x02, 0x00, 0x00, 0x01};
GateWayPara GateWay;
SensorCommPara SCPara;
RS485Para RS485Ch;
SCPara = &SComm1Para;
SCPara->SensorCnt = 0;
SCPara->InitOverFlag = false;
SCPara->ReadSensorInterval = 300;
GateWay = (GateWayPara)parameter;
InCommUnitMac[3] = GateWay->ConfigPara.GwMac[4];
InCommUnitMac[4] = GateWay->ConfigPara.GwMac[5];
RS485Ch = &GateWay->ConfigPara.Rs485Ch1;
memcpy(RS485Ch->CUData.Para.Mac, InCommUnitMac, 6);
RS485_CH1_POW_OFF();
if(RS485Ch->CommUnitEnable) {
RS485_CH1_POW_ON();
RS485Ch->CUData.Para.SensorN = 0;
memset(RS485Ch->CUData.Para.SensorType, 0x00, sizeof(SENSOR_NUM_MAX * 2));
RS485Ch->QuerySensorFlag = true;
RS485Ch->CUData.Para.CommStatus = true;
}
SCPara->RS485CommUnitReadTimeDelay = 100;
SCPara->RS485Rev_Sem = rt_sem_create("rsch1sem", 0, RT_IPC_FLAG_FIFO);
if(SCPara->RS485Rev_Sem == RT_NULL) {
Debug_Printf("RS485Ch1Rev Sem Create Failed!\r\n");
}
Debug_Printf("RS485Ch1Rev Thread is running\r\n");
rt_thread_delay(3000);
SCPara->InitOverFlag = true;
while(1) {
RS485LoopHandler(GateWay, RS485Ch, SCPara);
//rt_thread_delay(10);
}
}
/*****************************************************************************************
* 函数名称: RS485Ch1RxIrqCallback
* 功能描述: RS485通道1中断处理回调函数
* 参 数: rData 接收到的数据
* 返 回 值: 无
*****************************************************************************************/
void RS485Ch1RxIrqCallback(uint8_t rData)
{
if(SComm1Para.RS485TimeOutCnt == 0) {
SComm1Para.RS485RxLen = 0;
}
if(SComm1Para.RS485RxLen < RS485_RX_BUFF_LEN_MAX)
SComm1Para.RS485RxBuff[SComm1Para.RS485RxLen++] = rData;
SComm1Para.RS485TimeOutCnt = 3;
}
/*****************************************************************************************
* 函数名称: RS485Ch2_Thread_Entry
* 功能描述: RS485通道1任务函数
* 参 数: 任务参数入口
* 返 回 值: 无
*****************************************************************************************/
void RS485Ch2_Thread_Entry(void *parameter)
{
uint8_t InCommUnitMac[6] = {0x01, 0x80, 0x02, 0x00, 0x00, 0x02};
GateWayPara GateWay;
SensorCommPara SCPara;
RS485Para RS485Ch;
SCPara = &SComm2Para;
SCPara->SensorCnt = 0;
SCPara->InitOverFlag = false;
SCPara->ReadSensorInterval = 0;
GateWay = (GateWayPara)parameter;
InCommUnitMac[3] = GateWay->ConfigPara.GwMac[4];
InCommUnitMac[4] = GateWay->ConfigPara.GwMac[5];
RS485Ch = &GateWay->ConfigPara.Rs485Ch2;
memcpy(RS485Ch->CUData.Para.Mac, InCommUnitMac, 6);
RS485_CH2_POW_ON();
if(RS485Ch->CommUnitEnable) {
RS485_CH2_POW_ON();
RS485Ch->CUData.Para.SensorN = 0;
memset(RS485Ch->CUData.Para.SensorType, 0x00, sizeof(SENSOR_NUM_MAX * 2));
RS485Ch->QuerySensorFlag = true;
RS485Ch->CUData.Para.CommStatus = 1;
}
SCPara->RS485CommUnitReadTimeDelay = 100;
SCPara->RS485Rev_Sem = rt_sem_create("rsch2sem", 0, RT_IPC_FLAG_FIFO);
if(SCPara->RS485Rev_Sem == RT_NULL) {
Debug_Printf("RS485Ch2Rev Sem Create Failed!\r\n");
}
Debug_Printf("RS485Ch2Rev Thread is running\r\n");
rt_thread_delay(3000);
SCPara->InitOverFlag = true;
while(1) {
RS485LoopHandler(GateWay, RS485Ch, SCPara);
//rt_thread_delay(10);
}
}
/*****************************************************************************************
* 函数名称: RS485Ch2RxIrqCallback
* 功能描述: RS485通道1中断处理回调函数
* 参 数: rData 接收到的数据
* 返 回 值: 无
*****************************************************************************************/
void RS485Ch2RxIrqCallback(uint8_t rData)
{
if(SComm2Para.RS485TimeOutCnt == 0) {
SComm2Para.RS485RxLen = 0;
}
if(SComm2Para.RS485RxLen < RS485_RX_BUFF_LEN_MAX)
SComm2Para.RS485RxBuff[SComm2Para.RS485RxLen++] = rData;
SComm2Para.RS485TimeOutCnt = 3;
}
void RS485RxOverhandler(void)
{
if(SComm1Para.RS485TimeOutCnt > 0)
SComm1Para.RS485TimeOutCnt--;
if(SComm1Para.RS485RxLen > 5 && SComm1Para.RS485TimeOutCnt == 0) {
if(SComm1Para.InitOverFlag == true) {
rt_sem_release(SComm1Para.RS485Rev_Sem);
SComm1Para.RS485TimeOutCnt = 20;
}
else {
SComm1Para.RS485RxLen = 0;
SComm1Para.RS485TimeOutCnt = 0;
}
}
if(SComm2Para.RS485TimeOutCnt > 0)
SComm2Para.RS485TimeOutCnt--;
if(SComm2Para.RS485RxLen > 5 && SComm2Para.RS485TimeOutCnt == 0) {
if(SComm2Para.InitOverFlag == true) {
SComm2Para.RS485TimeOutCnt = 20;
rt_sem_release(SComm2Para.RS485Rev_Sem);
}
else {
SComm2Para.RS485RxLen = 0;
SComm2Para.RS485TimeOutCnt = 0;
}
}
}
#if 0
void RS485Ch2RxIrqCallback(uint8_t rData)
{
static bool FrameHeader = false;
static uint8_t rLen = 0;
if(FrameHeader == false) {
if(rData == 0x7a || rData == 0x7b) {
FrameHeader = true;
RS485Chr2RxLen = 0;
}
}
if(RS485Chr2RxLen < RS485_RX_BUFF_LEN_MAX) {
RS485Chr2RxBuff[RS485Chr2RxLen++] = rData;
}
else {
FrameHeader = false;
RS485Chr2RxLen = 0;
}
if(RS485Chr2RxLen == 6) {
rLen = rData + 8;
}
else if(RS485Chr2RxLen > 6) {
if(RS485Chr2RxLen >= rLen) {
rt_sem_release(RS485Ch2Rev_Sem);
FrameHeader = false;
}
}
}
#endif
+413
View File
@@ -0,0 +1,413 @@
#include <stdlib.h>
#include "bsp.h"
#include "ff.h"
/*****************************************************************************************
* System Clock
****************************************************************************************/
/*****************************************************************************************
* 函数名称: SystemClockConfig
* 功能描述: 系统时钟设置
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
static void SystemClockConfig(void)
{
stc_clk_sysclk_cfg_t stcSysClkCfg;
stc_clk_xtal_cfg_t stcXtalCfg;
stc_clk_mpll_cfg_t stcMpllCfg;
stc_sram_config_t stcSramConfig;
MEM_ZERO_STRUCT(stcSysClkCfg);
MEM_ZERO_STRUCT(stcXtalCfg);
MEM_ZERO_STRUCT(stcMpllCfg);
MEM_ZERO_STRUCT(stcSramConfig);
/* Set bus clk div. */
stcSysClkCfg.enHclkDiv = ClkSysclkDiv1;
stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;
CLK_SysClkConfig(&stcSysClkCfg);
/* Config Xtal and Enable Xtal */
stcXtalCfg.enMode = ClkXtalModeOsc;
stcXtalCfg.enDrv = ClkXtalLowDrv;
stcXtalCfg.enFastStartup = Enable;
CLK_XtalConfig(&stcXtalCfg);
CLK_XtalCmd(Enable);
// /* Config Hrc and enable HRC */
// CLK_HrcTrim(SystemCoreClock);
// CLK_HrcCmd(Enable);
/* sram init include read/write wait cycle setting */
stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx;
stcSramConfig.enSramRC = SramCycle2;
stcSramConfig.enSramWC = SramCycle2;
SRAM_Init(&stcSramConfig);
/* flash read wait cycle setting */
EFM_Unlock();
EFM_SetLatency(EFM_LATENCY_5);
EFM_Lock();
/* MPLL config (XTAL / pllmDiv * plln / PllpDiv = 200M). */
stcMpllCfg.pllmDiv = 1ul;
stcMpllCfg.plln = 50ul;
stcMpllCfg.PllpDiv = 2ul;
stcMpllCfg.PllqDiv = 2ul;
stcMpllCfg.PllrDiv = 2ul;
CLK_SetPllSource(ClkPllSrcXTAL);
CLK_MpllConfig(&stcMpllCfg);
/* Enable MPLL. */
CLK_MpllCmd(Enable);
/* Wait MPLL ready. */
while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
{
;
}
/* Switch driver ability */
PWC_HS2HP();
/* Switch system clock source to MPLL. */
CLK_SetSysClkSource(CLKSysSrcMPLL);
}
/*****************************************************************************************
* Debug Uart
****************************************************************************************/
/*****************************************************************************************
* 函数名称: DbgUartRec
* 功能描述: 调试串口接收函数
* 参 数: 无
* 返 回 值: 返回收到的字符
*****************************************************************************************/
static uint8_t DbgUartRec(void)
{
uint16_t u16Data = USART_RecData(DBG_USART_CH);
return (uint8_t)u16Data;
}
/*****************************************************************************************
* 函数名称: DBGUsartErrIrqCallback
* 功能描述: 调试串口错误中断回调函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
static void DBGUsartErrIrqCallback(void)
{
if(DBG_USART_CH->SR_f.ORE) {
DBG_USART_CH->CR1_f.CORE = 1;
USART_RecData(DBG_USART_CH);
}
if(DBG_USART_CH->SR_f.PE)
DBG_USART_CH->CR1_f.CPE = 1;
if(DBG_USART_CH->SR_f.FE)
DBG_USART_CH->CR1_f.CFE = 1;
}
/*****************************************************************************************
* 函数名称: DbgUsartRxIrqCallback
* 功能描述: 调试串口接收中断回调函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
static void DbgUsartRxIrqCallback(void)
{
uint8_t rData = DbgUartRec();
DbgRxIrqCallback(rData);
}
/*****************************************************************************************
* 函数名称: DbgUart_Config
* 功能描述: 调试串口配置函数
* 参 数: BaudRate 串口波特率
* 返 回 值: 无
*****************************************************************************************/
void DbgUart_Config(uint32_t BaudRate)
{
stc_usart_uart_init_t stcInitCfg;
stc_irq_regi_conf_t stcIrqRegiCfg;
en_result_t enRet;
stc_port_init_t stcPortInit;
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinOType = Pin_OType_Cmos;
PORT_Init(DBG_USART_RX_PORT, DBG_USART_RX_PIN, &stcPortInit);
PORT_Init(DBG_USART_TX_PORT, DBG_USART_TX_PIN, &stcPortInit);
stcInitCfg.enClkMode = UsartIntClkCkNoOutput;
stcInitCfg.enClkDiv = UsartClkDiv_1;
stcInitCfg.enDataLength = UsartDataBits8;
stcInitCfg.enDirection = UsartDataLsbFirst;
stcInitCfg.enStopBit = UsartOneStopBit;
stcInitCfg.enParity = UsartParityNone;
stcInitCfg.enSampleMode = UsartSampleBit8;
stcInitCfg.enDetectMode = UsartStartBitFallEdge;
stcInitCfg.enHwFlow = UsartRtsEnable;
PWC_Fcg1PeriphClockCmd(DBG_FCG1_PERIPH, Enable);
PORT_SetFunc(DBG_USART_RX_PORT, DBG_USART_RX_PIN, DBG_USART_RX_FUNC, Disable);
PORT_SetFunc(DBG_USART_TX_PORT, DBG_USART_TX_PIN, DBG_USART_TX_FUNC, Disable);
enRet = USART_UART_Init(DBG_USART_CH, &stcInitCfg);
if(enRet != Ok) {
Error_Handler();
}
enRet = USART_SetBaudrate(DBG_USART_CH, BaudRate);
if(enRet != Ok) {
Error_Handler();
}
stcIrqRegiCfg.enIRQn = DBGUART_IRQn;
stcIrqRegiCfg.pfnCallback = &DbgUsartRxIrqCallback;
stcIrqRegiCfg.enIntSrc = DBG_USART_RI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/* Set USART RX error IRQ */
stcIrqRegiCfg.enIRQn = DBGUART_EI_IRQn;
stcIrqRegiCfg.pfnCallback = &DBGUsartErrIrqCallback;
stcIrqRegiCfg.enIntSrc = DBG_USART_EI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
#if 0
/* Set USART TX IRQ */
stcIrqRegiCfg.enIRQn = Int002_IRQn;
stcIrqRegiCfg.pfnCallback = &UsartTxIrqCallback;
stcIrqRegiCfg.enIntSrc = USART_TI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/* Set USART TX complete IRQ */
stcIrqRegiCfg.enIRQn = Int003_IRQn;
stcIrqRegiCfg.pfnCallback = &UsartTxCmpltIrqCallback;
stcIrqRegiCfg.enIntSrc = USART_TCI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
#endif
USART_FuncCmd(DBG_USART_CH, UsartTx, Enable);
USART_FuncCmd(DBG_USART_CH, UsartRx, Enable);
USART_FuncCmd(DBG_USART_CH, UsartRxInt, Enable);
}
/*****************************************************************************************
* 函数名称: DebugUartSend
* 功能描述: 调试串口发送函数
* 参 数: sData 发送数据入口指针
sLen 发送数据长度
* 返 回 值: 无
*****************************************************************************************/
void DebugUartSend(uint8_t *sData, uint16_t sLen)
{
for(int i = 0; i < sLen; i++) {
USART_SendData(DBG_USART_CH, sData[i]);
while(USART_GetStatus(DBG_USART_CH, UsartTxComplete) == Reset);
}
}
/*****************************************************************************************
* 函数名称: GPIO_Config
* 功能描述: GPIO配置函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
static void GPIO_Config(void)
{
stc_port_init_t stcPortInit;
stc_port_pub_set_t stcPortPub;
PORT_DebugPortSetting(TDO_SWO, Disable);
PORT_DebugPortSetting(TDI, Disable);
PORT_DebugPortSetting(TRST, Disable);
MEM_ZERO_STRUCT(stcPortInit);
MEM_ZERO_STRUCT(stcPortPub);
stcPortPub.enReadWait = WaitCycle3;
PORT_PubSetting(&stcPortPub);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enPinOType = Pin_OType_Cmos;
stcPortInit.enPinDrv = Pin_Drv_H;
stcPortInit.enPullUp = Disable;
PORT_Init(KEY_LED_PORT, KEY_LED_PIN, &stcPortInit);
PORT_ResetBits(KEY_LED_PORT, KEY_LED_PIN);
PORT_Init(BAT_LED_R_PORT, BAT_LED_R_PIN, &stcPortInit);
PORT_ResetBits(BAT_LED_R_PORT, BAT_LED_R_PIN);
PORT_Init(BAT_LED_G_PORT, BAT_LED_G_PIN, &stcPortInit);
PORT_ResetBits(BAT_LED_G_PORT, BAT_LED_G_PIN);
PORT_Init(STATE_LED_R_PORT, STATE_LED_R_PIN, &stcPortInit);
PORT_ResetBits(STATE_LED_R_PORT, STATE_LED_R_PIN);
PORT_Init(STATE_LED_G_PORT, STATE_LED_G_PIN, &stcPortInit);
PORT_ResetBits(STATE_LED_G_PORT, STATE_LED_G_PIN);
}
void Error_Handler(void)
{
while(1){ ; }
}
/*****************************************************************************************
* Watch Dog
****************************************************************************************/
/*****************************************************************************************
* 函数名称: FeedDog
* 功能描述: 看门狗喂狗函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
void FeedDog(void)
{
#if (WATCH_DOG == 1)
SWDT_RefreshCounter();
#endif
}
void BSP_Init(void)
{
SystemClockConfig();
GPIO_Config();
DbgUart_Config(500000);
FeedDog();
SysTick_Init(1000);
FeedDog();
}
void FlashWrite(uint32_t Addr, uint32_t *wData, uint8_t wLen)
{
// while(Ok != Flash_SectorErase(BOOT_PARA_ADDRESS));
// for(int i = 0; i < wLen / 4; i++) {
// Flash_WriteWord(BOOT_PARA_ADDRESS + i * 4, wData[i]);
// }
EFM_Unlock();
/* Enable flash. */
EFM_FlashCmd(Enable);
/* Wait flash ready. */
while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY)) { ; }
/* Sequence program. */
//EFM_SequenceProgram(FLASH_WRITE_ADDR, wLen, wData);
for(int i = 0; i < wLen; i++) {
EFM_SingleProgram(Addr + i * 4, wData[i]);
}
EFM_Lock();
}
static void FlashRead(uint32_t *rData, uint8_t rLen)
{
uint32_t u32Addr = BOOT_PARA_ADDRESS;
for(int i = 0; i < rLen / 4; i++) {
rData[i] = *((volatile uint32_t*)(u32Addr + i * 4));
}
}
void ReadBootPara(BootPara rData)
{
FlashRead((uint32_t *)rData, sizeof(BootPara_t));
}
void WriteBootPara(BootPara wData)
{
int wLen;
uint32_t *Data;
Data = (uint32_t *)wData;
wLen = sizeof(BootPara_t) / 4;
EFM_Unlock();
/* Enable flash. */
EFM_FlashCmd(Enable);
/* Wait flash ready. */
while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY)) { ; }
/* Erase sector. */
EFM_SectorErase(BOOT_PARA_ADDRESS);
for(int i = 0; i < wLen; i++) {
EFM_SingleProgram(BOOT_PARA_ADDRESS + i * 4, Data[i]);
}
/* Lock EFM. */
EFM_Lock();
}
void EraseFlash(void)
{
EFM_Unlock();
EFM_FlashCmd(Enable);
while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY)) { ; }
for(int Addr = APP_ADDRESS; Addr < FLASH_SIZE; Addr += FLASH_SECTOR_SIZE) {
EFM_SectorErase(Addr);
}
EFM_Lock();
}
/*****************************************************************************************
* User Irq CallBack
****************************************************************************************/
/*****************************************************************************************
* 函数名称: DbgRxIrqCallback
* 功能描述: 调试串口接收中断外部重定向回调函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
__weak void DbgRxIrqCallback(uint8_t rData)
{
}
/*****************************************************************************************
* 函数名称: RS485Ch1RxIrqCallback
* 功能描述: RS485通道1串口接收中断外部重定向回调函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
__weak void RS485Ch1RxIrqCallback(uint8_t rData)
{
}
/*****************************************************************************************
* 函数名称: RS485Ch2RxIrqCallback
* 功能描述: RS485通道1串口接收中断外部重定向回调函数
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
__weak void RS485Ch2RxIrqCallback(uint8_t rData)
{
}
+338
View File
@@ -0,0 +1,338 @@
#include <stdlib.h>
#include <math.h>
#include "main.h"
//设备唯一编码,固定在0x00002800位置
const uint8_t DevMac[6] __attribute__((section(".ARM.__at_0x00002800"))) = {DEVICE_TYPE & 0xFF, (DEVICE_TYPE >> 8) & 0xFF, COMM_WAY, (ADD_NUMBER >> 16) & 0xFF, (ADD_NUMBER >> 8) & 0xFF, ADD_NUMBER & 0xFF};
//const uint8_t DevMac[6] __attribute__((at(DEV_MAC_ADDRESS)))= {0x19, 0x00, 0x02, 0x00, 0x00, 0x01};
uint32_t pdwCrc32Tbl[256];
void InitCrc32Table(uint32_t* Crc32Tbl)
{
for (int wCnt = 0; wCnt!= 256; wCnt++){
uint32_t dwCrc = wCnt;
for (int ucCnt = 0; ucCnt != 8; ucCnt++){
if (dwCrc & 1){
dwCrc = (dwCrc >> 1) ^ 0xEDB88320;
}
else{
dwCrc >>= 1;
}
}
Crc32Tbl[wCnt] = dwCrc;
}
}
uint32_t GetCrc32(int dwLen)
{
uint32_t Data;
uint32_t dwCrc32Data = 0xFFFFFFFF;
for (int dwCnt = 0; dwCnt!= dwLen; ++dwCnt){
Data = *((volatile uint8_t*)(APP_ADDRESS + dwCnt));
uint32_t dwTbl = (dwCrc32Data ^ Data) & 0xFF;
dwCrc32Data = ((dwCrc32Data >> 8) & 0xFFFFFF) ^ pdwCrc32Tbl[dwTbl];
}
return ~dwCrc32Data;
}
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length)
{
uint16_t crc = 0xffff;
uint16_t index,i;
for(index = 0 ; index < length;index++) {
crc ^= para[index];
for(i = 0; i < 8; i++) {
if(crc & 1) {
crc >>= 1;
crc ^= wBase;
}
else
crc >>= 1;
}
}
return crc;
}
uint32_t JumpAddress;
func_ptr_t JumpToApplication;
BootLoader_t BL;
static void BootLoader1mSRoutine(void)
{
if(BL.BootLoader1mSDlyCnt)
BL.BootLoader1mSDlyCnt--;
if(BL.UartRevTimeOutCnt > 0)
BL.UartRevTimeOutCnt--;
BL.FeedDogDlyCnt++;
}
void FeedDogHandler(void)
{
if(BL.FeedDogDlyCnt >= 200) {
FeedDog();
BL.FeedDogDlyCnt = 0;
}
}
void AppWriteFlash(uint32_t AddrOffset, uint8_t *wData, int wLen)
{
FlashWrite(APP_ADDRESS + AddrOffset, (uint32_t *)wData, wLen / 4);
}
//static bool JumpToApp(uint32_t AppAddr)
//{
// uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
// if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + RAM_SIZE))) {
// JumpAddress = *(__IO uint32_t *)(AppAddr + 4);
// JumpToApplication = (func_ptr_t)JumpAddress;
// __set_MSP(*(__IO uint32_t *)AppAddr);
// JumpToApplication();
// }
// return Error;
//}
static bool JumpToApp(uint32_t AppAddr)
{
uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + SRAM_SIZE))) {
JumpAddress = *(__IO uint32_t *)(AppAddr + 4);
JumpToApplication = (func_ptr_t)JumpAddress;
__set_MSP(*(__IO uint32_t *)AppAddr);
JumpToApplication();
}
return Error;
}
void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
{
uint8_t sData[20], sLen;
uint16_t crc16;
FrameH Frame = (FrameH)sData;
Frame->Header = 0x7a;
Frame->SlvAddr = 0x01;
Frame->Cmd = Cmd;
if(Cmd == 0x01) {
Frame->PayloadLen = 1;
sData[sizeof(FrameHeader_t)] = PayLoad;
}
else if(Cmd == 0x02) {
Frame->PayloadLen = 4;
GDReq GDData = (GDReq)&sData[sizeof(FrameHeader_t)];
GDData->PackageIndex = PayLoad;
GDData->PackageNum = BL.AppPackageCnt;
}
sLen = sizeof(FrameHeader_t) + Frame->PayloadLen;
crc16 = CRC_Modbus(CRC16_BASE, sData, sLen);
sData[sLen++] = crc16;
sData[sLen++] = (crc16 >> 8) & 0x00ff;
DebugUartSend(sData, sLen);
}
bool AnalyzeData(uint8_t *rData, uint16_t rLen)
{
uint16_t crc16, check;
check = CRC_Modbus(CRC16_BASE, rData, rLen - 2);
crc16 = (rData[rLen - 1] << 8) | rData[rLen - 2];
if(check != crc16) {
return false;
}
FrameH Frame = (FrameH)rData;
if(Frame->Cmd == 0x81) {
UDReq UpData = (UDReq)&rData[sizeof(FrameHeader_t)];
BL.Para.AppFlag = 0;
BL.Para.UpdateFlag = APP_UPDATE_FLAG;
BL.Para.Crc32Check = UpData->AppCrc32;
BL.Para.PackageCnt = UpData->PackageNum;
BL.Para.AppSize = UpData->AppSize;
WriteBootPara(&BL.Para);
BL.BootLoader1mSDlyCnt = 20;
BL.Status = BL_RESET;
SendGetCmd(0x01, 1);
}
else if(Frame->Cmd == 0x82) {
if(BL.UpDateFlag == false)
return false;
DownRes DownData = (DownRes)&rData[sizeof(FrameHeader_t)];
if(BL.AppPackageIdx != DownData->PackageIndex) {
return false;
}
AppWriteFlash(BL.AppPackageIdx * 200, &BL.RxBuff[sizeof(FrameHeader_t) + sizeof(DownResponse_t)], DownData->DataLen);
BL.AppPackageIdx++;
BL.RevErrCnt = 0;
if(BL.AppPackageIdx < BL.AppPackageCnt) {
BL.Status = BL_GET_DATA;
BL.BootLoader1mSDlyCnt = 5;
//BuzzCtrl(10, 0, 1);
}
else {
uint32_t crc32 = GetCrc32(BL.Para.AppSize);
if(crc32 == BL.Para.Crc32Check) {
BL.Status = BL_START_APP;
BL.Para.AppFlag = 0; //升级成功首次启动时,把APP启动标志清除,由APP置位,下次启动便按标志启动
BL.Para.UpdateFlag = 0;
BL.Para.DevType = DEV_TYPE;
WriteBootPara(&BL.Para);
}
}
}
else
return false;
return true;
}
void BootLoaderLoopHandler(void)
{
if(BL.RxFlag) {
BL.RxFlag = false;
AnalyzeData(BL.RxBuff, BL.RxLen);
TURN_OFF_STATE_LED();
}
switch(BL.Status){
case BL_IDLE:
break;
case BL_RESET:
if(BL.BootLoader1mSDlyCnt > 0) {
break;
}
NVIC_SystemReset();
break;
case BL_START_APP:
enIrqResign(DBGUART_IRQn);
enIrqResign(DBGUART_EI_IRQn);
JumpToApp(APP_ADDRESS);
break;
case BL_ERASE_FLASH:
FeedDog();
EraseFlash();
FeedDog();
BL.Status = BL_GET_DATA;
BL.BootLoader1mSDlyCnt = 200;
BL.AppPackageCnt = BL.Para.PackageCnt;
BL.RevErrCnt = 0;
BL.UpDateFlag = true;
break;
case BL_GET_DATA:
if(BL.BootLoader1mSDlyCnt > 0)
break;
SendGetCmd(0x02, BL.AppPackageIdx);
BL.Status = BL_WAIT_REV;
BL.BootLoader1mSDlyCnt = 500;
break;
case BL_WAIT_REV:
if(BL.BootLoader1mSDlyCnt == 0) {
BL.Status = BL_GET_DATA_TIMEOUT;
}
break;
case BL_GET_DATA_TIMEOUT:
BL.RevErrCnt++;
if(BL.RevErrCnt < 3) {
BL.Status = BL_GET_DATA;
}
else {
BL.Status = BL_IDLE;
BL.Para.AppFlag = 0;
BL.RevErrCnt = 0;
BL.Para.UpdateFlag = 0;
WriteBootPara(&BL.Para);
BL.UpDateFlag = false;
}
break;
}
}
int32_t main(void)
{
BSP_Init();
InitCrc32Table(pdwCrc32Tbl);
ReadBootPara(&BL.Para);
if(BL.Para.DevType != DEV_TYPE) { //设备类型错误,清除升级参数
BL.Status = BL_IDLE;
BL.Para.AppFlag = 0;
BL.Para.UpdateFlag = 0;
BL.Para.DevAddr = 0x01;
BL.Para.DevType = DEV_TYPE;
WriteBootPara(&BL.Para);
}
else if(BL.Para.AppFlag == APP_START_FLAG) {
BL.Status = BL_START_APP;
}
else if(BL.Para.UpdateFlag == APP_UPDATE_FLAG) {
BL.Status = BL_ERASE_FLASH;
}
while (1) {
FeedDogHandler();
BootLoaderLoopHandler();
}
}
/*******************************************************************************
* 中断服务函数
******************************************************************************/
void SysTick_IrqHandler(void)
{
BootLoader1mSRoutine();
}
static uint16_t rLen;
static uint8_t rBuff[300];
static bool Header;
static uint16_t PayLen;
void DbgRxIrqCallback(uint8_t RxData)
{
if(BL.UartRevTimeOutCnt == 0) {
Header = false;
rLen = 0;
PayLen = 0;
}
BL.UartRevTimeOutCnt = 3;
if(Header == false && RxData == 0x7a) {
Header = true;
rLen = 0;
PayLen = 0;
rBuff[rLen++] = RxData;
}
else {
rBuff[rLen++] = RxData;
if(rLen == 4) {
PayLen = rBuff[3];
if(PayLen > 256) {
Header = false;
return;
}
}
else if(rLen == sizeof(FrameHeader_t) + PayLen + 2) {
BL.RxLen = rLen;
memcpy(BL.RxBuff, rBuff, BL.RxLen);
BL.RxFlag = true;
Header = false;
TURN_ON_STATE_LED_GREEN();
}
}
}
+486
View File
@@ -0,0 +1,486 @@
#include "spiflash.h"
#include "rtthread.h"
#include "DebugCmd.h"
//#define FLASH_TEST
#ifdef FLASH_TEST
uint8_t flashtestbuff[SPIFLASH_SIZE];
#endif
static uint8_t SpiFlashReadByte(void)
{
return Spi1SendReceive(0);
}
static void SpiFlashSendByte(uint8_t sData)
{
Spi1SendReceive(sData);
}
static void SpiFlashWriteEnable(void)
{
SpiFlashClrNss();
SpiFlashSendByte(SPIFLASH_CMD_WREN);
SpiFlashSetNss();
}
static void SpiFlashWaitForWriteEnd(void)
{
uint8_t flashstatus = 0;
SpiFlashClrNss();
SpiFlashSendByte(SPIFLASH_CMD_RDSR);
do{
flashstatus = SpiFlashReadByte();
}
while ((flashstatus & SPIFLASH_WIP_FLAG) == SPIFLASH_WIP_FLAG);
SpiFlashSetNss();
}
//扇区擦除
void SpiFlashEraseSector(uint32_t SectorAddr)
{
#ifdef FLASH_TEST
memset(&flashtestbuff[SectorAddr], 0xff, 4096);
#else
SpiFlashWriteEnable();
SpiFlashWaitForWriteEnd();
SpiFlashClrNss();
SpiFlashSendByte(SPIFLASH_CMD_SE);
SpiFlashSendByte((SectorAddr >> 16) & 0x00FF);
SpiFlashSendByte((SectorAddr >> 8) & 0x00FF);
SpiFlashSendByte(SectorAddr & 0x00FF);
SpiFlashSetNss();
SpiFlashWaitForWriteEnd();
#endif
}
//整片擦除
void SpiFlashEraseChip(void)
{
SpiFlashWriteEnable();
SpiFlashClrNss();
SpiFlashSendByte(SPIFLASH_CMD_BE);
SpiFlashSetNss();
SpiFlashWaitForWriteEnd();
}
//写数据
void SpiFlashWriteData(uint8_t* wData, uint32_t wAddr, uint16_t wLen)
{
#ifdef FLASH_TEST
memcpy(&flashtestbuff[wAddr], wData, wLen);
#else
SpiFlashWriteEnable();
SpiFlashClrNss();
SpiFlashSendByte(SPIFLASH_CMD_WRITE);
SpiFlashSendByte((wAddr >> 16) & 0x00FF);
SpiFlashSendByte((wAddr >> 8) & 0x00FF);
SpiFlashSendByte(wAddr & 0x00FF);
for(int i = 0; i < wLen; i++) {
SpiFlashSendByte(wData[i]);
}
SpiFlashSetNss();
SpiFlashWaitForWriteEnd();
#endif
}
void SpiFlashWriteAnyLengthData(uint8_t* wData, uint32_t wAddr, uint16_t wLen)
{
uint16_t PageCnt; //需要写入页数
uint16_t FirstPageWriteSize; //在起始地址不为页起始地址的情况下,先写入当前页剩余空间
uint16_t LastPageWriteSize; //最后一页写入长度
uint32_t AddrOffset = 0;
uint32_t WriteAddr;
LogHeader LogH;
WriteAddr = wAddr;
//写入的长度超出最大空间,从起始开始写起
if((WriteAddr + wLen) > SPIFLASH_SIZE) {
LogH = (LogHeader)wData;
WriteAddr = LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE;
LogH->LogEndAddr = WriteAddr + wLen;
}
uint16_t FirstPageRemainSpace = SPIFLASH_PAGESIZE - (WriteAddr % SPIFLASH_PAGESIZE);
// //判断是否跨扇区,跨扇区需要先擦除下一扇区
// CheckDelSecter(wAddr, wLen);
if(wLen < FirstPageRemainSpace) {
FirstPageWriteSize = wLen; //计算首页写入长度
PageCnt = 0;
LastPageWriteSize = 0;
}
else {
// FirstPageWriteSize = FirstPageRemainSpace % SPIFLASH_PAGESIZE;
// PageCnt = (wLen - (FirstPageWriteSize % SPIFLASH_PAGESIZE)) / SPIFLASH_PAGESIZE; //计算需要写入多少整页
// LastPageWriteSize = (wLen - (FirstPageWriteSize % SPIFLASH_PAGESIZE)) % SPIFLASH_PAGESIZE; //计算剩余需要写入的长度
FirstPageWriteSize = FirstPageRemainSpace;
PageCnt = (wLen - FirstPageWriteSize) / SPIFLASH_PAGESIZE; //计算需要写入多少整页
LastPageWriteSize = (wLen - FirstPageWriteSize) % SPIFLASH_PAGESIZE; //计算剩余需要写入的长度
}
if(FirstPageWriteSize > 0) {
SpiFlashWriteData(&wData[AddrOffset], WriteAddr, FirstPageWriteSize);
AddrOffset += FirstPageWriteSize;
WriteAddr += FirstPageWriteSize;
}
for(int i = 0; i < PageCnt; i++) {
SpiFlashWriteData(&wData[AddrOffset], WriteAddr, SPIFLASH_PAGESIZE);
AddrOffset += SPIFLASH_PAGESIZE;
WriteAddr += SPIFLASH_PAGESIZE;
}
if(LastPageWriteSize > 0) {
SpiFlashWriteData(&wData[AddrOffset], WriteAddr, LastPageWriteSize);
}
}
void SpiFlashReadAnyLengthData(uint8_t* rData, uint32_t rAddr, uint16_t rLen)
{
#ifdef FLASH_TEST
memcpy(rData, &flashtestbuff[rAddr], rLen);
#else
SpiFlashClrNss();
SpiFlashSendByte(SPIFLASH_CMD_READ);
SpiFlashSendByte((rAddr >> 16) & 0x00FF);
SpiFlashSendByte((rAddr >> 8) & 0x00FF);
SpiFlashSendByte(rAddr & 0x00FF);
for(int i = 0; i < rLen; i++) {
rData[i] = SpiFlashReadByte();
}
SpiFlashSetNss();
#endif
}
uint32_t SpiFlashReadId(void)
{
uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
SpiFlashClrNss();
SpiFlashSendByte(0x9F);
Temp0 = SpiFlashReadByte();
Temp1 = SpiFlashReadByte();
Temp2 = SpiFlashReadByte();
SpiFlashSetNss();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
typedef struct {
uint16_t Flag;
uint16_t LoopSavFlag; //循环存储标志
uint32_t LogCnt; //日志最大数量
uint32_t FirstLogStartAddr; //第一个数据的起始地址
uint32_t LastLogEndAddr; //最后一个数据的结束地址
}LogNumSav_t;
static LogNumSav_t LogNumArray[256];
static __IO uint32_t gLogCnt = 0;
static __IO uint32_t FirstLogStartAddr = 0; //第一个日志起始地址
static __IO uint32_t LastLogEndAddr = 0; //最后一个日志结束地址
static __IO uint16_t LoopSavFlag = 0; //循环存储标志
static uint16_t LogNumIdx;
uint16_t ReadLoopSavFlag(void)
{
return LoopSavFlag;
}
void SetLoopSavFlag(uint16_t LoopFlag)
{
LoopSavFlag = LoopFlag;
}
uint32_t ReadLogNum(void)
{
return gLogCnt;
}
void SetLogNum(uint32_t LogCnt)
{
gLogCnt = LogCnt;
}
uint32_t ReadFirstLogStartAddr(void)
{
return FirstLogStartAddr;
}
void SetFirstLogStartAddr(uint32_t FLStartAddr)
{
FirstLogStartAddr = FLStartAddr;
}
uint32_t ReadLastLogEndAddr(void)
{
return LastLogEndAddr;
}
void SetLastLogEndAddr(uint32_t LLEndAddr)
{
LastLogEndAddr = LLEndAddr;
}
void LogInit(void)
{
LogNumIdx = 0xffff;
SpiFlashReadId();
SpiFlashReadAnyLengthData((uint8_t *)&LogNumArray, LOG_INFO_START_SECTOR * SPIFLASH_SECTORSIZE, sizeof(LogNumArray));
for(int i = 0; i < 256; i++) {
if(LogNumArray[i].Flag != LOG_INFO_SAV_FLAG) {
LogNumIdx = i;
break;
}
}
if(LogNumIdx == 0xffff) { //256条记录满,读最后一条记录
LogNumIdx = 0;
SetLogNum(LogNumArray[255].LogCnt);
SetLoopSavFlag(LogNumArray[255].LoopSavFlag);
SetFirstLogStartAddr(LogNumArray[255].FirstLogStartAddr);
SetLastLogEndAddr(LogNumArray[255].LastLogEndAddr);
return;
}
if(LogNumIdx == 0) { //没有记录
LogNumIdx = 0;
SetLogNum(0);
SetLoopSavFlag(0);
SetFirstLogStartAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
SetLastLogEndAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
return;
}
SetLogNum(LogNumArray[LogNumIdx-1].LogCnt);
SetLoopSavFlag(LogNumArray[LogNumIdx-1].LoopSavFlag);
SetFirstLogStartAddr(LogNumArray[LogNumIdx-1].FirstLogStartAddr);
SetLastLogEndAddr(LogNumArray[LogNumIdx-1].LastLogEndAddr);
}
void SavLogNum(uint32_t LogNum)
{
LogNumSav_t CLogSav;
if(LogNum == 0) {
LogNumIdx = 0;
SetLogNum(0);
SetLoopSavFlag(0);
SetFirstLogStartAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
SetLastLogEndAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
SpiFlashEraseSector(LOG_INFO_START_SECTOR * SPIFLASH_SECTORSIZE);
return;
}
SetLogNum(LogNum);
CLogSav.Flag = LOG_INFO_SAV_FLAG;
CLogSav.LogCnt = LogNum;
CLogSav.FirstLogStartAddr = ReadFirstLogStartAddr();
CLogSav.LastLogEndAddr = ReadLastLogEndAddr();
if(LogNumIdx == 256) {
SpiFlashEraseSector(LOG_INFO_START_SECTOR * SPIFLASH_SECTORSIZE);
LogNumIdx = 0;
}
SpiFlashWriteData((uint8_t *)&CLogSav, LogNumIdx * sizeof(LogNumSav_t) + LOG_INFO_START_SECTOR * SPIFLASH_SECTORSIZE, sizeof(LogNumSav_t));
LogNumIdx++;
}
/*****************************************************************************************
* 函数名称: CheckDelSecter
* 功能描述: 检查需要删除的扇区,跨扇区删除下一扇区,如果到了删除最后一个扇区,循环到起始扇区
* 参 数: wAddr, 写入地址
wLen, 写入长度
* 返 回 值: 返回写入起始地址
*****************************************************************************************/
uint8_t LogBuff[LOG_SAV_SIZE_MAX];
const uint8_t SavFlag[4] ={0xAA, 0x55, 0x55, 0xAA};
void CheckDelSecter(uint32_t wAddr, uint16_t wLen)
{
uint32_t DelOffsetAddr, FindFirstLogAddr; //存储起始地址
uint32_t DelSectorNum = 0;
uint32_t SurplusSpace = SPIFLASH_SECTORSIZE - (wAddr % SPIFLASH_SECTORSIZE);
if((wAddr + wLen) > SPIFLASH_SIZE) {
DelOffsetAddr = LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE;
SetLastLogEndAddr(DelOffsetAddr + wLen);
SetLoopSavFlag(1);
SpiFlashEraseSector(DelOffsetAddr);
FindFirstLogAddr = DelOffsetAddr + SPIFLASH_SECTORSIZE;
}
else {
if(wLen < SurplusSpace) { //长度没有超过扇区剩余容量
SetLastLogEndAddr(wAddr + wLen);
return;
}
DelOffsetAddr = (wAddr / SPIFLASH_SECTORSIZE + 1) * SPIFLASH_SECTORSIZE;
DelSectorNum = (wLen - SurplusSpace) / SPIFLASH_SECTORSIZE + 1;
SetLastLogEndAddr(wAddr + wLen);
for(int i = 0; i < DelSectorNum; i++) {
SpiFlashEraseSector(DelOffsetAddr);
DelOffsetAddr += SPIFLASH_SECTORSIZE;
}
if(DelOffsetAddr == SPIFLASH_SIZE) {
DelOffsetAddr = LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE;
}
FindFirstLogAddr = DelOffsetAddr;
}
if(!ReadLoopSavFlag())
return;
uint32_t ReadAddr = FindFirstLogAddr;
while(1) {
SpiFlashReadAnyLengthData(LogBuff, ReadAddr, LOG_SAV_SIZE_MAX);
int i;
for(i = 0; i < LOG_SAV_SIZE_MAX; i++) {
if(memcmp(&LogBuff[i], SavFlag, 4) == 0) {
SetFirstLogStartAddr(ReadAddr + i);
return;;
}
}
if(i == LOG_SAV_SIZE_MAX) {
ReadAddr += LOG_SAV_SIZE_MAX;
if(ReadAddr >= SPIFLASH_SIZE) { //找不到下一条数据,重置flash
Debug_Printf("Add LOG Error, Next Data No Find!\r\n");
SetLogNum(0);
SetLoopSavFlag(0);
SetFirstLogStartAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
SetLastLogEndAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
return;
}
}
}
}
uint8_t LogBuffTemp[LOG_SAV_SIZE_MAX];
void AddLog(uint8_t *wData, uint32_t wLen)
{
//const uint8_t SavFlag[4] ={0xAA, 0x55, 0x55, 0xAA};
uint32_t LogNum;
uint32_t LogSize;
//uint32_t FLStartAddr;
uint32_t LLEndAddr;
// uint32_t SectorN;
LogHeader LogH;
LogH = (LogHeader)LogBuffTemp;
LogNum = ReadLogNum();
if(LogNum == 0) {
SetFirstLogStartAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
SetLastLogEndAddr(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
SpiFlashEraseSector(LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE);
}
//FLStartAddr = ReadFirstLogStartAddr();
LLEndAddr = ReadLastLogEndAddr();
LogNum++;
LogH->LogSavFlag = LOG_SAV_FLAG;
LogH->LogIdx = LogNum;
LogSize = wLen + sizeof(LogHeader_t);
LogH->LogEndAddr = LLEndAddr + LogSize;
LogH->TimeStamp = TimeTs();
memcpy(&LogBuffTemp[sizeof(LogHeader_t)], wData, wLen);
//判断是否跨扇区,跨扇区需要先擦除下一扇区
CheckDelSecter(LLEndAddr, LogSize);
if(LogH->LogEndAddr > SPIFLASH_SIZE) {
LLEndAddr = LOG_SAV_START_SECTOR * SPIFLASH_SECTORSIZE;
LogH->LogEndAddr = ReadLastLogEndAddr();
}
SpiFlashWriteAnyLengthData(LogBuffTemp, LLEndAddr, LogSize);
SavLogNum(LogNum);
//Debug_Printf("Add LOG: %d,endaddr = %d\r\n", LogNum, ReadLastLogEndAddr());
}
/*****************************************************************************************
* 函数名称: ReadLog
* 功能描述: 读取日志
* 参 数: Header, 上一包日志头信息,连续读取时传入上一包数据信息,缩短日志遍历时间,
Header->LogEndAddr为0读取第一包数据,LogIdx数据无效
rData, 日志出口,需要释放
LogIdx, 读取的日志的序号,为0读取Header->LogEndAddr对应日志
* 返 回 值: 返回数据长度
*****************************************************************************************/
int ReadLog(LogHeader Header, uint8_t **rData, uint32_t LogIdx)
{
uint32_t FSAddr;
int LogLen = 0;
//bool FirstIdx = false;
if(Header == NULL)
return 0;
if(Header->LogEndAddr == 0) {
Header->LogEndAddr = ReadFirstLogStartAddr();
LogIdx = 0;
}
if(LogIdx == 1) {
FSAddr = ReadFirstLogStartAddr();
}
else
FSAddr = Header->LogEndAddr;
while(1) {
SpiFlashReadAnyLengthData((uint8_t *)Header, FSAddr, sizeof(LogHeader_t));
if(Header->LogSavFlag != LOG_SAV_FLAG) {
if((SPIFLASH_SIZE - FSAddr) < LOG_SAV_SIZE_MAX) { //判断是否到片尾
FSAddr = LOG_SAV_START_SECTOR * SPIFLASH_SECTOR_NUM;
continue;
}
else
return 0;
}
if(LogIdx == 0) {
LogIdx = Header->LogIdx;
}
else if(Header->LogIdx != LogIdx) {
FSAddr = Header->LogEndAddr;
continue;
}
if(Header->LogIdx == LogIdx) {
if(*rData == NULL)
return sizeof(LogHeader_t);
SpiFlashReadAnyLengthData(LogBuffTemp, FSAddr, Header->LogEndAddr - FSAddr);
LogLen = Header->LogEndAddr - FSAddr - sizeof(LogHeader_t);
*rData = rt_malloc(LogLen);
if(*rData == NULL)
return 0;
memcpy(*rData, &LogBuffTemp[sizeof(LogHeader_t)], LogLen);
break;
}
}
return LogLen;
}
/*****************************************************************************************
* 函数名称: ReadPara
* 功能描述: 读取参数
* 参 数: Para, 网管参数
ParaLen, 参数长度
* 返 回 值: 无
*****************************************************************************************/
int ReadPara(uint8_t *Para, uint32_t ParaLen)
{
SpiFlashReadAnyLengthData(Para, GATEWEY_PARA_SAV_ADDR, ParaLen); //读取片尾数据
return 0;
}
/*****************************************************************************************
* 函数名称: WritePara
* 功能描述: 写入参数
* 参 数: Para, 网管参数
ParaLen, 参数长度
* 返 回 值: 无
*****************************************************************************************/
int WritePara(uint8_t *Para, uint32_t ParaLen)
{
SpiFlashEraseSector(GATEWEY_PARA_SAV_ADDR);
SpiFlashWriteAnyLengthData(Para, GATEWEY_PARA_SAV_ADDR, ParaLen); //读取片尾数据
return 0;
}
/* USER CODE END */