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