初始版本
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,730 @@
|
||||
#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)
|
||||
Debug_Printf("\r\nCat1 Display Enable!\r\n\r\n");
|
||||
else
|
||||
Debug_Printf("\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 < 24 || sTimet.tm_year > 50)
|
||||
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);
|
||||
CatOne.GateWay->BatteryReadDlyCnt = 30;
|
||||
}
|
||||
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)
|
||||
{
|
||||
uint16_t UnitCommCnt = 0;
|
||||
uint8_t *p = &TxBuff[0];
|
||||
uint16_t len = 5;
|
||||
|
||||
if(CatOne.GateWay->ConfigPara.Rs485Ch1.CommUnitEnable == true && CatOne.GateWay->ConfigPara.Rs485Ch1.Enable == true) {
|
||||
UnitCommCnt++;
|
||||
memcpy(&p[len], CatOne.GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac[0], 6);
|
||||
len += 6;
|
||||
}
|
||||
if(CatOne.GateWay->ConfigPara.Rs485Ch2.CommUnitEnable == true && CatOne.GateWay->ConfigPara.Rs485Ch2.Enable == true) {
|
||||
UnitCommCnt++;
|
||||
memcpy(&p[len], CatOne.GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac[0], 6);
|
||||
len += 6;
|
||||
}
|
||||
for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
|
||||
if(CatOne.GateWay->ConfigPara.CommUnitArray[i].RegFlag == true) {
|
||||
for(int j = 0; j < CatOne.GateWay->ConfigPara.CommUnitArray[i].SensorN; j++)
|
||||
{
|
||||
memcpy(&p[len], CatOne.GateWay->ConfigPara.CommUnitArray[i].Mac[j], 6);
|
||||
len += 6;
|
||||
UnitCommCnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
TxBuff[0] = (len - 3) & 0x00ff;
|
||||
TxBuff[1] = ((len - 3) >> 8) & 0x00ff;
|
||||
TxBuff[2] = NET_COMM_CMD_REG;
|
||||
TxBuff[3] = UnitCommCnt & 0x00ff;
|
||||
TxBuff[4] = (UnitCommCnt >> 8) & 0x00ff;
|
||||
return len;
|
||||
}
|
||||
|
||||
void CatOneLoopHandler(void)
|
||||
{
|
||||
static rt_err_t result;
|
||||
uint16_t ret;
|
||||
static uint8_t Cat1RevErrCnt = 0;
|
||||
|
||||
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 > CAT1_ERR_RESET_DLY_MAX) {
|
||||
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 = 3;
|
||||
Cat1RevErrCnt++;
|
||||
if(Cat1RevErrCnt > 10) {
|
||||
CatOne.Status = CAT_ONE_RESET;
|
||||
CAT1_DBG_LOG("Cat1 has no receive data for a long time, Reset!\r\n");
|
||||
Cat1RevErrCnt = 0;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Cat1RevErrCnt = 0;
|
||||
}
|
||||
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 = 3;
|
||||
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);
|
||||
CatOne.GateWay->BatteryReadDlyCnt = 60;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EthLoopHandler(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
if(CatOne.GateWay->SvrRegFlag == false) {
|
||||
if(CatOne.RegisterDelayCnt == 0) {
|
||||
if(ETH_LINK_GET() == Reset) {
|
||||
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;
|
||||
CAT1_DBG_LOG("Eth Send: %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);
|
||||
RxBuffTemp[CatOneEthRxLen] = 0;
|
||||
CAT1_DBG_LOG("Eth Rev: %s\r\n",RxBuffTemp);
|
||||
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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
#include "LoraTask.h"
|
||||
#include "main.h"
|
||||
#include "CatOneTask.h"
|
||||
#include "DebugCmd.h"
|
||||
|
||||
#define UC_OFFLINE_TIME_INTERVAL_MAX (2 * 60 * 60)//离线判断最大时间间隔,单位秒
|
||||
|
||||
static rt_sem_t LoraDioIRQ_Sem = RT_NULL;
|
||||
static rt_thread_t LoraIRQ_Thread = RT_NULL;
|
||||
static GateWayPara GateWay;
|
||||
|
||||
void LoraSend(uint8_t* pucBuff, uint8_t ucLen)
|
||||
{
|
||||
Sx1276LoRaSendBuffer(pucBuff, ucLen);
|
||||
}
|
||||
|
||||
//Lora接收消息统一放到消息队列,由接收任务处理
|
||||
int LoraRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen)
|
||||
{
|
||||
uint8_t *sData;
|
||||
if(rLen > 255)
|
||||
return -1;
|
||||
|
||||
sData = rt_malloc(rLen + 5);
|
||||
sData[0] = rLen;
|
||||
|
||||
// Debug_Printf("Lora Rev: ");
|
||||
// for(int i = 0; i < rLen; i++) {
|
||||
// Debug_Printf("%02x ", rData[i]);
|
||||
// }
|
||||
// Debug_Printf("\r\n");
|
||||
|
||||
memcpy(&sData[1], rData, rLen);
|
||||
rt_mq_send(GateWay->LoraRev_MQ, sData, rLen + 1);
|
||||
rt_free(sData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LoraIRQ_Thread_Entry(void *parameter)
|
||||
{
|
||||
rt_err_t result;
|
||||
static uint16_t LoraErrCnt = 0;
|
||||
|
||||
Debug_Printf("LoraRev Thread is running!\r\n");
|
||||
while(1) {
|
||||
if(GateWay->ConfigPara.Lora.OnOff == false) {
|
||||
rt_thread_delay(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = rt_sem_take(LoraDioIRQ_Sem, 1000);
|
||||
if(result == RT_EOK) {
|
||||
IsrSx1276LoRaTxRx(GateWay);
|
||||
LoraErrCnt = 0;
|
||||
}
|
||||
else {
|
||||
LoraErrCnt++;
|
||||
if(LoraErrCnt > LORA_ERR_RESET_DLY_MAX) { //15分钟内没有收到lora数据重启lora模块
|
||||
LoraErrCnt = 0;
|
||||
Debug_Printf("Lora Reset!\r\n");
|
||||
Sx1276LoRaInit(LoraRevCallBack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LoRaSendBuffer(uint8_t* pucBuff, uint16_t ucLen)
|
||||
{
|
||||
if(GateWay->ConfigPara.Lora.OnOff)
|
||||
Sx1276LoRaSendBuffer(pucBuff, ucLen);
|
||||
}
|
||||
|
||||
void Lora_Thread_Entry(void *parameter)
|
||||
{
|
||||
rt_err_t result;
|
||||
#ifndef LORA_LOWPOWER
|
||||
bool UnitCommSendFlag = false;
|
||||
uint8_t SendUnitCommIdx = 0;
|
||||
uint16_t UnitCommReadDelayCnt = 0;
|
||||
#endif
|
||||
uint8_t Payload[256];
|
||||
uint8_t MegData[9];
|
||||
|
||||
GateWay = (GateWayPara)parameter;
|
||||
|
||||
while(GateWay->ConfigPara.Lora.OnOff == false) {
|
||||
rt_thread_delay(100);
|
||||
}
|
||||
|
||||
LoraDioIRQ_Sem = rt_sem_create("loradioirq_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
if(LoraDioIRQ_Sem == RT_NULL) {
|
||||
Debug_Printf("CatOneIRQ Sem Create Failed!\r\n");
|
||||
}
|
||||
|
||||
LoraIRQ_Thread = rt_thread_create("LoraIRQ", LoraIRQ_Thread_Entry, NULL, 512, 3, 20);
|
||||
if (LoraIRQ_Thread != RT_NULL)
|
||||
rt_thread_startup(LoraIRQ_Thread);
|
||||
|
||||
Sx1276LoRaInit(LoraRevCallBack);
|
||||
Debug_Printf("Lora Thread is running!\r\n");
|
||||
#ifdef LORA_LOWPOWER
|
||||
while(1) {
|
||||
if(GateWay->ConfigPara.Lora.OnOff == false) {
|
||||
rt_thread_delay(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = rt_mq_recv(GateWay->LoraRev_MQ, Payload, 256, 1000);
|
||||
if(result == RT_EOK) {
|
||||
int ret = GateWay->CommUnitRevCallBack(GateWay, &Payload[1], Payload[0], LoRaSendBuffer);
|
||||
if(ret == 0xff) //注册信息
|
||||
continue;
|
||||
}
|
||||
else { //离线判断
|
||||
for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
|
||||
if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == true) {
|
||||
if(GateWay->ConfigPara.CommUnitArray[i].CommErrCnt < UC_OFFLINE_TIME_INTERVAL_MAX) {
|
||||
GateWay->ConfigPara.CommUnitArray[i].CommErrCnt++;
|
||||
}
|
||||
else if(GateWay->ConfigPara.CommUnitArray[i].CommStatus) {
|
||||
GateWay->ConfigPara.CommUnitArray[i].CommStatus = 0;
|
||||
MegData[0] = 7;
|
||||
MegData[1] = 0;
|
||||
MegData[2] = COMM_UNIT_CMD_READ;
|
||||
memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[i].Mac[0], 6);
|
||||
MegData[9] = GateWay->ConfigPara.CommUnitArray[i].CommStatus;
|
||||
Debug_Printf("The CommUnit is offline.Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
|
||||
GateWay->ConfigPara.CommUnitArray[i].Mac[0][0],
|
||||
GateWay->ConfigPara.CommUnitArray[i].Mac[0][1],
|
||||
GateWay->ConfigPara.CommUnitArray[i].Mac[0][2],
|
||||
GateWay->ConfigPara.CommUnitArray[i].Mac[0][3],
|
||||
GateWay->ConfigPara.CommUnitArray[i].Mac[0][4],
|
||||
GateWay->ConfigPara.CommUnitArray[i].Mac[0][5]);
|
||||
CatOneEthSendQueue(MegData, 10); //发送离线消息
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
while(1) {
|
||||
if(UnitCommSendFlag == false && UnitCommReadDelayCnt >= GateWay->ConfigPara.CommUnitReadInterval) {
|
||||
if(SendUnitCommIdx < COMMUNIT_NUM_MAX) {
|
||||
if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RegFlag &&
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[2] == 0x01) {
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RevNewDataFlag = false;
|
||||
Debug_Printf("Lora Read CommUnit: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0],
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[1],
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[2],
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[3],
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[4],
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[5]);
|
||||
CommUnitCmdSend(GateWay, GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], COMM_UNIT_CMD_READ, NULL, 0, Sx1276LoRaSendBuffer);
|
||||
UnitCommSendFlag = true;
|
||||
}
|
||||
else {
|
||||
SendUnitCommIdx++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SendUnitCommIdx = 0;
|
||||
UnitCommReadDelayCnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(UnitCommReadDelayCnt < GateWay->ConfigPara.CommUnitReadInterval)
|
||||
UnitCommReadDelayCnt++;
|
||||
|
||||
result = rt_mq_recv(GateWay->LoraRev_MQ, Payload, 256, 1000);
|
||||
if(result == RT_EOK) {
|
||||
int ret = GateWay->CommUnitRevCallBack(GateWay, &Payload[1], Payload[0], Sx1276LoRaSendBuffer);
|
||||
if(ret == 0xff) //注册信息
|
||||
continue;
|
||||
|
||||
if(UnitCommSendFlag && GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].RevNewDataFlag) {
|
||||
UnitCommSendFlag = false;
|
||||
SendUnitCommIdx++;
|
||||
}
|
||||
}
|
||||
else if(UnitCommSendFlag) { //离线判断
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt++;
|
||||
if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt == 10) {
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommErrCnt = 0;
|
||||
if(GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus) {
|
||||
GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus = 0;
|
||||
MegData[0] = 7;
|
||||
MegData[1] = 0;
|
||||
MegData[2] = COMM_UNIT_CMD_READ;
|
||||
memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].Mac[0], 6);
|
||||
MegData[9] = GateWay->ConfigPara.CommUnitArray[SendUnitCommIdx].CommStatus;
|
||||
CatOneEthSendQueue(MegData, 10); //发送离线消息
|
||||
}
|
||||
}
|
||||
UnitCommSendFlag = false;
|
||||
SendUnitCommIdx++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void LoraTxRxIrqCallback(void)
|
||||
{
|
||||
rt_sem_release(LoraDioIRQ_Sem);
|
||||
}
|
||||
|
||||
void LoraInit(void)
|
||||
{
|
||||
Sx1276LoRaInit(LoraRevCallBack);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,623 @@
|
||||
#include "main.h"
|
||||
#include "RS485Task.h"
|
||||
#include "Public.h"
|
||||
#include "spiflash.h"
|
||||
#include "CatOneTask.h"
|
||||
#include "DebugCmd.h"
|
||||
#include "update_protocol.h"
|
||||
#include "bsp.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
|
||||
* 功能描述: 485数据解析
|
||||
* 参 数: 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)
|
||||
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(SCPara->SensorData.Data[SCPara->SensorAddr - 1], &rData[sizeof(FrameHeader_t)], Header->PayloadLen);
|
||||
if(SCPara->SendFlag)
|
||||
SCPara->ReadSensorCnt++;
|
||||
DebugDisplaySensorData(Header->SlvAddr, 0, &rData[sizeof(FrameHeader_t)]);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_on_start(uint8_t* frame, int len, uint8_t* pload, int size)
|
||||
{
|
||||
update_protocol_req_t* pReq = (void*)&frame[sizeof(update_protocol_hd_t)];
|
||||
|
||||
//TODO:
|
||||
|
||||
boot_para_t cfg = {0};
|
||||
|
||||
cfg.AppFlag = 0;
|
||||
cfg.UpdateFlag = APP_UPDATE_FLAG;
|
||||
cfg.Crc32Check = pReq->AppCrc32;
|
||||
cfg.PackageNum = pReq->PackageNum;
|
||||
cfg.AppSize = pReq->AppSize;
|
||||
/**
|
||||
操作FALSH ,写升级参数
|
||||
**/
|
||||
dev_boot_write_param(cfg);
|
||||
|
||||
update_send_cmd(0x01, 1, pReq->PackageNum);
|
||||
|
||||
//重启进入BOOT
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
static int update_cmd_process(uint8_t cmd, void* frame, int len, void* pload, int size)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
switch (cmd) {
|
||||
case 0x81: {
|
||||
update_on_start(frame, len, pload, size);
|
||||
|
||||
res = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int update_process(void* frame, int len)
|
||||
{
|
||||
uint8_t cmd = 0;
|
||||
|
||||
uint8_t slave_addr = 0;
|
||||
|
||||
uint8_t user_data[256] = {0};
|
||||
|
||||
int user_data_len = 0;
|
||||
|
||||
int res = update_unpack(frame, len, &cmd, &slave_addr, user_data, &user_data_len);
|
||||
|
||||
if (res != 0)
|
||||
return -1;
|
||||
|
||||
if (slave_addr != 0x01)
|
||||
return -2;
|
||||
|
||||
res = update_cmd_process(cmd, frame, len, user_data, user_data_len);
|
||||
|
||||
if (res != 0)
|
||||
return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: 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 = 0x7C;
|
||||
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 == true) { //使用内置通讯单元
|
||||
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, &SCPara->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_NUM_MAX) {
|
||||
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].RegFlag &&
|
||||
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][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][0],
|
||||
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][1],
|
||||
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][2],
|
||||
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][3],
|
||||
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][4],
|
||||
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][5]);
|
||||
CommUnitCmdSend(GateWay, GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0], 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->UpgradeEnable == true) { //升级
|
||||
update_process(RxBuffTemp,RxLenTemp);
|
||||
}
|
||||
else if(RxBuffTemp[0] == 0x7A && RS485Ch->CommUnitEnable == true) { //内置通讯单元数据解析
|
||||
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 == true) {
|
||||
//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, &SCPara->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[0], 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);
|
||||
if(RS485Ch->CommUnitEnable == true) {
|
||||
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;
|
||||
|
||||
|
||||
update_init(RS485Ch1UartSend);
|
||||
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);
|
||||
if(RS485Ch->CommUnitEnable == true) {
|
||||
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
|
||||
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
数据通信任务
|
||||
*/
|
||||
#include "bsp.h"
|
||||
|
||||
#include "ringbuffer.h"
|
||||
#include "protocol.h"
|
||||
#include "update_protocol.h"
|
||||
|
||||
#include "app_comm.h"
|
||||
#include "app_tp_collect.h"
|
||||
#include "app_ad_collect.h"
|
||||
|
||||
#define USING_SIMULATOR ( 0 )
|
||||
|
||||
#define COMM_RECV_OUTTIME (20)
|
||||
|
||||
static struct {
|
||||
ring_buf_t rb;
|
||||
uint8_t rb_pool[128];
|
||||
} g_comm;
|
||||
|
||||
static struct {
|
||||
uint8_t rxbuf[256];
|
||||
int rxbytes;
|
||||
} g_frame;
|
||||
|
||||
static void rs485_rx_cb(uint8_t data)
|
||||
{
|
||||
ring_buf_put(&g_comm.rb, &data, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
返回值:成功:len,失败: 0
|
||||
***/
|
||||
static int recive_frame(void)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
int len = ring_buf_len(&g_comm.rb);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
if (g_frame.rxbytes < sizeof(g_frame.rxbuf)) {
|
||||
|
||||
int byte = ring_buf_get(&g_comm.rb, &data, 1);
|
||||
|
||||
if (byte > 0) {
|
||||
|
||||
g_frame.rxbuf[ g_frame.rxbytes] = data;
|
||||
|
||||
g_frame.rxbytes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void update_on_start(uint8_t* frame, int len, uint8_t* pload, int size)
|
||||
{
|
||||
update_protocol_req_t* pReq = (void*)&frame[sizeof(update_protocol_hd_t)];
|
||||
|
||||
boot_para_t cfg = {0};
|
||||
|
||||
cfg.AppFlag = 0;
|
||||
cfg.UpdateFlag = APP_UPDATE_FLAG;
|
||||
cfg.Crc32Check = pReq->AppCrc32;
|
||||
cfg.PackageNum = pReq->PackageNum;
|
||||
cfg.AppSize = pReq->AppSize;
|
||||
|
||||
dev_boot_write_param(cfg);
|
||||
|
||||
update_send_cmd(0x01, 1, pReq->PackageNum);
|
||||
|
||||
//重启进入BOOT
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
static int update_cmd_process(uint8_t cmd, void* frame, int len, void* pload, int size)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
switch (cmd) {
|
||||
case 0x81: {
|
||||
update_on_start(frame, len, pload, size);
|
||||
|
||||
res = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int update_process(void* frame, int len)
|
||||
{
|
||||
uint8_t cmd = 0;
|
||||
|
||||
uint8_t slave_addr = 0;
|
||||
|
||||
uint8_t user_data[256] = {0};
|
||||
|
||||
int user_data_len = 0;
|
||||
|
||||
int res = update_unpack(frame, len, &cmd, &slave_addr, user_data, &user_data_len);
|
||||
|
||||
if (res != 0)
|
||||
return -1;
|
||||
|
||||
if (slave_addr != 0x01)
|
||||
return -2;
|
||||
|
||||
res = update_cmd_process(cmd, frame, len, user_data, user_data_len);
|
||||
|
||||
if (res != 0)
|
||||
return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void comm_rsp(uint8_t slave_addr,uint8_t frame_cmd,void *pay, int len)
|
||||
{
|
||||
uint8_t frame_ack[128] = {0};
|
||||
|
||||
uint16_t frame_ack_len = 0;
|
||||
|
||||
protocol_pack_frame(slave_addr, frame_cmd - 0x80, pay, len, frame_ack, sizeof(frame_ack), &frame_ack_len);
|
||||
|
||||
dev_rs485_send(frame_ack, frame_ack_len);
|
||||
}
|
||||
|
||||
static void comm_process(uint8_t* frame, int len)
|
||||
{
|
||||
uint16_t slave_addr = 0;
|
||||
uint8_t frame_cmd = 0;
|
||||
uint8_t frame_data[64] = {0};
|
||||
uint16_t frame_data_len = 0;
|
||||
|
||||
/***数据解码***/
|
||||
int err = -1;
|
||||
|
||||
err= protocol_unpack_frame(frame, len, &slave_addr, &frame_cmd, frame_data, &frame_data_len);
|
||||
|
||||
if (err != PROTOCOL_SUCCESS)
|
||||
return ;
|
||||
|
||||
//TODO:获取本机地址
|
||||
uint8_t local_addr = 0;
|
||||
dev_cfg_get_devid(&local_addr);
|
||||
|
||||
|
||||
uint8_t rsp_data[64] = {0};
|
||||
void* payload = rsp_data;
|
||||
uint16_t payload_len = 0;
|
||||
|
||||
uint8_t is_match =1;
|
||||
|
||||
switch (frame_cmd) {
|
||||
|
||||
case PROTOCOL_CMD_SET_ID: {
|
||||
|
||||
//
|
||||
if (slave_addr != local_addr)
|
||||
return ;
|
||||
|
||||
id_data_t data = {0};
|
||||
|
||||
memcpy(&data, &frame_data, sizeof(data));
|
||||
|
||||
dev_cfg_set_devid(data.id);
|
||||
|
||||
BSP_LOG("set: device id =[%d] =[0x%x] \n", data.id,data.id);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROTOCOL_CMD_GET_ID:{
|
||||
|
||||
id_data_t id_data = {0};
|
||||
|
||||
id_data.id = local_addr;
|
||||
|
||||
payload_len = sizeof(id_data);
|
||||
|
||||
memcpy(payload ,&id_data,payload_len);
|
||||
|
||||
BSP_LOG("get: device id =[%d] =[0x%x] \n", id_data.id,id_data.id);
|
||||
|
||||
}break;
|
||||
|
||||
|
||||
case PROTOCOL_CMD_GET_TP: {
|
||||
//TODO: get tp datas
|
||||
if (slave_addr != local_addr)
|
||||
return ;
|
||||
|
||||
tp_datas_t tp_data = {0};
|
||||
|
||||
collect_tp_info_t tp_info={0};
|
||||
|
||||
app_collect_tp_get(&tp_info);
|
||||
|
||||
memcpy( &tp_data,&tp_info.tp_datas,sizeof(tp_data));
|
||||
|
||||
//兼容旧协议,没有用到的通道,填充无效数据
|
||||
for(int i=0; i <8-TP_SENSOR_NUM; i++){
|
||||
|
||||
tp_data.channels[i+TP_SENSOR_NUM].status =1;
|
||||
tp_data.channels[i+TP_SENSOR_NUM].value =0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < TP_SENSOR_NUM ; i++) {
|
||||
|
||||
char strbuf[128]={0};
|
||||
|
||||
snprintf(strbuf,sizeof(strbuf)," comm ad ch[%d] %08.4f \r\n", i, tp_data.channels[i].value);
|
||||
|
||||
BSP_LOG("%s",strbuf);
|
||||
}
|
||||
|
||||
BSP_LOG("\r\n");
|
||||
|
||||
payload_len = sizeof(tp_data);
|
||||
|
||||
memcpy(payload, &tp_data, payload_len);
|
||||
|
||||
}break;
|
||||
|
||||
case PROTOCOL_CMD_GET_AD: {
|
||||
|
||||
//
|
||||
if (slave_addr != local_addr)
|
||||
return ;
|
||||
|
||||
//TODO: get ad datas
|
||||
ad_datas_t ad_data = {0};
|
||||
|
||||
app_collect_ad_get(&ad_data);
|
||||
|
||||
//兼容旧协议,没有用到的通道,填充无效数据
|
||||
for(int i=0; i <8-YB_SENSOR_NUM; i++){
|
||||
|
||||
ad_data.channels[i+5].status =1;
|
||||
}
|
||||
|
||||
BSP_LOG("\r\n");
|
||||
|
||||
for (int i = 0; i < YB_SENSOR_NUM ; i++) {
|
||||
|
||||
char strbuf[128] = {0};
|
||||
|
||||
snprintf(strbuf, sizeof(strbuf), " comm ad ch[%d] %08.4f \r\n", i, ad_data.channels[i].value);
|
||||
|
||||
BSP_LOG("%s", strbuf);
|
||||
}
|
||||
|
||||
BSP_LOG("\r\n");
|
||||
|
||||
payload_len = sizeof(ad_data);
|
||||
|
||||
memcpy(payload, &ad_data, payload_len);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PROTOCOL_CMD_SET_TP_OFFSET:{
|
||||
|
||||
if (slave_addr != local_addr)
|
||||
return ;
|
||||
|
||||
offset_set_data_t offset_data={0};
|
||||
|
||||
memcpy( &offset_data,frame_data,sizeof(offset_data));
|
||||
|
||||
dev_cfg_set_temp_offset(offset_data.id, offset_data.prams.value);
|
||||
|
||||
char strbuf[128]={0};
|
||||
|
||||
snprintf(strbuf,sizeof(strbuf)," set[%d] offset %.2f \r\n", offset_data.id , offset_data.prams.value);
|
||||
|
||||
BSP_LOG("%s",strbuf);
|
||||
|
||||
}break;
|
||||
|
||||
|
||||
case PROTOCOL_CMD_GET_TP_OFFSET:{
|
||||
|
||||
//
|
||||
if (slave_addr != local_addr)
|
||||
return ;
|
||||
|
||||
offset_get_param_t *param = (void *)frame_data;
|
||||
|
||||
offset_get_data_t offset_data={0};
|
||||
|
||||
float val = 200;
|
||||
|
||||
dev_cfg_get_temp_offset( param->id,&val);
|
||||
|
||||
offset_data.id = param->id;
|
||||
|
||||
offset_data.prams.value = val;
|
||||
|
||||
payload_len = sizeof(offset_data);
|
||||
|
||||
memcpy(payload,&offset_data,payload_len);
|
||||
|
||||
char strbuf[128]={0};
|
||||
|
||||
snprintf(strbuf,sizeof(strbuf)," get[%d] offset %.2f \r\n", offset_data.id , offset_data.prams.value);
|
||||
|
||||
BSP_LOG("%s",strbuf);
|
||||
|
||||
|
||||
}break;
|
||||
|
||||
case PROTOCOL_CMD_RESET_CHANNEL: {
|
||||
//
|
||||
if (slave_addr != local_addr)
|
||||
return ;
|
||||
|
||||
app_collect_ad_reset_offset();
|
||||
|
||||
BSP_LOG("reset offset start");
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
is_match =0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(is_match ==0)
|
||||
return;
|
||||
|
||||
comm_rsp(slave_addr,frame_cmd, payload, payload_len);
|
||||
}
|
||||
|
||||
|
||||
void app_comm_entry(void *param)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
dev_rs485_init();
|
||||
|
||||
dev_rs485_rx_register(rs485_rx_cb);
|
||||
|
||||
ring_buf_init(&g_comm.rb, g_comm.rb_pool, sizeof(g_comm.rb_pool));
|
||||
|
||||
/***/
|
||||
update_init(dev_rs485_send);
|
||||
|
||||
while (1) {
|
||||
|
||||
rt_thread_mdelay(1);
|
||||
|
||||
len = recive_frame();
|
||||
|
||||
if (len == 0) {
|
||||
|
||||
rt_thread_mdelay(5);
|
||||
|
||||
len = recive_frame();
|
||||
|
||||
if (len == 0) {
|
||||
|
||||
if (g_frame.rxbytes > 0) {
|
||||
|
||||
update_process(g_frame.rxbuf, g_frame.rxbytes);
|
||||
|
||||
comm_process(g_frame.rxbuf, g_frame.rxbytes);
|
||||
|
||||
g_frame.rxbytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ALIGN(RT_ALIGN_SIZE)
|
||||
static uint8_t comm_thd_stack[4096];
|
||||
static struct rt_thread comm_thd;
|
||||
|
||||
int app_comm_init(void)
|
||||
{
|
||||
|
||||
#if USING_SIMULATOR
|
||||
BSP_LOG("comm data using simulator \n");
|
||||
#endif
|
||||
|
||||
int ret = rt_thread_init(&comm_thd,
|
||||
"app_comm",
|
||||
app_comm_entry,
|
||||
RT_NULL,
|
||||
comm_thd_stack,
|
||||
sizeof(comm_thd_stack),
|
||||
10,
|
||||
20
|
||||
);
|
||||
|
||||
|
||||
if(ret == RT_EOK){
|
||||
|
||||
rt_thread_startup(&comm_thd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_APP_EXPORT(app_comm_init);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,645 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "main.h"
|
||||
#include "CatOneTask.h"
|
||||
#include "LoraTask.h"
|
||||
#include "CatOneTask.h"
|
||||
#include "RS485Task.h"
|
||||
#include "DebugCmd.h"
|
||||
#include "spiflash.h"
|
||||
|
||||
|
||||
//雅下: 81-00-00-06-00-01
|
||||
// 81-00-00-06-00-02
|
||||
// 81-00-00-06-00-03
|
||||
// 81-00-00-06-00-04
|
||||
// 81-00-00-06-00-05
|
||||
// 81-00-00-06-00-06
|
||||
// 81-00-00-06-00-07
|
||||
// 81-00-00-06-00-08
|
||||
// 81-00-00-06-00-09
|
||||
// 81-00-00-06-00-0A
|
||||
|
||||
static const uint8_t GateWayMac_Test[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x00};
|
||||
static const uint8_t GateWayMac_BL1[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x01};
|
||||
static const uint8_t GateWayMac_BL2[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x02};
|
||||
static const uint8_t GateWayMac_BL3[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x03};
|
||||
static const uint8_t GateWayMac_BL4[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x04};
|
||||
static const uint8_t GateWayMac_BL5[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x05};
|
||||
static const uint8_t GateWayMac_BL6[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x06};
|
||||
static const uint8_t GateWayMac_BL7[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x07};
|
||||
static const uint8_t GateWayMac_BL8[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x08};
|
||||
static const uint8_t GateWayMac_BL9[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x09};
|
||||
static const uint8_t GateWayMac_BL10[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x0A};
|
||||
bool MainDispEn = true;
|
||||
|
||||
static rt_thread_t Lora_Thread = RT_NULL;
|
||||
static rt_thread_t Cat1Eth_Thread = RT_NULL;
|
||||
static rt_thread_t RS485Ch1_Thread = RT_NULL;
|
||||
static rt_thread_t RS485Ch2_Thread = RT_NULL;
|
||||
static rt_thread_t Debug_Thread = RT_NULL;
|
||||
|
||||
GateWayPara_t GateWay;
|
||||
|
||||
#define ARRAY_DIM(a) (sizeof(a) / sizeof((a)[0]))
|
||||
//static int Battery_Level_Percent_Table[11] = {3000, 3650, 3700, 3740, 3760, 3795, 3840, 3910, 3980, 4070, 4150};
|
||||
static int Battery_Level_Percent_Table[11] = {6000, 7300, 7400, 7480, 7520, 7590, 7680, 7820, 7960, 8140, 8300};
|
||||
int toPercentage(int voltage)
|
||||
{
|
||||
int i;
|
||||
if(voltage < Battery_Level_Percent_Table[0])
|
||||
return 0;
|
||||
|
||||
for(i = 0; i<ARRAY_DIM(Battery_Level_Percent_Table); i++){
|
||||
if(voltage < Battery_Level_Percent_Table[i])
|
||||
return i*10 - (10UL * (int)(Battery_Level_Percent_Table[i] - voltage)) /
|
||||
(int)(Battery_Level_Percent_Table[i] - Battery_Level_Percent_Table[i-1]);;
|
||||
}
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: MainDBGOnOff
|
||||
* 功能描述: 主调试信息开关函数
|
||||
* 参 数: OnOff,开关
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
void MainDBGOnOff(bool OnOff)
|
||||
{
|
||||
MainDispEn = OnOff;
|
||||
if(OnOff)
|
||||
Debug_Printf("\r\nMain Display Enable!\r\n\r\n");
|
||||
else
|
||||
Debug_Printf("\r\nMain Display Disable!\r\n\r\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
uint32_t SDStartBlock;
|
||||
uint8_t TestData[10 * 512];
|
||||
uint8_t ADBuff[10 * 512];
|
||||
|
||||
void SDCardTest(void)
|
||||
{
|
||||
SDStartBlock = 0;
|
||||
SDCardReadBlocks(SDStartBlock, 10, TestData);
|
||||
if(TestData[0] != 0xAA) {
|
||||
SDCardErase(SDStartBlock, 10);
|
||||
memset(ADBuff, 0xAA, 10 * 512);
|
||||
SDCardWriteBlocks(SDStartBlock, 10, (uint8_t *)&ADBuff);
|
||||
}
|
||||
SDCardReadBlocks(SDStartBlock, 10, TestData);
|
||||
}
|
||||
#endif
|
||||
|
||||
void InfTest(void)
|
||||
{
|
||||
uint8_t sData[10] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A};
|
||||
RS485_CH1_RX();
|
||||
RS485_CH1_POW_ON();
|
||||
rt_thread_delay(100);
|
||||
RS485_CH1_POW_OFF();
|
||||
|
||||
RS485_CH2_POW_ON();
|
||||
rt_thread_delay(100);
|
||||
RS485_CH2_POW_OFF();
|
||||
|
||||
POWER_LED_OFF();
|
||||
POWER_LED_ON();
|
||||
LORA_RX_LED_SET();
|
||||
LORA_RX_LED_CLR();
|
||||
RS485_CH1_TX();
|
||||
RS485_CH2_RX();
|
||||
RS485Ch1_Config(500000);
|
||||
RS485Ch2_Config(500000);
|
||||
RS485Ch1UartSend(sData, 10);
|
||||
rt_thread_delay(100);
|
||||
|
||||
RS485_CH2_TX();
|
||||
RS485_CH1_RX();
|
||||
RS485Ch2UartSend(sData, 10);
|
||||
rt_thread_delay(100);
|
||||
// SDCardTest();
|
||||
}
|
||||
|
||||
void GateWayInit(void)
|
||||
{
|
||||
LogHeader_t Header;
|
||||
uint32_t FlashID = SpiFlashReadId();
|
||||
Debug_Printf("FlashID: %08x\r\n", FlashID);
|
||||
|
||||
memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
|
||||
int ret = ReadPara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
if(GateWay.ConfigPara.SavFlag != LOG_SAV_FLAG) {
|
||||
memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
|
||||
GateWay.ConfigPara.SavFlag = LOG_SAV_FLAG;
|
||||
GateWay.ConfigPara.Comm = CATONE_COMM;
|
||||
// memcpy(GateWay.ConfigPara.GwMac, GateWayMac, 6);
|
||||
GateWay.ConfigPara.SvrAddr[0] = 8;
|
||||
GateWay.ConfigPara.SvrAddr[1] = 137;
|
||||
GateWay.ConfigPara.SvrAddr[2] = 104;
|
||||
GateWay.ConfigPara.SvrAddr[3] = 4;
|
||||
GateWay.ConfigPara.SvrPort = 8007;
|
||||
GateWay.ConfigPara.CommUnitReadInterval = COMMUNIT_READ_SENSOR_INTERVAL_MAX;
|
||||
memset(GateWay.ConfigPara.CommUnitArray, 0x00, sizeof(CommUnitData_t) * COMMUNIT_NUM_MAX);
|
||||
GateWay.ConfigPara.Rs485Ch1.Enable = true;
|
||||
GateWay.ConfigPara.Rs485Ch1.CommUnitEnable = false;
|
||||
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
|
||||
GateWay.ConfigPara.Rs485Ch1.UpgradeEnable = true;
|
||||
GateWay.ConfigPara.Rs485Ch1.Power = false;
|
||||
GateWay.ConfigPara.Rs485Ch2.Enable = true;
|
||||
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
|
||||
GateWay.ConfigPara.Rs485Ch2.UpgradeEnable = false;
|
||||
GateWay.ConfigPara.Rs485Ch2.CommUnitEnable = false;
|
||||
GateWay.ConfigPara.Rs485Ch2.Power = true;
|
||||
|
||||
GateWay.ConfigPara.Lora.OnOff = true;
|
||||
GateWay.ConfigPara.Lora.ucChannel = 8;
|
||||
GateWay.ConfigPara.Lora.ucPower = 20;
|
||||
GateWay.ConfigPara.Lora.SignalBw = 8;
|
||||
GateWay.ConfigPara.Lora.SpreadFactor = 9;
|
||||
GateWay.ConfigPara.Lora.ErrorCoding = 2;
|
||||
GateWay.ConfigPara.Lora.RegPreamble = 10;
|
||||
GateWay.ConfigPara.Lora.FreqCent = FREQ_CENT;
|
||||
GateWay.ConfigPara.OutageFlag = false;
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
}
|
||||
|
||||
if(GateWay.ConfigPara.OutageFlag != true && GateWay.ConfigPara.OutageFlag != false)
|
||||
GateWay.ConfigPara.OutageFlag = false;
|
||||
|
||||
GateWay.SvrRegFlag = false;
|
||||
memset(GateWay.SvrMac, 0x00, 6);
|
||||
GateWay.ConfigPara.Rs485Ch1.RS485Send = RS485Ch1UartSend;
|
||||
GateWay.ConfigPara.Rs485Ch2.RS485Send = RS485Ch2UartSend;
|
||||
|
||||
GateWay.ConfigPara.Rs485Ch1.Enable = true;
|
||||
GateWay.ConfigPara.Rs485Ch1.CommUnitEnable = false;
|
||||
GateWay.ConfigPara.Rs485Ch1.UpgradeEnable = true;
|
||||
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
|
||||
GateWay.ConfigPara.Rs485Ch1.Power = false;
|
||||
GateWay.ConfigPara.Rs485Ch2.Enable = true;
|
||||
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
|
||||
GateWay.ConfigPara.Rs485Ch2.CommUnitEnable = false;
|
||||
GateWay.ConfigPara.Rs485Ch2.UpgradeEnable = false;
|
||||
GateWay.ConfigPara.Rs485Ch2.Power = false;
|
||||
|
||||
GateWay.ConfigPara.Lora.OnOff = true;
|
||||
GateWay.ConfigPara.Lora.ucChannel = 8;
|
||||
GateWay.ConfigPara.Lora.ucPower = 20;
|
||||
GateWay.ConfigPara.Lora.SignalBw = 8;
|
||||
GateWay.ConfigPara.Lora.SpreadFactor = 9;
|
||||
GateWay.ConfigPara.Lora.ErrorCoding = 2;
|
||||
GateWay.ConfigPara.Lora.RegPreamble = 10;
|
||||
GateWay.ConfigPara.Lora.FreqCent = FREQ_CENT;
|
||||
|
||||
#if MAC_ADDR_TYPE == 0
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_Test, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_DBG;
|
||||
#elif MAC_ADDR_TYPE == 1
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL1, 6);
|
||||
//GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_DBG;
|
||||
#elif MAC_ADDR_TYPE == 2
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL2, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
//GateWay.ConfigPara.DebugChannel = DEBUG_CH_DBG;
|
||||
#elif MAC_ADDR_TYPE == 3
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL3, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 4
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL4, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 5
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL5, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 6
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL6, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 7
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL7, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 8
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL8, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 9
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL9, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#elif MAC_ADDR_TYPE == 10
|
||||
memcpy(GateWay.ConfigPara.GwMac, GateWayMac_BL10, 6);
|
||||
GateWay.ConfigPara.DebugChannel = DEBUG_CH_RS485_1;
|
||||
#endif
|
||||
|
||||
#if MAC_ADDR_TYPE == 0//测试服务器
|
||||
GateWay.ConfigPara.SvrAddr[0] = 39;
|
||||
GateWay.ConfigPara.SvrAddr[1] = 106;
|
||||
GateWay.ConfigPara.SvrAddr[2] = 103;
|
||||
GateWay.ConfigPara.SvrAddr[3] = 147;
|
||||
GateWay.ConfigPara.SvrPort = 8080;
|
||||
#elif MAC_ADDR_TYPE > 0
|
||||
// GateWay.ConfigPara.SvrAddr[0] = 39;
|
||||
// GateWay.ConfigPara.SvrAddr[1] = 106;
|
||||
// GateWay.ConfigPara.SvrAddr[2] = 103;
|
||||
// GateWay.ConfigPara.SvrAddr[3] = 147;
|
||||
// GateWay.ConfigPara.SvrPort = 8080;
|
||||
GateWay.ConfigPara.SvrAddr[0] = 103;
|
||||
GateWay.ConfigPara.SvrAddr[1] = 217;
|
||||
GateWay.ConfigPara.SvrAddr[2] = 192;
|
||||
GateWay.ConfigPara.SvrAddr[3] = 248;
|
||||
GateWay.ConfigPara.SvrPort = 12111;
|
||||
#endif
|
||||
|
||||
if(GateWay.ConfigPara.DebugChannel == DEBUG_CH_RS485_1) {
|
||||
GateWay.ConfigPara.Rs485Ch1.Enable = true;
|
||||
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
|
||||
}
|
||||
if(GateWay.ConfigPara.Rs485Ch1.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch1.BaudRate > 921600)
|
||||
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
|
||||
RS485Ch1_Config(GateWay.ConfigPara.Rs485Ch1.BaudRate);
|
||||
|
||||
if(GateWay.ConfigPara.DebugChannel == DEBUG_CH_RS485_2) {
|
||||
GateWay.ConfigPara.Rs485Ch2.Enable = true;
|
||||
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
|
||||
}
|
||||
if(GateWay.ConfigPara.Rs485Ch2.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch2.BaudRate > 921600)
|
||||
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
|
||||
RS485Ch2_Config(GateWay.ConfigPara.Rs485Ch2.BaudRate);
|
||||
|
||||
if(GateWay.ConfigPara.Rs485Ch1.Power)
|
||||
RS485_CH1_POW_ON();
|
||||
else
|
||||
RS485_CH1_POW_OFF();
|
||||
|
||||
if(GateWay.ConfigPara.Rs485Ch2.Power) {
|
||||
RS485_CH2_POW_OFF();
|
||||
rt_thread_delay(1000);
|
||||
RS485_CH2_POW_ON();
|
||||
}
|
||||
else
|
||||
RS485_CH2_POW_OFF();
|
||||
|
||||
if(GateWay.ConfigPara.Lora.OnOff == true) {
|
||||
LORA_POW_ON();
|
||||
}
|
||||
else {
|
||||
LORA_POW_OFF();
|
||||
}
|
||||
if(LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel) == false) {
|
||||
GateWay.ConfigPara.Lora.ucChannel = 8;
|
||||
LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel);
|
||||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
}
|
||||
if(LoraSetPower(GateWay.ConfigPara.Lora.ucPower) == false) {
|
||||
GateWay.ConfigPara.Lora.ucPower = 20;
|
||||
LoraSetPower(GateWay.ConfigPara.Lora.ucPower);
|
||||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
}
|
||||
if(LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw) == false) {
|
||||
GateWay.ConfigPara.Lora.SignalBw = 8;
|
||||
LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw);
|
||||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
}
|
||||
if(LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor) == false) {
|
||||
GateWay.ConfigPara.Lora.SpreadFactor = 9;
|
||||
LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor);
|
||||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
}
|
||||
if(LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding) == false) {
|
||||
GateWay.ConfigPara.Lora.ErrorCoding = 2;
|
||||
LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding);
|
||||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
}
|
||||
if(GateWay.ConfigPara.Lora.RegPreamble > 0xFE) {
|
||||
GateWay.ConfigPara.Lora.RegPreamble = 10;
|
||||
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
}
|
||||
LoraSetRegPreamble(GateWay.ConfigPara.Lora.RegPreamble);
|
||||
|
||||
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
|
||||
LogInit();
|
||||
|
||||
Header.LogEndAddr = 0;
|
||||
if(ReadLogNum() > 0) {
|
||||
int ret = ReadLog(&Header, NULL, 0);
|
||||
if(ret > 0) {
|
||||
GateWay.HistoryNum = ReadLogNum() - Header.LogIdx + 1;
|
||||
rt_kprintf("History Num: %d\r\n", GateWay.HistoryNum);
|
||||
}
|
||||
else {
|
||||
rt_kprintf("History Num: 0\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
rt_kprintf("History Num: 0\r\n");
|
||||
if(GateWay.ConfigPara.Comm == CATONE_COMM) {
|
||||
CAT1_ON();
|
||||
}
|
||||
else {
|
||||
ETH_ON();
|
||||
}
|
||||
}
|
||||
|
||||
void OutageUpdate(uint8_t AlarmType, bool AlarmState, uint8_t Batt)
|
||||
{
|
||||
GateWayAlarmType_t *Alarm;
|
||||
uint8_t MegData[6],len;
|
||||
len = sizeof(GateWayAlarmType_t);
|
||||
MegData[0] = len & 0x00ff;;
|
||||
MegData[1] = (len >> 8) & 0x00ff;
|
||||
MegData[2] = NET_COMM_CMD_ALARM;
|
||||
|
||||
Alarm = (GateWayAlarmType_t *)&MegData[3];
|
||||
Alarm->AlarmType = AlarmType;
|
||||
Alarm->AlarmState = AlarmState;
|
||||
Alarm->AlarmPara = Batt;
|
||||
CatOneEthSendQueue(MegData, 6); //发送报警信息
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: main
|
||||
* 功能描述: 主函数
|
||||
* 参 数: 无
|
||||
* 返 回 值: 运行错误返回-1
|
||||
*****************************************************************************************/
|
||||
static uint8_t LastBattery = 0xff; //上一次电池电压
|
||||
int main(void)
|
||||
{
|
||||
uint16_t OneSecondDlyCnt = 0;
|
||||
// struct tm cTime;
|
||||
uint16_t PowerONLedDly = 2000;
|
||||
uint32_t SystemRseetDlyCnt = 0;
|
||||
uint32_t BatteryUpdateDlyCnt = 0;
|
||||
uint8_t AlarmType = 0;
|
||||
|
||||
GateWayInit();
|
||||
|
||||
rt_kprintf("\r\n\r\n");
|
||||
rt_kprintf("****************************************************\r\n");
|
||||
rt_kprintf("** **\r\n");
|
||||
rt_kprintf("** GateWay **\r\n");
|
||||
rt_kprintf("** SoftWare V%d.%d **\r\n", SOFTWARE_VERSION / 10, SOFTWARE_VERSION % 10);
|
||||
rt_kprintf("** HardWare V%d.%d **\r\n", HARDWARE_VERSION / 10, HARDWARE_VERSION % 10);
|
||||
rt_kprintf("** Compile: %s %s **\r\n", __DATE__, __TIME__);
|
||||
rt_kprintf("** **\r\n");
|
||||
rt_kprintf("****************************************************\r\n\r\n");
|
||||
// TimeGet(&cTime);
|
||||
// TimeShow(TimeTs());
|
||||
FeedDog();
|
||||
//rt_thread_delay(500);
|
||||
//InfTest();
|
||||
//FeedDog();
|
||||
|
||||
//Cat1DBGOnOff(true);
|
||||
|
||||
|
||||
GateWay.CommUnitRevCallBack = CommUnitAnalyze;
|
||||
GateWay.SvrRevCallBack = Cat1EthRevCallBack;
|
||||
|
||||
GateWay.NetSendData_MQ = rt_mq_create("NetSendMQ", 512, 10, RT_IPC_FLAG_FIFO);
|
||||
if(GateWay.NetSendData_MQ == RT_NULL) {
|
||||
rt_kprintf("CatOne MQ Create Failed!\r\n");
|
||||
}
|
||||
|
||||
GateWay.LoraRev_MQ = rt_mq_create("LoraRevMQ", 256, 10, RT_IPC_FLAG_FIFO);
|
||||
if(GateWay.LoraRev_MQ == RT_NULL) {
|
||||
rt_kprintf("LoraRev MQ Create Failed!\r\n");
|
||||
}
|
||||
|
||||
GateWay.UartRevMutex = rt_mutex_create("urmutex", RT_IPC_FLAG_FIFO);
|
||||
if(GateWay.UartRevMutex == RT_NULL) {
|
||||
rt_kprintf("UR Mutex Create Failed!\r\n");
|
||||
}
|
||||
|
||||
GateWay.SvrRevCallBack = Cat1EthRevCallBack;
|
||||
|
||||
RS485Ch1_Thread = rt_thread_create("RS485Ch1", RS485Ch1_Thread_Entry, &GateWay, 2048, 3, 20);
|
||||
if (RS485Ch1_Thread != RT_NULL)
|
||||
rt_thread_startup(RS485Ch1_Thread);
|
||||
else
|
||||
return -1;
|
||||
|
||||
RS485Ch2_Thread = rt_thread_create("RS485Ch2", RS485Ch2_Thread_Entry, &GateWay, 2048, 3, 20);
|
||||
if (RS485Ch2_Thread != RT_NULL)
|
||||
rt_thread_startup(RS485Ch2_Thread);
|
||||
else
|
||||
return -1;
|
||||
|
||||
Debug_Thread = rt_thread_create("DebugUart", Debug_Thread_Entry, &GateWay, 2048, 3, 20);
|
||||
if (RS485Ch2_Thread != RT_NULL)
|
||||
rt_thread_startup(Debug_Thread);
|
||||
else
|
||||
return -1;
|
||||
|
||||
Cat1Eth_Thread = rt_thread_create("Cat1Eth", CatOne_Eth_Thread_Entry, &GateWay, 4096, 3, 20);
|
||||
if (Cat1Eth_Thread != RT_NULL)
|
||||
rt_thread_startup(Cat1Eth_Thread);
|
||||
else
|
||||
return -1;
|
||||
|
||||
Lora_Thread = rt_thread_create("Lora", Lora_Thread_Entry, &GateWay, 1024, 3, 20);
|
||||
if (Lora_Thread != RT_NULL)
|
||||
rt_thread_startup(Lora_Thread);
|
||||
else
|
||||
return -1;
|
||||
|
||||
while(1) {
|
||||
if(PowerONLedDly > 0) {
|
||||
PowerONLedDly--;
|
||||
if(PowerONLedDly == 1) {
|
||||
POWER_LED_OFF();
|
||||
}
|
||||
}
|
||||
EthRxOverhandler();
|
||||
RS485RxOverhandler();
|
||||
DebugRxOverhandler();
|
||||
if(OneSecondDlyCnt % 200 == 0) {
|
||||
FeedDog();
|
||||
LORA_RX_TOGGLE();
|
||||
POWER_TOGGLE();
|
||||
}
|
||||
OneSecondDlyCnt++;
|
||||
if(OneSecondDlyCnt == 1000) {
|
||||
OneSecondDlyCnt = 0;
|
||||
|
||||
if(GateWay.BatteryReadDlyCnt > 0) {
|
||||
GateWay.BatteryReadDlyCnt--;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16_t ADValue = GetADCBuffPoint();
|
||||
//V = (AD * 3.3 / 4096) * (R1+R2) / R1; R1 = 200, R2 = 120
|
||||
//计算出常数为0.0021484375,扩大1000倍
|
||||
float Voltage = ADValue * 2.1484375;
|
||||
GateWay.Battery = toPercentage(Voltage);
|
||||
|
||||
//上电判断电量
|
||||
if(LastBattery == 0xff) {
|
||||
LastBattery = GateWay.Battery;
|
||||
|
||||
if(GateWay.ConfigPara.OutageFlag == true) { //有报警
|
||||
AlarmType = 1;
|
||||
}
|
||||
else {
|
||||
AlarmType = 0;
|
||||
}
|
||||
//BatteryUpdateDlyCnt = 2 * 60;
|
||||
BatteryUpdateDlyCnt = 10;
|
||||
}
|
||||
else {
|
||||
if(GateWay.ConfigPara.OutageFlag == false) { //没有告警,判断电池电压是否降低
|
||||
if(GateWay.Battery <= LastBattery) {
|
||||
if(LastBattery <= 5) {
|
||||
GateWay.ConfigPara.OutageFlag = true;
|
||||
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
Debug_Printf("The power is cutted.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
|
||||
LastBattery = GateWay.Battery;
|
||||
AlarmType = 1;
|
||||
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
|
||||
BatteryUpdateDlyCnt = 20 * 60;
|
||||
}
|
||||
else if((LastBattery - GateWay.Battery) > 2) {
|
||||
GateWay.ConfigPara.OutageFlag = true;
|
||||
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
LastBattery = GateWay.Battery;
|
||||
AlarmType = 1;
|
||||
Debug_Printf("The power is cutted.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
|
||||
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
|
||||
BatteryUpdateDlyCnt = 20 * 60;
|
||||
}
|
||||
}
|
||||
else { //充电,更新上一次电池电压
|
||||
LastBattery = GateWay.Battery;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(GateWay.Battery >= LastBattery) {
|
||||
if(LastBattery > 95) {
|
||||
GateWay.ConfigPara.OutageFlag = false;
|
||||
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
Debug_Printf("The power is restored.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
|
||||
LastBattery = GateWay.Battery;
|
||||
AlarmType = 1;
|
||||
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
|
||||
BatteryUpdateDlyCnt = 90 * 60;
|
||||
AlarmType = 0;
|
||||
}
|
||||
else if(GateWay.Battery - LastBattery > 5) {
|
||||
GateWay.ConfigPara.OutageFlag = false;
|
||||
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
|
||||
Debug_Printf("The power is restored.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
|
||||
LastBattery = GateWay.Battery;
|
||||
AlarmType = 1;
|
||||
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
|
||||
BatteryUpdateDlyCnt = 90 * 60;
|
||||
AlarmType = 0;
|
||||
}
|
||||
}
|
||||
else { //电池继续放电,更新上一次电池电压
|
||||
LastBattery = GateWay.Battery;
|
||||
}
|
||||
}
|
||||
}
|
||||
BatteryUpdateDlyCnt--;
|
||||
if(BatteryUpdateDlyCnt == 0) {
|
||||
if(GateWay.ConfigPara.OutageFlag) { //有报警
|
||||
BatteryUpdateDlyCnt = 20 * 60;
|
||||
}
|
||||
else {
|
||||
BatteryUpdateDlyCnt = 90 * 60;
|
||||
}
|
||||
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
|
||||
}
|
||||
//ADC_Start();
|
||||
}
|
||||
SystemRseetDlyCnt++;
|
||||
if(SystemRseetDlyCnt > (24 * 60 * 60 * 1000)) {
|
||||
SystemRseetDlyCnt = 0;
|
||||
Debug_Printf("The system resets periodically.\r\n");
|
||||
rt_thread_delay(10);
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
rt_thread_delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static FATFS SDFatFs;
|
||||
static FIL TestFile;
|
||||
static uint8_t u8WorkBuffer[FF_MAX_SS];
|
||||
|
||||
void FSInit(void)
|
||||
{
|
||||
FRESULT fRet;
|
||||
uint32_t u32WBNbr, u32RBNbr;
|
||||
char SDPath[] = "1:";
|
||||
MKFS_PARM opt;
|
||||
uint8_t u8ReadText[100];
|
||||
en_result_t enTestRet = Error;
|
||||
uint8_t u8WriteText[] = "This is a string used to test the FatFs";
|
||||
|
||||
if (FR_OK != f_mount(&SDFatFs, (TCHAR const*)SDPath, 0U)) {
|
||||
rt_kprintf("FatFs Initialization Error!\r\n");
|
||||
}
|
||||
else {
|
||||
memset(&opt, 0, sizeof(MKFS_PARM));
|
||||
opt.fmt = (BYTE)FM_FAT32;
|
||||
/* Create a FAT file system (format) on the logical drive */
|
||||
if (FR_OK != f_mkfs((TCHAR const*)SDPath, &opt, u8WorkBuffer, sizeof(u8WorkBuffer))) {
|
||||
rt_kprintf("FatFs Format Error!\r\n");
|
||||
}
|
||||
else {
|
||||
/* Create and Open a new text file object with write access */
|
||||
if (FR_OK != f_open(&TestFile, "1:Test.txt", ((BYTE)FA_CREATE_ALWAYS | (BYTE)FA_WRITE))) {
|
||||
rt_kprintf("\"Test.txt\" file Open for write Error!\r\n");
|
||||
}
|
||||
else {
|
||||
/* Write data to the text file */
|
||||
fRet = f_write(&TestFile, u8WriteText, sizeof(u8WriteText), (void *)&u32WBNbr);
|
||||
if ((0UL == u32WBNbr) || (FR_OK != fRet)) {
|
||||
rt_kprintf("\"Test.txt\" file Write or EOF Error!\r\n");
|
||||
else {
|
||||
/* Close the open text file */
|
||||
f_close(&TestFile);
|
||||
/* Open the text file object with read access */
|
||||
if (FR_OK != f_open(&TestFile, "1:Test.txt", (BYTE)FA_READ)) {
|
||||
rt_kprintf("\"Test.txt\" file Open for read Error!\r\n");
|
||||
}
|
||||
else {
|
||||
memset(u8ReadText, 0, sizeof(u8ReadText));
|
||||
/* Read data from the text file */
|
||||
fRet = f_read(&TestFile, u8ReadText, sizeof(u8ReadText), (UINT*)(uint32_t)&u32RBNbr);
|
||||
if ((0UL == u32RBNbr) || (FR_OK != fRet)) {
|
||||
rt_kprintf("\"Test.txt\" file Read or EOF Error!\r\n");
|
||||
}
|
||||
else {
|
||||
/* Close the open text file */
|
||||
f_close(&TestFile);
|
||||
/* Compare read data with the expected data */
|
||||
if (u32RBNbr == u32WBNbr) {
|
||||
/* Check data value */
|
||||
if (0 == memcmp(u8WriteText, u8ReadText, u32RBNbr)) {
|
||||
enTestRet = Ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Unlink the micro SD disk I/O driver */
|
||||
f_mount(NULL, (TCHAR const*)SDPath, 0U);
|
||||
|
||||
if(enTestRet != Ok) {
|
||||
rt_kprintf("Error!\r\n");
|
||||
}
|
||||
else {
|
||||
rt_kprintf("Ok!\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "protocol.h"
|
||||
#include "string.h"
|
||||
#include "utils.h"
|
||||
|
||||
int protocol_pack_frame(
|
||||
uint16_t slave_addr,
|
||||
uint8_t command,const
|
||||
uint8_t *payload,
|
||||
uint16_t payload_len,
|
||||
uint8_t *buffer,uint16_t buffer_size,
|
||||
uint16_t *packed_len)
|
||||
{
|
||||
|
||||
// 构建基础帧头
|
||||
|
||||
buffer[0] = PROTOCOL_HEAD & 0xFF;
|
||||
buffer[1] = (PROTOCOL_HEAD >> 8) & 0xFF;
|
||||
buffer[2] = slave_addr & 0xFF;
|
||||
buffer[3] = (slave_addr >> 8) & 0xFF;
|
||||
|
||||
buffer[4] = command;
|
||||
|
||||
buffer[5] = payload_len & 0xFF;
|
||||
buffer[6] = (payload_len >> 8) & 0xFF;
|
||||
|
||||
// 复制有效载荷(保持小端格式)
|
||||
if (payload_len > 0 && payload != NULL) {
|
||||
memcpy(buffer + PROTOCOL_FRAME_HEAD_SIZE , payload, payload_len);
|
||||
}
|
||||
|
||||
// 设置实际长度
|
||||
int fram_len = PROTOCOL_FRAME_MIN_SIZE + payload_len;
|
||||
|
||||
|
||||
// 计算CRC(覆盖地址、命令、长度和有效载荷)
|
||||
uint16_t crc = 0xFFFF;
|
||||
|
||||
crc = modbus_crc16(buffer,fram_len -2);
|
||||
|
||||
// 写入CRC(保持小端格式)
|
||||
|
||||
buffer[fram_len-2] = (uint8_t)(crc & 0xFF);
|
||||
buffer[fram_len-1] = (uint8_t)(crc >> 8);
|
||||
|
||||
*packed_len =fram_len;
|
||||
|
||||
return PROTOCOL_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
int protocol_unpack_frame(
|
||||
const uint8_t *frame,
|
||||
uint16_t frame_len,
|
||||
uint16_t *slave_addr,
|
||||
uint8_t *command,
|
||||
uint8_t *payload,
|
||||
uint16_t *payload_len
|
||||
) {
|
||||
// 参数校验
|
||||
if (frame == NULL || slave_addr == NULL || command == NULL || payload_len == NULL) {
|
||||
return PROTOCOL_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (frame_len < PROTOCOL_FRAME_MIN_SIZE) {
|
||||
return PROTOCOL_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// 帧头校验
|
||||
uint16_t header = (frame[0] | frame[1] <<8);
|
||||
|
||||
if (header != PROTOCOL_HEAD) {
|
||||
|
||||
return PROTOCOL_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// 基础字段解析
|
||||
*slave_addr = (frame[2] | frame[3] << 8);
|
||||
|
||||
|
||||
*command = frame[4];
|
||||
|
||||
|
||||
*payload_len = (frame[5] | frame[6] << 8);
|
||||
|
||||
// 数据完整性校验
|
||||
if (*payload_len > (frame_len - PROTOCOL_FRAME_MIN_SIZE)) {
|
||||
|
||||
return PROTOCOL_ERR_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
int frame_size = *payload_len + 9;
|
||||
|
||||
uint16_t calc_crc =0xffff;
|
||||
|
||||
calc_crc = modbus_crc16((uint8_t *)frame, frame_size -2 );
|
||||
|
||||
// 校验CRC(保持小端格式)
|
||||
union{
|
||||
|
||||
uint16_t value;
|
||||
struct{
|
||||
uint8_t crcl;
|
||||
uint8_t crch;
|
||||
}bytes;
|
||||
|
||||
}crc_data;
|
||||
|
||||
crc_data.bytes.crcl =(frame[frame_size - 2] ) ;
|
||||
crc_data.bytes.crch =(frame[frame_size - 1] ) ;
|
||||
|
||||
if (calc_crc != crc_data.value) {
|
||||
return PROTOCOL_ERR_CRC;
|
||||
}
|
||||
|
||||
// 复制有效载荷(保持小端格式)
|
||||
if (*payload_len > 0 && payload != NULL) {
|
||||
memcpy(payload, frame + PROTOCOL_FRAME_HEAD_SIZE, *payload_len);
|
||||
}
|
||||
|
||||
return PROTOCOL_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/******************************************************************************
|
||||
* @brief 环形缓冲区管理(参考linux/kfifo)
|
||||
*
|
||||
* Copyright (c) 2016~2020, <morro_luo@163.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-05-30 Morro 初版完成
|
||||
******************************************************************************/
|
||||
#include "ringbuffer.h"
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define min(a,b) ( (a) < (b) )? (a):(b)
|
||||
|
||||
/*
|
||||
*@brief 构造一个空环形缓冲区
|
||||
*@param[in] r - 环形缓冲区管理器
|
||||
*@param[in] buf - 数据缓冲区
|
||||
*@param[in] len - buf长度(必须是2的N次幂)
|
||||
*@retval bool
|
||||
*/
|
||||
bool ring_buf_init(ring_buf_t *r,unsigned char *buf, unsigned int len)
|
||||
{
|
||||
r->buf = buf;
|
||||
r->size = len;
|
||||
r->front = r->rear = 0;
|
||||
return (buf != NULL) && ((len & len -1) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
*@brief 清空环形缓冲区
|
||||
*@param[in] r - 待清空的环形缓冲区
|
||||
*@retval none
|
||||
*/
|
||||
void ring_buf_clr(ring_buf_t *r)
|
||||
{
|
||||
r->front = r->rear = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*@brief 获取环形缓冲区数据长度
|
||||
*@retval 环形缓冲区中有效字节数
|
||||
*/
|
||||
int ring_buf_len(ring_buf_t *r)
|
||||
{
|
||||
return r->rear - r->front;
|
||||
}
|
||||
|
||||
/*
|
||||
*@brief 将指定长度的数据放到环形缓冲区中
|
||||
*@param[in] buf - 数据缓冲区
|
||||
* len - 缓冲区长度
|
||||
*@retval 实际放到中的数据
|
||||
*/
|
||||
int ring_buf_put(ring_buf_t *r,unsigned char *buf,unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int left;
|
||||
left = r->size + r->front - r->rear;
|
||||
len = min(len , left);
|
||||
i = min(len, r->size - (r->rear & r->size - 1));
|
||||
memcpy(r->buf + (r->rear & r->size - 1), buf, i);
|
||||
memcpy(r->buf, buf + i, len - i);
|
||||
r->rear += len;
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*@brief 从环形缓冲区中读取指定长度的数据
|
||||
*@param[in] len - 读取长度
|
||||
*@param[out] buf - 输出数据缓冲区
|
||||
*@retval 实际读取长度
|
||||
*/
|
||||
int ring_buf_get(ring_buf_t *r,unsigned char *buf,unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int left;
|
||||
left = r->rear - r->front;
|
||||
len = min(len , left);
|
||||
i = min(len, r->size - (r->front & r->size - 1));
|
||||
memcpy(buf, r->buf + (r->front & r->size - 1), i);
|
||||
memcpy(buf + i, r->buf, len - i);
|
||||
r->front += len;
|
||||
return len;
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
#include "spiflash.h"
|
||||
#include "rtthread.h"
|
||||
#include "DebugCmd.h"
|
||||
#include "Public.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);
|
||||
void *pTemp = rt_malloc(LogLen);
|
||||
if(pTemp == NULL)
|
||||
return 0;
|
||||
|
||||
*rData =pTemp;
|
||||
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); //读取片尾数据
|
||||
uint16_t Check = CRC_Modbus(0xA001, Para, ParaLen - 2);
|
||||
GWConfigPara CfgPara = (GWConfigPara)Para;
|
||||
if(CfgPara->crc16 != Check)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: WritePara
|
||||
* 功能描述: 写入参数
|
||||
* 参 数: Para, 网关参数
|
||||
ParaLen, 参数长度
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
int WritePara(uint8_t *Para, uint32_t ParaLen)
|
||||
{
|
||||
SpiFlashEraseSector(GATEWEY_PARA_SAV_ADDR);
|
||||
|
||||
uint16_t Check = CRC_Modbus(0xA001, Para, ParaLen - 2);
|
||||
GWConfigPara CfgPara = (GWConfigPara)Para;
|
||||
CfgPara->crc16 = Check;
|
||||
SpiFlashWriteAnyLengthData(Para, GATEWEY_PARA_SAV_ADDR, ParaLen); //读取片尾数据
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* USER CODE END */
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "update_protocol.h"
|
||||
#include "string.h"
|
||||
#include "public.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
update_send_t pfnSend;
|
||||
|
||||
}g_update_protoc;
|
||||
|
||||
|
||||
void update_send_cmd(uint8_t Cmd, uint16_t Indx, int PageNum)
|
||||
{
|
||||
uint8_t sData[24]={0};
|
||||
uint8_t sLen =0;
|
||||
uint16_t crc16;
|
||||
|
||||
update_protocol_hd_t *Frame = (update_protocol_hd_t*)sData;
|
||||
|
||||
Frame->Header = 0x7a;
|
||||
Frame->SlvAddr = 0x01;
|
||||
Frame->Cmd = Cmd;
|
||||
|
||||
if (Cmd == 0x01)
|
||||
{
|
||||
Frame->PayloadLen = 1;
|
||||
sData[sizeof(update_protocol_hd_t)] = Indx;
|
||||
}
|
||||
else if (Cmd == 0x02)
|
||||
{
|
||||
Frame->PayloadLen = 4;
|
||||
update_protocol_get_t *GDData = (update_protocol_get_t*)&sData[sizeof(update_protocol_hd_t)];
|
||||
GDData->PackageIndex = Indx;
|
||||
GDData->PackageNum = PageNum;
|
||||
}
|
||||
|
||||
sLen = sizeof(update_protocol_hd_t) + Frame->PayloadLen;
|
||||
crc16 = CRC_Modbus(CRC16_BASE, sData, sLen);
|
||||
sData[sLen++] = crc16;
|
||||
sData[sLen++] = (crc16 >> 8) & 0x00ff;
|
||||
|
||||
g_update_protoc.pfnSend(sData, sLen);
|
||||
}
|
||||
|
||||
void update_init(update_send_t pCbs)
|
||||
{
|
||||
g_update_protoc.pfnSend =pCbs;
|
||||
}
|
||||
|
||||
|
||||
int update_unpack(uint8_t* rxData, int rLen,uint8_t *cmd, uint8_t* dev_addr, void *pload, int *pLen){
|
||||
|
||||
uint16_t crc16;
|
||||
|
||||
uint16_t check;
|
||||
|
||||
check = CRC_Modbus(CRC16_BASE, rxData, rLen - 2);
|
||||
|
||||
crc16 = (rxData[rLen - 1] << 8) | rxData[rLen - 2];
|
||||
|
||||
if (check != crc16 || rxData[0] !=0x7a || pload ==0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
update_protocol_hd_t *Frame = (update_protocol_hd_t*)rxData;
|
||||
|
||||
*dev_addr = Frame->SlvAddr;
|
||||
|
||||
*cmd = Frame->Cmd;
|
||||
|
||||
if (Frame->Cmd == 0x81){
|
||||
|
||||
//update_protocol_req_t *UpData = (update_protocol_req_t*)&rxData[sizeof(update_protocol_hd_t)];
|
||||
|
||||
pload = 0;
|
||||
|
||||
*pLen = 0;
|
||||
|
||||
|
||||
}else if (Frame->Cmd == 0x82){
|
||||
|
||||
update_protocol_rsp_t *DownData = (update_protocol_rsp_t *)&rxData[sizeof(update_protocol_hd_t)];
|
||||
|
||||
memcpy(pload , &rxData[sizeof(update_protocol_hd_t) + sizeof(update_protocol_rsp_t)],DownData->DataLen);
|
||||
|
||||
*pLen = DownData->DataLen;
|
||||
|
||||
}else{
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
生成多项式 (x^16 + x^15 + x^2 + 1)
|
||||
*/
|
||||
uint16_t modbus_crc16(uint8_t* data, int length)
|
||||
{
|
||||
|
||||
uint16_t crc = 0xFFFF; // 初始值FFFF
|
||||
uint16_t polynomial = 0x8005; // 多项式8005
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
// 输入反转(REFIN):对每个字节进行位反转
|
||||
uint8_t byte = data[i];
|
||||
uint8_t reversed_byte = 0;
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
reversed_byte = (reversed_byte << 1) | (byte & 0x01);
|
||||
byte >>= 1;
|
||||
}
|
||||
|
||||
crc ^= (reversed_byte << 8); // 与高字节异或
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (crc & 0x8000) { // 检查最高位
|
||||
crc = (crc << 1) ^ polynomial;
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输出反转(REFOUT):对16位CRC结果进行位反转
|
||||
uint16_t reversed_crc = 0;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
reversed_crc = (reversed_crc << 1) | (crc & 0x0001);
|
||||
crc >>= 1;
|
||||
}
|
||||
|
||||
// 结果异或值(XOROUT):0000(实际不变)
|
||||
return reversed_crc ^ 0x0000;
|
||||
}
|
||||
Reference in New Issue
Block a user