BootLoader重构: 适配HC32F460KETA并按传感器通用串口升级协议V1.1改造
主要修改事项: 1. 器件更换: HC32F460PETB改为HC32F460KETA, 更新MDK工程(uvprojx/uvoptx/RTE), 调试器切换为Segger J-Link 2. 新增自定义分散加载文件MDK/BootLoader_custom.sct 3. 新增传感器通用串口升级协议V1.1.xlsx(协议文档) 4. 时钟系统: 取消外部晶振, 改用内部HRC 16MHz -> MPLL 200MHz 5. 删除未使用模块: FatFS/SDCard/SHT20/SX127x(Lora)/AD7924/spiflash/ADS1231/Encryption及LoraTask/CatOneTask/RS485Task/DebugCmd/AppTask, 清理工程IncludePath 6. bsp: BootPara_t参数结构体与GateWay APP对齐(新增GwMac/SvrAddr/SvrPort/LoraFreq/通道配置), 新增RS485 Ch1(USART2)升级通道及RS485 Ch2(USART3)配置, GPIO仅保留RS485方向控制(PC7/PB13) 7. main: 设备MAC固定地址由0x2800改为0x4000并按宏构造(VerInfo/PrjNum/GwNum), 帧头由0x7a改为0x7D并带DevMac字段, 增加MAC匹配(支持0xFF广播), 升级命令更新(0x01 ACK/0x02请求数据/0x81请求/0x82下发), CRC32校验后写参数并复位 8. 跳转APP前关闭全局中断/停SysTick/禁用NVIC中断, 避免残留中断干扰APP 9. Flash擦除仅擦APP区(不擦参数区), 首次运行检测及旧参数区默认值补齐 10. 修复驱动头文件乱码注释(hc32f460_dcu.h/hc32f460_icg.h)
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
#ifndef __ADS1231__
|
||||
#define __ADS1231__
|
||||
|
||||
#include "bsp.h"
|
||||
|
||||
void ADS1231_Open(void);
|
||||
void ADS1231_SpeedSet(void);
|
||||
bool ADS1231_Read(uint32_t *r_data, uint8_t channel);
|
||||
void ADS1231_HighSpeedSet(void);
|
||||
void ADS1231_LowSpeedSet(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
#ifndef __CAT_ONE_TASK_H
|
||||
#define __CAT_ONE_TASK_H
|
||||
#include "main.h"
|
||||
#include "Public.h"
|
||||
|
||||
#define CAT_ONE_REV_TIMEOUT_MAX (10 * 60 * 1000)
|
||||
#define CAT_ONE_REV_LEN_MAX 512
|
||||
|
||||
#define CAT_ONE_POW_ON() CAT1_POW_ON()
|
||||
#define CAT_ONE_POW_OFF() CAT1_POW_OFF()
|
||||
|
||||
#define CAT_ONE_LINKA_GET() CAT1_LINKA_GET()
|
||||
#define CAT_ONE_LINKB_GET() CAT1_LINKB_GET()
|
||||
|
||||
#define CAT_ONE_DELAY_1MS(X)
|
||||
|
||||
typedef enum {
|
||||
CAT_ONE_AT_NULL,
|
||||
CAT_ONE_AT, //开机检测
|
||||
CAT_ONE_ATE0, //关回显
|
||||
CAT_ONE_CPIN, //识卡
|
||||
CAT_ONE_IMEI,
|
||||
CAT_ONE_LCCID, //读卡
|
||||
CAT_ONE_CEREG, //查询注册状态
|
||||
CAT_ONE_CGPADDR, //查询IP地址
|
||||
CAT_ONE_CSQ, //查询信号强度
|
||||
CAT_ONE_LDNSGIP, //域名解析
|
||||
CAT_ONE_LBS, //获取基站定位信息
|
||||
CAT_ONE_LIPOPEN, //设置TCP服务器地址和端口
|
||||
CAT_ONE_LIPSEND, //发送数据
|
||||
CAT_ONE_LTPCLOSE, //断开连接
|
||||
CAT_ONE_LBSPARA,
|
||||
CAT_ONE_CCLK, //获取时间
|
||||
CAT_ONE_AT_CMD_END,
|
||||
}CatOneATCMD_m;
|
||||
|
||||
typedef enum {
|
||||
CAT_ONE_IDEL,
|
||||
CAT_ONE_INIT,
|
||||
CAT_ONE_TCP_CONN,
|
||||
CAT_ONE_WAIT_CONN,
|
||||
CAT_ONE_SEND_DATA,
|
||||
CAT_ONE_WAIT_SEND,
|
||||
CAT_ONE_REV_DATA,
|
||||
CAT_ONE_REG_SVR,
|
||||
CAT_ONE_WAIT_REV,
|
||||
CAT_ONE_RESET,
|
||||
CAT_ONE_OFF,
|
||||
CAT_ONE_CLOSE_TCP,
|
||||
}CatOneStatus_m;
|
||||
|
||||
typedef enum {
|
||||
CAT_ONE_RET_NULL,
|
||||
CAT_ONE_RET_OK,
|
||||
CAT_ONE_RET_ERR,
|
||||
CAT_ONE_RET_TIMEOUT,
|
||||
}CatOneRetStatus_m;
|
||||
|
||||
typedef enum {
|
||||
CAT_ONE_CMD_MODE,
|
||||
CAT_ONE_PT_MODE,
|
||||
}CatOneMode_m;
|
||||
|
||||
typedef enum {
|
||||
CAT_ONE_2G,
|
||||
CAT_ONE_ATE,
|
||||
}CatOneNetType_m;
|
||||
|
||||
typedef struct {
|
||||
CatOneStatus_m Status;
|
||||
CatOneStatus_m NextStatus;
|
||||
CatOneRetStatus_m ATCmdRet;
|
||||
uint32_t CatOne1mSDelayCnt;
|
||||
uint32_t ResetDelayCnt;
|
||||
uint32_t RegisterDelayCnt;
|
||||
uint8_t AtCmdResendCnt;
|
||||
uint8_t AtCmdIdx;
|
||||
CatOneATCMD_m AtCmd;
|
||||
bool RxFlag;
|
||||
uint16_t CSQ;
|
||||
char IMEI[20];
|
||||
char SIM[32];
|
||||
CatOneNetType_m NetType;
|
||||
bool TcpConnFlag;
|
||||
|
||||
bool LBSFlag;
|
||||
int Longitude;
|
||||
int Latitude;
|
||||
char CatOneSendBuff[1024];
|
||||
|
||||
GateWayPara GateWay;
|
||||
DataRevCallBack CatOneRevCallBack;
|
||||
}CatOne_t, *pCatOne_t;
|
||||
|
||||
CatOneRetStatus_m CatOneSend(uint8_t *sData, uint16_t sLen);
|
||||
void CatOneStart(void);
|
||||
void CatOneStop(void);
|
||||
void CatOneReset(void);
|
||||
void Cat1DBGOnOff(bool OnOff);
|
||||
void CatOneGetLocationInfo(int *Longitude, int *Latitude);
|
||||
void CatOneGetIMEIAndSIM(char *Imei, char *Sim);
|
||||
bool CatOneGetStatus(void);
|
||||
bool CatOneEthSendQueue(uint8_t *sData, uint16_t sLen);
|
||||
void CatOne_Eth_Thread_Entry(void *parameter);
|
||||
void EthRxOverhandler(void);
|
||||
void CatReadImeiOrSim(char *Imei, char *Sim);
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef __DEBUG_CMD_H
|
||||
#define __DEBUG_CMD_H
|
||||
|
||||
void Debug_Thread_Entry(void *parameter);
|
||||
void DebugRxOverhandler(void);
|
||||
void Debug_Printf(char *format, ...);
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef __EPT__
|
||||
#define __EPT__
|
||||
|
||||
void Encrypt_Code(unsigned char *data, unsigned char *EPT_data);
|
||||
void Decrypt_Code(unsigned char *EPT_data,unsigned char *DPT_data);
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __LORA_TASK_H
|
||||
#define __LORA_TASK_H
|
||||
|
||||
#include "bsp.h"
|
||||
#include "sx127x.h"
|
||||
|
||||
void Lora_Thread_Entry(void *parameter);
|
||||
int LoraRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen);
|
||||
void LoraInit(void);
|
||||
#endif
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
#ifndef __PUBLIC_H
|
||||
#define __PUBLIC_H
|
||||
|
||||
#include "bsp.h"
|
||||
|
||||
#define LORA_LOWPOWER //LORA低功耗设备,采用主动上报方式
|
||||
|
||||
#define SENSOR_DATA_LEN_MAX 50
|
||||
#define SENSOR_NUM_MAX 16
|
||||
#define COMMUNIT_MUM_MAX 32
|
||||
|
||||
#define REGISTER_INTERVAL_MAX (2 * 60)
|
||||
#define COMMUNIT_READ_SENSOR_INTERVAL_MAX (1 * 60)
|
||||
|
||||
#define LORA_CAT_ERR_RESET_DLY_MAX (20 * 60) //单位秒
|
||||
|
||||
typedef struct GateWay_t GateWayPara_t, *GateWayPara;
|
||||
|
||||
typedef void (*SendData)(uint8_t *sData, uint16_t sLen);
|
||||
typedef int (*DataRevCallBack)(GateWayPara GateWay, uint8_t *rData, uint16_t rLen);
|
||||
typedef int (*DataRevResCallBack)(GateWayPara GateWay, uint8_t *rData, uint16_t rLen, SendData Response);
|
||||
typedef int (*SendDataOrg)(uint8_t *sData);
|
||||
|
||||
typedef enum {
|
||||
DEBUG_CH_DBG,
|
||||
DEBUG_CH_RS485_1,
|
||||
DEBUG_CH_RS485_2,
|
||||
}DebugChannel_m;
|
||||
|
||||
|
||||
typedef enum {
|
||||
DEV_TYPE_BROADCAST,
|
||||
DEV_TYPE_INC_COMMUNIT = 0x8001,
|
||||
DEV_TYPE_EXT_COMMUNIT,
|
||||
DEV_TYPE_ICE_SENSOR,
|
||||
DEV_TYPE_CRACK_SENSOR,
|
||||
DEV_TYPE_PRESSURE_SENSOR,
|
||||
DEV_TYPE_RAIN_SENSOR,
|
||||
}DevType_m;
|
||||
|
||||
typedef enum {
|
||||
CATONE_COMM,
|
||||
ETH_COMM,
|
||||
}CommType_m;
|
||||
|
||||
typedef enum {
|
||||
LORA_COMM,
|
||||
RS485CH1_COMM,
|
||||
RS485CH2_COMM
|
||||
}SensorComm_m;
|
||||
|
||||
typedef enum {
|
||||
SENSOR_TYPE_NULL,
|
||||
STRAIN_SENSOR,
|
||||
PRESSURE_SENSOR,
|
||||
SONAR_SENSOR,
|
||||
CAP_SENSOR,
|
||||
VIBRATE_SENSOR,
|
||||
DEFM_3D_SENSOR,
|
||||
STRAIN_SENSOR_MAG = 8,
|
||||
PRESSURE_SENSOR_MAG,
|
||||
SONAR_SENSOR_MAG,
|
||||
CAP_SENSOR_MAG,
|
||||
DEFM_3D_SENSOR_MAG,
|
||||
STRAIN_2_SENSOR,
|
||||
CRACK_SENSOR,
|
||||
SIX_DIM_SENSOR,
|
||||
POSTURE_SENSOR,
|
||||
LASER_DISTANCE_SENSOR,
|
||||
CRACK_2_SENSOR, //裂缝别名
|
||||
}SensorType_m;
|
||||
|
||||
typedef enum {
|
||||
COMM_UNIT_CMD_REG,
|
||||
COMM_UNIT_CMD_CAIL,
|
||||
COMM_UNIT_CMD_READ,
|
||||
COMM_UNIT_CMD_SET_SENSOR_COLL_TIME = 5,
|
||||
COMM_UNIT_CMD_TIME_SYNC,
|
||||
COMM_UNIT_CMD_END,
|
||||
}CommUnitCmd_m;
|
||||
|
||||
typedef enum {
|
||||
NET_COMM_CMD_REG,
|
||||
NET_COMM_CMD_CAIL,
|
||||
NET_COMM_CMD_UPDATE,
|
||||
NET_COMM_CMD_READ_GW_INFO,
|
||||
NET_COMM_CMD_READ_UNIT_INFO,
|
||||
NET_COMM_CMD_HIS_DATA,
|
||||
NET_COMM_CMD_ADD_UNIT,
|
||||
NET_COMM_CMD_LP_DEV_CONFIG,
|
||||
NET_COMM_CMD_END,
|
||||
}NetCommCmd_m;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int32_t Strain1;
|
||||
int32_t Strain2;
|
||||
int32_t Strain3;
|
||||
int32_t Strain4;
|
||||
int32_t Strain5;
|
||||
}__attribute__((packed))StrainSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MegX;
|
||||
int16_t MegY;
|
||||
int16_t MegZ;
|
||||
int32_t Strain1;
|
||||
int32_t Strain2;
|
||||
int32_t Strain3;
|
||||
int32_t Strain4;
|
||||
int32_t Strain5;
|
||||
int32_t Strain6;
|
||||
}__attribute__((packed))StrainMegSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
uint32_t Pressure;
|
||||
}__attribute__((packed))PressureSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
uint16_t Sonar1;
|
||||
uint16_t Sonar2;
|
||||
uint16_t Sonar3;
|
||||
uint16_t Sonar4;
|
||||
}__attribute__((packed))SonarSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
uint16_t Capacitance1;
|
||||
uint16_t Capacitance2;
|
||||
}__attribute__((packed))CapSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
}__attribute__((packed))Defm3DSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MegX;
|
||||
int16_t MegY;
|
||||
int16_t MegZ;
|
||||
}__attribute__((packed))Defm3DMegSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MagX;
|
||||
int16_t MagY;
|
||||
int16_t MagZ;
|
||||
int32_t Strain1;
|
||||
int32_t Strain2;
|
||||
int32_t Strain3;
|
||||
int32_t Strain4;
|
||||
int32_t Strain5;
|
||||
int32_t Strain6;
|
||||
}__attribute__((packed))StrainMagSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MagX;
|
||||
int16_t MagY;
|
||||
int16_t MagZ;
|
||||
uint32_t Pressure;
|
||||
}__attribute__((packed))PressureMagSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MagX;
|
||||
int16_t MagY;
|
||||
int16_t MagZ;
|
||||
uint16_t Sonar1;
|
||||
uint16_t Sonar2;
|
||||
uint16_t Sonar3;
|
||||
uint16_t Sonar4;
|
||||
}__attribute__((packed))SonarMagSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MagX;
|
||||
int16_t MagY;
|
||||
int16_t MagZ;
|
||||
uint16_t Capacitance1;
|
||||
uint16_t Capacitance2;
|
||||
}__attribute__((packed))CapMagSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int16_t MagX;
|
||||
int16_t MagY;
|
||||
int16_t MagZ;
|
||||
}__attribute__((packed))Defm3DMagSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX;
|
||||
int16_t AccY;
|
||||
int16_t AccZ;
|
||||
int32_t Strain1;
|
||||
int32_t Strain2;
|
||||
}__attribute__((packed))Strain2SensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t AccX_L;
|
||||
int16_t AccY_L;
|
||||
int16_t AccZ_L;
|
||||
int16_t MagX_L;
|
||||
int16_t MagY_L;
|
||||
int16_t MagZ_L;
|
||||
int16_t AccX_R;
|
||||
int16_t AccY_R;
|
||||
int16_t AccZ_R;
|
||||
int16_t MagX_R;
|
||||
int16_t MagY_R;
|
||||
int16_t MagZ_R;
|
||||
}__attribute__((packed))CrackSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t PitchAngle;
|
||||
int16_t RollAngle;
|
||||
int16_t VibrationStrength;
|
||||
int16_t Temperature;
|
||||
}__attribute__((packed))PostureSensorType_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t CommDevAddr[6]; //通讯单元地址
|
||||
uint16_t CollectInterval; //采集时间间隔
|
||||
uint16_t ReportInterval; //上报时间间隔
|
||||
uint8_t ERInterval; //紧急上报时间间隔
|
||||
uint8_t ERTime; //紧急上报时长
|
||||
}__attribute__((packed))SvrDownLPDevConfigPara_t;
|
||||
|
||||
typedef struct {
|
||||
int Distance;
|
||||
}__attribute__((packed))LaserDistanceSensorType_t;
|
||||
|
||||
|
||||
#define LW_DEV_COLLECT_INTERVAL_MAX 300
|
||||
#define LW_DEV_REPORT_INTERVAL_MAX 20
|
||||
#define LW_DEV_ER_INTERVAL_MAX 2
|
||||
#define LW_DEV_ER_TIME_MAX 20
|
||||
|
||||
typedef struct {
|
||||
uint16_t CollectInterval; //采集时间间隔
|
||||
uint16_t ReportInterval; //上报时间间隔
|
||||
uint8_t ERInterval; //紧急上报时间间隔
|
||||
uint8_t ERTime; //紧急上报时长
|
||||
uint32_t TimeStamp; //时间戳
|
||||
}__attribute__((packed))LPDevConfigPara_t;
|
||||
|
||||
typedef struct {
|
||||
bool RegFlag;
|
||||
bool RevNewDataFlag;
|
||||
bool CommStatus; //通讯状态,1-在线,0-离线
|
||||
uint8_t BatLevel;
|
||||
uint32_t CommErrCnt;
|
||||
uint8_t Mac[6];
|
||||
uint16_t CUType;
|
||||
uint8_t SensorN;
|
||||
uint16_t SensorType[SENSOR_NUM_MAX];
|
||||
//低功耗设备配置信息
|
||||
bool ConfigFlag; //配置标志,为1表示有新配置,应答低功耗设备时需要附带发送
|
||||
uint16_t CollectInterval; //采集时间间隔
|
||||
uint16_t ReportInterval; //上报时间间隔
|
||||
uint8_t ERInterval; //紧急上报时间间隔
|
||||
uint8_t ERTime; //紧急上报时长
|
||||
}CommUnitPara_t, *CommUnitPara;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Data[SENSOR_NUM_MAX][SENSOR_DATA_LEN_MAX];
|
||||
}CommUnitData_t, *CommUnitData;
|
||||
|
||||
typedef struct {
|
||||
CommUnitPara_t Para;
|
||||
CommUnitData_t SensorData;
|
||||
}CommUnit_t, *CommUnit;
|
||||
|
||||
typedef struct {
|
||||
bool Enable; //串口使能
|
||||
bool CommUnitEnable; //通讯单元使能,开启(使用内部通讯单元功能,直接和传感器通讯),关闭(直接和RS485类型的通讯单元通讯)
|
||||
bool QuerySensorFlag; //查询传感器标志
|
||||
uint8_t Power;
|
||||
uint32_t BaudRate;
|
||||
SendData RS485Send;
|
||||
CommUnit_t CUData;
|
||||
}RS485Para_t, *RS485Para;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Header;
|
||||
uint8_t GWMac[6];
|
||||
uint8_t DevMac[6];
|
||||
uint8_t Cmd;
|
||||
uint16_t DevType;
|
||||
uint8_t PayloadLen;
|
||||
}__attribute__((packed))CommUnitFrameHeader_t, *CommUnitFrameHeader;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Header;
|
||||
uint8_t GWMac[6];
|
||||
uint8_t SvrMac[6];
|
||||
uint8_t Cmd;
|
||||
uint32_t Timestamp;
|
||||
uint8_t PacketNum;
|
||||
uint8_t PacketIdx;
|
||||
uint16_t PayloadLen;
|
||||
}__attribute__((packed))NetCommFrameHeader_t, *NetCommFrameHeader;
|
||||
|
||||
typedef struct {
|
||||
uint8_t ucChannel;
|
||||
int8_t ucPower;
|
||||
uint8_t SignalBw;
|
||||
uint8_t SpreadFactor;
|
||||
uint8_t ErrorCoding;
|
||||
uint8_t RegPreamble;
|
||||
}LoraPara_t, *pLoraPara;
|
||||
|
||||
typedef struct {
|
||||
uint32_t SavFlag; //存储标志
|
||||
CommType_m Comm; //网关通讯方式
|
||||
uint8_t GwMac[6]; //网关mac
|
||||
char SvrAddr[4]; //服务器地址
|
||||
uint32_t SvrPort; //服务器端口
|
||||
uint32_t CommUnitReadInterval; //通讯单元读取时间间隔,单位S
|
||||
CommUnitPara_t CommUnitArray[COMMUNIT_MUM_MAX]; //注册的通讯单元信息
|
||||
RS485Para_t Rs485Ch1; //RS485通道1配置
|
||||
RS485Para_t Rs485Ch2; //RS485通道2配置
|
||||
LoraPara_t Lora; //Lora配置
|
||||
}GWConfigPara_t, *GWConfigPara;
|
||||
|
||||
struct GateWay_t{
|
||||
uint8_t DebugChannel;
|
||||
bool TimeSyncFlag; //时间同步标志
|
||||
bool SvrRegFlag; //服务器注册标志
|
||||
uint8_t SvrMac[6]; //服务器mac
|
||||
GWConfigPara_t ConfigPara; //配置参数
|
||||
CommUnitData_t CUDataArray[COMMUNIT_MUM_MAX];
|
||||
uint8_t Battery; //电池电量
|
||||
uint32_t HistoryNum; //历史数据数量
|
||||
DataRevCallBack SvrRevCallBack; //接收到服务器回调
|
||||
DataRevResCallBack CommUnitRevCallBack; //通讯单元接收回调
|
||||
rt_mq_t NetSendData_MQ; //网络发送数据队列,第一个字节用于存储消息长度, 第二字节存储命令字,后为数据
|
||||
rt_mq_t LoraRev_MQ; //Lora接收消息队列,第一个字节用于存储消息长度,后为数据
|
||||
rt_mutex_t UartRevMutex;
|
||||
};
|
||||
|
||||
int Cat1EthRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen);
|
||||
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length);
|
||||
uint8_t AsciiToHex(char *ASCData, uint8_t *HexData, uint8_t sLen);
|
||||
void HexToAscii(uint8_t *HexData, char *ASCData, uint8_t sLen);
|
||||
int NetCommOrgData(GateWayPara GateWay, uint8_t *MegData, uint8_t *OutData);
|
||||
int CommUnitAnalyze(GateWayPara GateWay, uint8_t *rData, uint16_t rLen, SendData Response);
|
||||
void DebugAnalyze(GateWayPara GateWay, uint8_t *rData, uint16_t rLen);
|
||||
void CommUnitCmdSend(GateWayPara GateWay, uint8_t *CommUnitMac, CommUnitCmd_m Cmd, uint8_t *Payload, uint16_t PayloadLen, SendData Send);
|
||||
int CheckCommUnitReg(GateWayPara GateWay, uint8_t *CommUnitMac);
|
||||
int CommUintOrgData(GateWayPara GateWay, CommUnitPara CUPara, CommUnitData CUData, uint8_t *sData);
|
||||
void DebugDisplaySensorData(int SensorIdx, uint16_t SensorType, uint8_t *SensorData);
|
||||
#endif
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef __PUBLIC_TYPES_H
|
||||
#define __PUBLIC_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef void (*ReadPara)(pSFBTPara rPara);
|
||||
typedef void (*SavPara)(pSFBTPara wPara);
|
||||
typedef void (*UartSend)(uint8_t *sData, int sLen);
|
||||
typedef void (*DataRevCallBack)(uint8_t *rData, uint8_t rLen);
|
||||
typedef int (*SendDataOrg)(uint8_t *sData);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#ifndef __RS485_TASK_H
|
||||
#define __RS485_TASK_H
|
||||
|
||||
#include "bsp.h"
|
||||
#include "Public.h"
|
||||
|
||||
#define RS485_RX_BUFF_LEN_MAX 64
|
||||
|
||||
typedef struct {
|
||||
SensorComm_m Com;
|
||||
uint16_t SensorType;
|
||||
}SensorTypes_t;
|
||||
|
||||
typedef enum {
|
||||
RS485_OUT_VOLTAGE_OV,
|
||||
RS485_OUT_VOLTAGE_5V,
|
||||
RS485_OUT_VOLTAGE_12V,
|
||||
}RS485Vol_m;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Header;
|
||||
uint8_t SlvAddr;
|
||||
uint8_t Cmd;
|
||||
uint16_t DevType;
|
||||
uint8_t PayloadLen;
|
||||
}__attribute__((packed))FrameHeader_t, *FrameHeader;
|
||||
|
||||
typedef enum {
|
||||
RS485_SENSOR_CMD_NULL,
|
||||
RS485_SENSOR_CMD_CAIL,
|
||||
RS485_SENSOR_CMD_READ,
|
||||
RS485_SENSOR_CMD_SET_ADDR,
|
||||
RS485_SENSOR_CMD_QUERY,
|
||||
RS485_SENSOR_CMD_SET_INV_TIME,
|
||||
RS485_SENSOR_CMD_TIME_SYNC,
|
||||
RS485_SENSOR_CMD_END,
|
||||
}RS485SensorCmd_m;
|
||||
|
||||
//´«¸ÐÆ÷Êý¾Ý·¢ËͽṹÌå
|
||||
typedef struct {
|
||||
bool SendFlag;
|
||||
uint8_t SensorCnt;
|
||||
uint8_t SensorErrCnt[SENSOR_NUM_MAX];
|
||||
uint8_t ReadSensorCnt;
|
||||
int32_t ReadSensorInterval;
|
||||
RS485SensorCmd_m Cmd;
|
||||
uint8_t SensorAddr;
|
||||
uint16_t SensorType;
|
||||
uint8_t CmdParaLen;
|
||||
uint8_t *CmdPara;
|
||||
uint8_t RS485RxBuff[RS485_RX_BUFF_LEN_MAX];
|
||||
uint8_t RS485RxLen;
|
||||
uint8_t RS485TimeOutCnt;
|
||||
uint32_t RS485CommUnitReadTimeDelay;
|
||||
uint8_t SendUnitCommIdx;
|
||||
rt_sem_t RS485Rev_Sem;
|
||||
bool InitOverFlag;
|
||||
}SensorCommPara_t, *SensorCommPara;
|
||||
|
||||
void RS485CmdSend(GateWayPara GateWay, uint8_t CommUintAddr, SensorCommPara SensorComm);
|
||||
void RS485Ch1_Thread_Entry(void *parameter);
|
||||
void RS485Ch2_Thread_Entry(void *parameter);
|
||||
void RS485RxOverhandler(void);
|
||||
|
||||
extern SensorCommPara_t SComm1Para;
|
||||
extern SensorCommPara_t SComm2Para;
|
||||
#endif
|
||||
|
||||
|
||||
+105
-220
@@ -5,29 +5,47 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "hc32_ddl.h"
|
||||
#include "ff.h"
|
||||
|
||||
/*版本信息枚举 - 对应Mac[0]的Bit[6:0], Bit[7]固定为1*/
|
||||
typedef enum {
|
||||
GATEWAY_VER1_0 = 0x01, //网关Ver1.0
|
||||
GATEWAY_VER2_0 = 0x02, //网关Ver2.0
|
||||
}GATEWAY_VER_M;
|
||||
|
||||
/*版本信息*/
|
||||
/*项目编号枚举 - 对应Mac[1:3](3字节)*/
|
||||
typedef enum {
|
||||
GW_V1_0 = 0x81, //1-网关Ver1.0:具有LORA通信、4G通讯、以太网通信,支持DC12V供
|
||||
GW_V2_0 = 0x82, //2-网关Ver2.0:具有LORA通信、4G通讯、以太网通信、光纤通信,支持AC-220V供电,DC-12V供电
|
||||
}VER_INFO_M;
|
||||
/*项目编号*/
|
||||
GATEWAY_PRJ_TEST = 0, //测试项目
|
||||
GATEWAY_PRJ_AKY, //安科院项目
|
||||
GATEWAY_PRJ_BJTU, //北交大项目
|
||||
GATEWAY_PRJ_BALADIAN, //巴拉水电边坡监测项目
|
||||
GATEWAY_PRJ_TYY1, //铁一院川藏铁路隧道监测项目
|
||||
GATEWAY_PRJ_TYY2, //铁二院川藏铁路隧道监测项目
|
||||
GATEWAY_PRJ_YAXIA, //雅下项目
|
||||
GATEWAY_PRJ_OTHER, //…………
|
||||
}GATEWAY_PRJ_M;
|
||||
|
||||
/*通道枚举 - 与GateWay APP一致*/
|
||||
typedef enum {
|
||||
TEST = 0x000000, //测试项目
|
||||
CASST = 0x000001, //安科院项目
|
||||
BJTU = 0x000002, //北交大项目
|
||||
BSM = 0x000003, //巴拉水电边坡监测项目
|
||||
FSTM = 0x000004, //铁一院川藏铁路隧道监测项目
|
||||
CSTM = 0x000005, //铁二院川藏铁路隧道监测项目
|
||||
LYT = 0x000003, //雅下项目
|
||||
}PRJ_NUM_M;
|
||||
/*Lora频率:433100000ul + 200000*N */
|
||||
CH_NULL = -1,
|
||||
CH_DBG = 0,
|
||||
CH_RS485_1,
|
||||
CH_RS485_2,
|
||||
CH_ETH,
|
||||
CH_LORA,
|
||||
CH_CAT1,
|
||||
}Channel_m;
|
||||
|
||||
/*通讯单元通道掩码 - 与GateWay APP一致*/
|
||||
#define CUCH_CH1 (1 << CH_RS485_1)
|
||||
#define CUCH_CH2 (1 << CH_RS485_2)
|
||||
#define CUCH_ETH (1 << CH_ETH)
|
||||
#define CUCH_LORA (1 << CH_LORA)
|
||||
#define CUCH_CAT1 (1 << CH_CAT1)
|
||||
|
||||
/*Lora频率:433100000ul + 200000*N,用于配置Lora频率更方便*/
|
||||
typedef enum {
|
||||
CH0 = (433100000ul + 0), //测试频率
|
||||
CH0 = (433100000ul + 0), //测试频率
|
||||
CH1 = (433100000ul + 200000),
|
||||
CH2 = (433100000ul + 400000),
|
||||
CH3 = (433100000ul + 600000),
|
||||
@@ -37,45 +55,50 @@ typedef enum {
|
||||
CH7 = (433100000ul + 1400000),
|
||||
CH8 = (433100000ul + 1600000),
|
||||
CH9 = (433100000ul + 1800000),
|
||||
CH10 = (433100000ul + 2000000),
|
||||
CH10 = (433100000ul + 2000000),
|
||||
}LORA_FREQ_M;
|
||||
|
||||
/*版本选择*/
|
||||
#define VERINFO GW_V1_0
|
||||
/*项目选择*/
|
||||
#define PRJNUM LYT
|
||||
/*网关序号设置*/
|
||||
#define GW_NUM_M (0x0000)
|
||||
/*Lora频率配置*/
|
||||
#define LORA_FREQ CH0
|
||||
/*当前设备版本/项目选择*/
|
||||
#define GATEWAY_VER_INFO GATEWAY_VER1_0 //版本信息
|
||||
#define GATEWAY_PRJ_NUM GATEWAY_PRJ_YAXIA //项目编号
|
||||
#define GATEWAY_GW_NUM 0x0000 //网关编号(2字节, 1~65535)
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x2000ul
|
||||
#define FLASH_BASE ((uint32_t)0x00000000)
|
||||
#define FLASH_SIZE (64u * FLASH_SECTOR_SIZE)
|
||||
/*默认服务器/Lora配置 - 替代原MAC_ADDR_TYPE编译宏, 在Boot中直接配置*/
|
||||
#define GATEWAY_SVR_ADDR0 39 //服务器IP[0]
|
||||
#define GATEWAY_SVR_ADDR1 106 //服务器IP[1]
|
||||
#define GATEWAY_SVR_ADDR2 103 //服务器IP[2]
|
||||
#define GATEWAY_SVR_ADDR3 147 //服务器IP[3]
|
||||
#define GATEWAY_SVR_PORT 8080 //服务器端口
|
||||
|
||||
#define GATEWAY_LORA_FREQ CH3 //Lora中心频率(可配置为CH0~CH10)
|
||||
|
||||
/*默认通道配置 - 在Boot中直接配置, 替代原APP硬编码默认值*/
|
||||
#define GATEWAY_MUCH CH_ETH //主上传通道
|
||||
#define GATEWAY_AUCH CH_NULL //辅助上传通道
|
||||
#define GATEWAY_DUCH CH_CAT1 //调试/升级通道
|
||||
#define GATEWAY_CUCH_MASK CUCH_LORA //通讯单元通道掩码
|
||||
|
||||
/*Flash分区 - 32KB Boot + APP(0x8000起) + 参数区(0x7C000)*/
|
||||
#define FLASH_SECTOR_SIZE 0x2000ul //8KB
|
||||
#define FLASH_BASE ((uint32_t)0x00000000)
|
||||
#define FLASH_SIZE (64u * FLASH_SECTOR_SIZE) //512KB
|
||||
|
||||
#define SRAM_BASE ((uint32_t)0x1FFF8000)
|
||||
#define SRAM_SIZE 0x2F000ul
|
||||
#define SRAM_SIZE 0x2F000ul //192KB
|
||||
|
||||
#define BOOT_SIZE (4 * FLASH_SECTOR_SIZE)
|
||||
#define APP_ADDRESS (FLASH_BASE + BOOT_SIZE)
|
||||
|
||||
#define BOOT_PARA_ADDRESS (FLASH_SIZE - FLASH_SECTOR_SIZE)
|
||||
#define BOOT_PARA_SIZE (FLASH_SECTOR_SIZE)
|
||||
|
||||
|
||||
#define DEV_TYPE (0x0001)
|
||||
#define BOOT_SIZE (4 * FLASH_SECTOR_SIZE) //32KB
|
||||
#define APP_ADDRESS (FLASH_BASE + BOOT_SIZE) //0x8000
|
||||
#define APP_SIZE (58 * FLASH_SECTOR_SIZE) //464KB
|
||||
#define BOOT_PARA_ADDRESS (APP_ADDRESS + APP_SIZE) //0x7C000
|
||||
#define BOOT_PARA_SIZE (FLASH_SECTOR_SIZE)
|
||||
|
||||
#define DEBUG 1
|
||||
#define USE_SD_CARD 0
|
||||
#define WATCH_DOG 1
|
||||
|
||||
|
||||
#if(VERINFO == GW_V1_0)
|
||||
//DEBUG USART1
|
||||
#define DBGUART_IRQn Int006_IRQn
|
||||
#define DBGUART_EI_IRQn Int007_IRQn
|
||||
#define DBG_RXPIN_IRQn Int002_IRQn
|
||||
|
||||
//DEBUG
|
||||
#define DBG_USART_CH (M4_USART1)
|
||||
#define DBG_USART_RX_PORT (PortA)
|
||||
#define DBG_USART_RX_PIN (Pin11)
|
||||
@@ -85,11 +108,9 @@ typedef enum {
|
||||
#define DBG_USART_TX_FUNC (Func_Usart1_Tx)
|
||||
#define DBG_USART_RI_NUM (INT_USART1_RI)
|
||||
#define DBG_USART_EI_NUM (INT_USART1_EI)
|
||||
#define DBG_USART_TI_NUM (INT_USART1_TI)
|
||||
#define DBG_USART_TCI_NUM (INT_USART1_TCI)
|
||||
#define DBG_FCG1_PERIPH (PWC_FCG1_PERIPH_USART1)
|
||||
|
||||
//RS485 Ch1
|
||||
//RS485 Ch1 USART2 - 升级通道
|
||||
#define RS485_CH1_USART_CH (M4_USART2)
|
||||
#define RS485_CH1_USART_RX_PORT (PortA)
|
||||
#define RS485_CH1_USART_RX_PIN (Pin10)
|
||||
@@ -99,21 +120,16 @@ typedef enum {
|
||||
#define RS485_CH1_USART_TX_FUNC (Func_Usart2_Tx)
|
||||
#define RS485_CH1_USART_RI_NUM (INT_USART2_RI)
|
||||
#define RS485_CH1_USART_EI_NUM (INT_USART2_EI)
|
||||
#define RS485_CH1_USART_TI_NUM (INT_USART2_TI)
|
||||
#define RS485_CH1_USART_TCI_NUM (INT_USART2_TCI)
|
||||
#define RS485_CH1_FCG1_PERIPH (PWC_FCG1_PERIPH_USART2)
|
||||
#define RS485CH1_UART_IRQn Int012_IRQn
|
||||
#define RS485CH1_UART_EI_IRQn Int011_IRQn
|
||||
|
||||
#define RS485_CH1_CTRL_PORT (PortC)
|
||||
#define RS485_CH1_CTRL_PIN (Pin07)
|
||||
#define RS485_CH1_TX() PORT_SetBits(RS485_CH1_CTRL_PORT, RS485_CH1_CTRL_PIN)
|
||||
#define RS485_CH1_RX() PORT_ResetBits(RS485_CH1_CTRL_PORT, RS485_CH1_CTRL_PIN)
|
||||
|
||||
#define RS485_CH1_POW_PORT (PortC)
|
||||
#define RS485_CH1_POW_PIN (Pin10)
|
||||
#define RS485_CH1_POW_ON() PORT_SetBits(RS485_CH1_POW_PORT, RS485_CH1_POW_PIN)
|
||||
#define RS485_CH1_POW_OFF() PORT_ResetBits(RS485_CH1_POW_PORT, RS485_CH1_POW_PIN)
|
||||
|
||||
//RS485 Ch2
|
||||
//RS485 Ch2 USART3
|
||||
#define RS485_CH2_USART_CH (M4_USART3)
|
||||
#define RS485_CH2_USART_RX_PORT (PortB)
|
||||
#define RS485_CH2_USART_RX_PIN (Pin14)
|
||||
@@ -123,192 +139,61 @@ typedef enum {
|
||||
#define RS485_CH2_USART_TX_FUNC (Func_Usart3_Tx)
|
||||
#define RS485_CH2_USART_RI_NUM (INT_USART3_RI)
|
||||
#define RS485_CH2_USART_EI_NUM (INT_USART3_EI)
|
||||
#define RS485_CH2_USART_TI_NUM (INT_USART3_TI)
|
||||
#define RS485_CH2_USART_TCI_NUM (INT_USART3_TCI)
|
||||
#define RS485_CH2_FCG1_PERIPH (PWC_FCG1_PERIPH_USART3)
|
||||
#define RS485CH2_UART_IRQn Int002_IRQn
|
||||
#define RS485CH2_UART_EI_IRQn Int003_IRQn
|
||||
|
||||
#define RS485_CH2_CTRL_PORT (PortB)
|
||||
#define RS485_CH2_CTRL_PIN (Pin13)
|
||||
#define RS485_CH2_TX() PORT_SetBits(RS485_CH2_CTRL_PORT, RS485_CH2_CTRL_PIN)
|
||||
#define RS485_CH2_RX() PORT_ResetBits(RS485_CH2_CTRL_PORT, RS485_CH2_CTRL_PIN)
|
||||
|
||||
#define RS485_CH2_POW_PORT (PortB)
|
||||
#define RS485_CH2_POW_PIN (Pin02)
|
||||
#define RS485_CH2_POW_ON() PORT_SetBits(RS485_CH2_POW_PORT, RS485_CH2_POW_PIN)
|
||||
#define RS485_CH2_POW_OFF() PORT_ResetBits(RS485_CH2_POW_PORT, RS485_CH2_POW_PIN)
|
||||
|
||||
//ETH OR CAT1
|
||||
#define ETH_OR_CAT1_USART_CH (M4_USART4)
|
||||
#define ETH_OR_CAT1_USART_RX_PORT (PortB)
|
||||
#define ETH_OR_CAT1_USART_RX_PIN (Pin09)
|
||||
#define ETH_OR_CAT1_USART_TX_PORT (PortC)
|
||||
#define ETH_OR_CAT1_USART_TX_PIN (Pin13)
|
||||
#define ETH_OR_CAT1_USART_RX_FUNC (Func_Usart4_Rx)
|
||||
#define ETH_OR_CAT1_USART_TX_FUNC (Func_Usart4_Tx)
|
||||
#define ETH_OR_CAT1_USART_RI_NUM (INT_USART4_RI)
|
||||
#define ETH_OR_CAT1_USART_EI_NUM (INT_USART4_EI)
|
||||
#define ETH_OR_CAT1_USART_TI_NUM (INT_USART4_TI)
|
||||
#define ETH_OR_CAT1_USART_TCI_NUM (INT_USART4_TCI)
|
||||
#define ETH_OR_CAT1_FCG1_PERIPH (PWC_FCG1_PERIPH_USART4)
|
||||
|
||||
#define ETH_OR_CAT1_CTRL_PORT (PortB)
|
||||
#define ETH_OR_CAT1_CTRL_PIN (Pin08)
|
||||
#define ETH_ON() PORT_SetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN)
|
||||
#define CAT1_ON() PORT_ResetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN)
|
||||
|
||||
//#define ETH_OR_CAT1_TX_CTRL_PORT (PortH)
|
||||
//#define ETH_OR_CAT1_TX_CTRL_PIN (Pin02)
|
||||
//#define ETH_ON() { PORT_SetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN); PORT_SetBits(ETH_OR_CAT1_TX_CTRL_PORT, ETH_OR_CAT1_TX_CTRL_PIN); }
|
||||
//#define CAT1_ON() { PORT_ResetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN); PORT_ResetBits(ETH_OR_CAT1_TX_CTRL_PORT, ETH_OR_CAT1_TX_CTRL_PIN);}
|
||||
|
||||
#define CAT1_PWR_KEY_PORT (PortA)
|
||||
#define CAT1_PWR_KEY_PIN (Pin03)
|
||||
#define CAT1_PWR_KEY_CLR() PORT_SetBits(CAT1_PWR_KEY_PORT, CAT1_PWR_KEY_PIN)
|
||||
#define CAT1_PWR_KEY_SET() PORT_ResetBits(CAT1_PWR_KEY_PORT, CAT1_PWR_KEY_PIN)
|
||||
|
||||
#define CAT1_RESET_PORT (PortA)
|
||||
#define CAT1_RESET_PIN (Pin00)
|
||||
#define CAT1_RESET_CLR() PORT_SetBits(CAT1_RESET_PORT, CAT1_RESET_PIN)
|
||||
#define CAT1_RESET_SET() PORT_ResetBits(CAT1_RESET_PORT, CAT1_RESET_PIN)
|
||||
|
||||
//#define CAT1_POW_PORT (PortA)
|
||||
//#define CAT1_POW_PIN (Pin00)
|
||||
//#define CAT1_POW_ON() PORT_SetBits(CAT1_POW_PORT, CAT1_POW_PIN)
|
||||
//#define CAT1_POW_OFF() PORT_ResetBits(CAT1_POW_PORT, CAT1_POW_PIN)
|
||||
|
||||
#define ETH_RESET_PORT (PortB)
|
||||
#define ETH_RESET_PIN (Pin05)
|
||||
#define ETH_RESET_SET() PORT_SetBits(ETH_RESET_PORT, ETH_RESET_PIN)
|
||||
#define ETH_RESET_CLR() PORT_ResetBits(ETH_RESET_PORT, ETH_RESET_PIN)
|
||||
|
||||
#define ETH_DEF_PORT (PortB)
|
||||
#define ETH_DEF_PIN (Pin07)
|
||||
#define ETH_DEF_SET() PORT_SetBits(ETH_DEF_PORT, ETH_DEF_PIN)
|
||||
#define ETH_DEF_CLR() PORT_ResetBits(ETH_DEF_PORT, ETH_DEF_PIN)
|
||||
|
||||
#define ETH_LINK_PORT (PortB)
|
||||
#define ETH_LINK_PIN (Pin06)
|
||||
#define ETH_LINK_GET() PORT_GetBit(ETH_LINK_PORT, ETH_LINK_PIN)
|
||||
|
||||
//LORA IO
|
||||
/* SPI_SCK Port/Pin definition */
|
||||
#define SPI2_SCK_PORT (PortC)
|
||||
#define SPI2_SCK_PIN (Pin04)
|
||||
#define SPI2_SCK_FUNC (Func_Spi2_Sck)
|
||||
|
||||
/* SPI_MOSI Port/Pin definition */
|
||||
#define SPI2_MOSI_PORT (PortA)
|
||||
#define SPI2_MOSI_PIN (Pin07)
|
||||
#define SPI2_MOSI_FUNC (Func_Spi2_Mosi)
|
||||
|
||||
/* SPI_MISO Port/Pin definition */
|
||||
#define SPI2_MISO_PORT (PortA)
|
||||
#define SPI2_MISO_PIN (Pin06)
|
||||
#define SPI2_MISO_FUNC (Func_Spi2_Miso)
|
||||
|
||||
/* SPI_MOSI Port/Pin definition */
|
||||
#define SPI2_NSS_PORT (PortC)
|
||||
#define SPI2_NSS_PIN (Pin05)
|
||||
#define SPI2_NSS_FUNC (Func_Spi2_Nss0)
|
||||
#define SPI2_NSS_SET() PORT_SetBits(SPI2_NSS_PORT, SPI2_NSS_PIN)
|
||||
#define SPI2_NSS_CLR() PORT_ResetBits(SPI2_NSS_PORT, SPI2_NSS_PIN)
|
||||
|
||||
/* SPI unit and clock definition */
|
||||
#define SPI2_UNIT (M4_SPI2)
|
||||
#define SPI2_UNIT_CLOCK (PWC_FCG1_PERIPH_SPI2)
|
||||
|
||||
#define LORA_DIO_PORT (PortA)
|
||||
#define LORA_DIO_PIN (Pin04)
|
||||
#define LORA_DIO_GET() PORT_GetBit(LORA_DIO_PORT, LORA_DIO_PIN)
|
||||
#define LORA_DIO_EXIT_CH (ExtiCh04)
|
||||
#define LORA_DIO_EXIT_SRC (INT_PORT_EIRQ4)
|
||||
|
||||
#define LORA_RESET_PORT (PortA)
|
||||
#define LORA_RESET_PIN (Pin05)
|
||||
#define LORA_RESET_SET() PORT_SetBits(LORA_RESET_PORT, LORA_RESET_PIN)
|
||||
#define LORA_RESET_CLR() PORT_ResetBits(LORA_RESET_PORT, LORA_RESET_PIN)
|
||||
|
||||
#define LORA_RXEN_PORT (PortB)
|
||||
#define LORA_RXEN_PIN (Pin00)
|
||||
#define LORA_RXEN_SET() PORT_SetBits(LORA_RXEN_PORT, LORA_RXEN_PIN)
|
||||
#define LORA_RXEN_CLR() PORT_ResetBits(LORA_RXEN_PORT, LORA_RXEN_PIN)
|
||||
|
||||
#define LORA_TXEN_PORT (PortB)
|
||||
#define LORA_TXEN_PIN (Pin01)
|
||||
#define LORA_TXEN_SET() PORT_SetBits(LORA_TXEN_PORT, LORA_TXEN_PIN)
|
||||
#define LORA_TXEN_CLR() PORT_ResetBits(LORA_TXEN_PORT, LORA_TXEN_PIN)
|
||||
|
||||
#define LORA_RX_LED_PORT (PortB)
|
||||
#define LORA_RX_LED_PIN (Pin03)
|
||||
#define LORA_RX_LED_SET() PORT_SetBits(LORA_RX_LED_PORT, LORA_RX_LED_PIN)
|
||||
#define LORA_RX_LED_CLR() PORT_ResetBits(LORA_RX_LED_PORT, LORA_RX_LED_PIN)
|
||||
#define LORA_RX_TOGGLE() PORT_Toggle(LORA_RX_LED_PORT, LORA_RX_LED_PIN)
|
||||
|
||||
#define LORA_POW_PORT (PortC)
|
||||
#define LORA_POW_PIN (Pin06)
|
||||
#define LORA_POW_ON() PORT_SetBits(LORA_POW_PORT, LORA_POW_PIN)
|
||||
#define LORA_POW_OFF() PORT_ResetBits(LORA_POW_PORT, LORA_POW_PIN)
|
||||
|
||||
//开关按钮灯
|
||||
#define KEY_LED_PORT (PortB)
|
||||
#define KEY_LED_PIN (Pin04)
|
||||
|
||||
/*BootLoader参数结构体 - 与GateWay APP一致*/
|
||||
typedef struct {
|
||||
bool Enable; //串口使能
|
||||
bool CommUnitEnable; //通讯单元使能,开启(使用内部通讯单元功能,直接和传感器通讯),关闭(直接和RS485类型的通讯单元通讯)
|
||||
bool QuerySensorFlag; //查询传感器标志
|
||||
bool UpgradeEnable;//升级功能使能
|
||||
uint8_t Power;
|
||||
uint32_t BaudRate;
|
||||
SendData RS485Send;
|
||||
CommUnit_t CUData;
|
||||
}__attribute__((packed))RS485Para_t, *RS485Para;
|
||||
|
||||
typedef struct {
|
||||
bool OnOff;
|
||||
SendData LoraSend;
|
||||
uint8_t ucChannel;
|
||||
int8_t ucPower;
|
||||
uint8_t SignalBw;
|
||||
uint8_t SpreadFactor;
|
||||
uint8_t ErrorCoding;
|
||||
uint8_t RegPreamble;
|
||||
uint32_t FreqCent;
|
||||
}LoraPara_t, *pLoraPara;
|
||||
|
||||
typedef struct {
|
||||
uint32_t SavFlag; //存储标志
|
||||
CommType_m Comm; //网关通讯方式
|
||||
uint8_t GwMac[6]; //网关mac
|
||||
char SvrAddr[4]; //服务器地址
|
||||
uint32_t SvrPort; //服务器端口
|
||||
uint32_t CommUnitReadInterval; //通讯单元读取时间间隔,单位S
|
||||
RS485Para_t Rs485Ch1; //RS485通道1配置
|
||||
RS485Para_t Rs485Ch2; //RS485通道2配置
|
||||
uint8_t DebugChannel; //调试通道
|
||||
LoraPara_t Lora; //Lora配置
|
||||
}__attribute__((packed))GWConfigPara_t, *GWConfigPara;
|
||||
|
||||
typedef struct {
|
||||
uint32_t AppFlag;
|
||||
uint32_t UpdateFlag;
|
||||
uint32_t PackageCnt;
|
||||
uint32_t AppSize;
|
||||
uint32_t Crc32Check;
|
||||
uint32_t FirstRunFlag;//第一次运行
|
||||
uint32_t AppFlag; //应用启动标志
|
||||
uint32_t UpdateFlag; //升级标志
|
||||
uint32_t PackageCnt; //数据包总数
|
||||
uint32_t AppSize; //应用程序大小
|
||||
uint32_t Crc32Check; //CRC32校验值
|
||||
uint32_t FirstRunFlag; //首次运行标志
|
||||
uint8_t GwMac[6]; //网关MAC地址
|
||||
uint8_t SvrAddr[4]; //默认服务器IP地址
|
||||
uint16_t SvrPort; //默认服务器端口
|
||||
uint32_t LoraFreq; //默认Lora中心频率
|
||||
int8_t Much; //主上传通道
|
||||
int8_t Auch; //辅助上传通道
|
||||
int8_t Duch; //调试/升级通道
|
||||
uint8_t CuchMask; //通讯单元通道掩码
|
||||
}BootPara_t, *BootPara;
|
||||
|
||||
/*BSP初始化*/
|
||||
void BSP_Init(void);
|
||||
|
||||
/*调试串口*/
|
||||
void DbgUart_Config(uint32_t BaudRate);
|
||||
void DebugUartSend(uint8_t *sData, uint16_t sLen);
|
||||
void DbgRxIrqCallback(uint8_t rData);
|
||||
|
||||
/*RS485 Ch1 - 升级通道*/
|
||||
void RS485Ch1_Config(uint32_t BaudRate);
|
||||
void RS485Ch1UartSend(uint8_t *sData, uint16_t sLen);
|
||||
uint8_t RS485Ch1UartRec(void);
|
||||
void RS485Ch1RxIrqCallback(uint8_t rData);
|
||||
|
||||
/*RS485 Ch2*/
|
||||
void RS485Ch2_Config(uint32_t BaudRate);
|
||||
void RS485Ch2UartSend(uint8_t *sData, uint16_t sLen);
|
||||
void RS485Ch2RxIrqCallback(uint8_t rData);
|
||||
|
||||
/*看门狗*/
|
||||
void FeedDog(void);
|
||||
void Error_Handler(void);
|
||||
|
||||
/*Flash操作*/
|
||||
void FlashWrite(uint32_t Addr, uint32_t *wData, uint8_t wLen);
|
||||
void ReadBootPara(BootPara rData);
|
||||
void WriteBootPara(BootPara wData);
|
||||
void EraseFlash(void);
|
||||
//extern stc_sd_handle_t stcSdhandle;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
|
||||
typedef enum {
|
||||
UPDATE_CMD_NULL,
|
||||
UPDATE_CMD_SLAVE_RES, //从机应答主机下发
|
||||
UPDATE_CMD_SLAVE_REQ_DATA, //从机请求主机下发数据
|
||||
UPDATE_CMD_MASTER_REQ = 0x81, //主机请求升级
|
||||
UPDATE_CMD_MASTRE_RES_DATA, //主机发送数据
|
||||
UPDATE_CMD_SLAVE_RES = 0x01, //从机应答命令(ACK)
|
||||
UPDATE_CMD_SLAVE_REQ_DATA = 0x02, //从机请求数据命令
|
||||
UPDATE_CMD_MASTER_REQ = 0x81, //主机升级请求
|
||||
UPDATE_CMD_MASTRE_RES_DATA = 0x82, //主机下发数据
|
||||
}UpdateCmd_m;
|
||||
|
||||
//帧头结构体
|
||||
//帧头结构体
|
||||
typedef struct {
|
||||
uint8_t Header;
|
||||
uint8_t DevMac[6];
|
||||
@@ -24,20 +24,20 @@ typedef struct {
|
||||
}__attribute__ ((packed))FrameHeader_t, *FrameH;
|
||||
|
||||
|
||||
//主机下发升级请求载荷结构体
|
||||
//主机下发升级请求载荷结构体
|
||||
typedef struct {
|
||||
uint16_t PackageNum;
|
||||
uint32_t AppSize;
|
||||
uint32_t AppCrc32;
|
||||
}__attribute__ ((packed))UpDataRequset_t, *UDReq;
|
||||
|
||||
//从机请求下发结构体
|
||||
//从机请求下发数据结构体
|
||||
typedef struct {
|
||||
uint16_t PackageIndex;
|
||||
uint32_t PackageNum;
|
||||
uint16_t PackageNum;
|
||||
}__attribute__ ((packed))GetDataRequest_t, *GDReq;
|
||||
|
||||
//主机应答下发数据结构体
|
||||
//主机应答下发数据结构体
|
||||
typedef struct {
|
||||
uint16_t PackageIndex;
|
||||
uint16_t PackageNum;
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#ifndef __SPI_FLASH_H
|
||||
#define __SPI_FLASH_H
|
||||
|
||||
#include "bsp.h"
|
||||
|
||||
#define LOG_SAV_FLAG (0xAA5555AA)
|
||||
#define LOG_INFO_SAV_FLAG (0xA55A)
|
||||
|
||||
#define SpiFlashClrNss() SPI_NSS_CLR()
|
||||
#define SpiFlashSetNss() SPI_NSS_SET()
|
||||
|
||||
#define SPIFLASH_CMD_WRITE 0x02 /* Write to Memory instruction */
|
||||
#define SPIFLASH_CMD_WRSR 0x01 /* Write Status Register instruction */
|
||||
#define SPIFLASH_CMD_WREN 0x06 /* Write enable instruction */
|
||||
#define SPIFLASH_CMD_READ 0x03 /* Read from Memory instruction */
|
||||
#define SPIFLASH_CMD_RDSR 0x05 /* Read Status Register instruction */
|
||||
#define SPIFLASH_CMD_RDID 0x9F /* Read identification */
|
||||
#define SPIFLASH_CMD_SE 0x20 /* 4KSector Erase instruction */
|
||||
#define SPIFLASH_CMD_BE 0xC7 /* Bulk Erase instruction */
|
||||
#define SPIFLASH_WIP_FLAG 0x01 /* Write In Progress (WIP) flag */
|
||||
#define SPIFLASH_DUMMY_BYTE 0xA5
|
||||
#define SPIFLASH_PAGESIZE 0x100
|
||||
#define SPIFLASH_SECTORSIZE 4096
|
||||
#define SPIFLASH_M25P128_ID 0x202018
|
||||
#define SPIFLASH_M25P64_ID 0x202017
|
||||
|
||||
void SpiFlashEraseChip(void);
|
||||
void SpiFlashEraseSector(uint32_t SectorAddr);
|
||||
void SpiFlashWriteAnyLengthData(uint8_t* wData, uint32_t wAddr, uint16_t wLen);
|
||||
void SpiFlashReadAnyLengthData(uint8_t* rData, uint32_t rAddr, uint16_t rLen);
|
||||
uint32_t SpiFlashReadId(void);
|
||||
|
||||
/* USER CODE BEGIN */
|
||||
#define SPIFLASH_SIZE 16777216
|
||||
#define SPIFLASH_SECTOR_NUM 4096
|
||||
|
||||
#define GATEWEY_PARA_SAV_ADDR 0x00
|
||||
#define GATEWEY_PARA_SAV_SECTOR 0x00
|
||||
|
||||
#define LOG_INFO_START_SECTOR 0x01
|
||||
#define LOG_SAV_START_SECTOR 0x02
|
||||
|
||||
//#if (LORA_MODULE == WH_LR36_L)
|
||||
//#define LOG_SAV_SIZE 78
|
||||
//#define LOG_SAV_NUM_SECTOR 52 //每扇区存储数量
|
||||
//#else
|
||||
//#define LOG_SAV_SIZE 78 //150
|
||||
//#define LOG_SAV_NUM_SECTOR 52 //27 //每扇区存储数量
|
||||
//#endif
|
||||
|
||||
#define LOG_SAV_SIZE_MAX 256
|
||||
#define LOG_SAV_NUM_MAX ((SPIFLASH_SECTOR_NUM - LOG_SAV_START_SECTOR) * LOG_SAV_NUM_SECTOR)
|
||||
|
||||
typedef struct {
|
||||
uint32_t LogSavFlag; //日志存储标志
|
||||
uint32_t LogIdx; //日志序号
|
||||
uint32_t LogEndAddr; //日志结束地址
|
||||
uint32_t TimeStamp; //存储时间
|
||||
}LogHeader_t, *LogHeader;
|
||||
|
||||
void SavMMC5983Calib(uint8_t *wData, uint32_t wLen);
|
||||
void ReadMMC5983Calib(uint8_t *rData, uint32_t rLen);
|
||||
|
||||
void LogInit(void);
|
||||
uint32_t ReadLogNum(void);
|
||||
uint32_t ReadLastLogEndAddr(void);
|
||||
uint32_t ReadFirstLogStartAddr(void);
|
||||
void SavLogNum(uint32_t LogNum);
|
||||
void AddLog(uint8_t *wData, uint32_t wLen);
|
||||
int ReadLog(LogHeader Header, uint8_t **wData, uint32_t LogIdx);
|
||||
int ReadPara(uint8_t *Para, uint32_t ParaLen);
|
||||
int WritePara(uint8_t *Para, uint32_t ParaLen);
|
||||
/* USER CODE END */
|
||||
|
||||
#endif
|
||||
@@ -1,126 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,709 +0,0 @@
|
||||
#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
@@ -1,87 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,905 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,546 +0,0 @@
|
||||
#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
|
||||
+244
-176
@@ -1,26 +1,16 @@
|
||||
#include <stdlib.h>
|
||||
#include "bsp.h"
|
||||
#include "ff.h"
|
||||
|
||||
/*****************************************************************************************
|
||||
* System Clock
|
||||
* System Clock - HRC 16MHz -> MPLL 200MHz (不用外部晶振)
|
||||
****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: 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);
|
||||
|
||||
@@ -34,17 +24,6 @@ static void SystemClockConfig(void)
|
||||
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;
|
||||
@@ -56,13 +35,16 @@ static void SystemClockConfig(void)
|
||||
EFM_SetLatency(EFM_LATENCY_5);
|
||||
EFM_Lock();
|
||||
|
||||
/* MPLL config (XTAL / pllmDiv * plln / PllpDiv = 200M). */
|
||||
stcMpllCfg.pllmDiv = 1ul;
|
||||
/* Config HRC and enable HRC */
|
||||
CLK_HrcCmd(Enable);
|
||||
|
||||
/* MPLL config (HRC / pllmDiv * plln / PllpDiv = 16/2*50/2 = 200M). */
|
||||
stcMpllCfg.pllmDiv = 2ul;
|
||||
stcMpllCfg.plln = 50ul;
|
||||
stcMpllCfg.PllpDiv = 2ul;
|
||||
stcMpllCfg.PllqDiv = 2ul;
|
||||
stcMpllCfg.PllrDiv = 2ul;
|
||||
CLK_SetPllSource(ClkPllSrcXTAL);
|
||||
CLK_SetPllSource(ClkPllSrcHRC);
|
||||
CLK_MpllConfig(&stcMpllCfg);
|
||||
|
||||
/* Enable MPLL. */
|
||||
@@ -76,64 +58,36 @@ static void SystemClockConfig(void)
|
||||
PWC_HS2HP();
|
||||
/* Switch system clock source to MPLL. */
|
||||
CLK_SetSysClkSource(CLKSysSrcMPLL);
|
||||
SystemCoreClockUpdate();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
* Debug Uart
|
||||
* Debug Uart (USART1)
|
||||
****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: 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)
|
||||
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;
|
||||
@@ -142,11 +96,10 @@ void DbgUart_Config(uint32_t BaudRate)
|
||||
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;
|
||||
@@ -156,12 +109,12 @@ void DbgUart_Config(uint32_t BaudRate)
|
||||
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();
|
||||
@@ -170,56 +123,28 @@ void DbgUart_Config(uint32_t BaudRate)
|
||||
if(enRet != Ok) {
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
|
||||
stcIrqRegiCfg.enIRQn = DBGUART_IRQn;
|
||||
stcIrqRegiCfg.pfnCallback = &DbgUsartRxIrqCallback;
|
||||
stcIrqRegiCfg.pfnCallback = &DBGUsartRxIrqCallback;
|
||||
stcIrqRegiCfg.enIntSrc = DBG_USART_RI_NUM;
|
||||
enIrqRegistration(&stcIrqRegiCfg);
|
||||
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
|
||||
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2);
|
||||
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_SetPriority(stcIrqRegiCfg.enIRQn, 2);
|
||||
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++) {
|
||||
@@ -229,45 +154,223 @@ void DebugUartSend(uint8_t *sData, uint16_t sLen)
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: GPIO_Config
|
||||
* 功能描述: GPIO配置函数
|
||||
* 参 数: 无
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
* RS485 Ch1 (USART2) - 升级通道, 按GateWay APP配置方式
|
||||
****************************************************************************************/
|
||||
static uint8_t RS485Ch1UartRec(void)
|
||||
{
|
||||
uint16_t u16Data = USART_RecData(RS485_CH1_USART_CH);
|
||||
return (uint8_t)u16Data;
|
||||
}
|
||||
|
||||
static void RS485Ch1UsartErrIrqCallback(void)
|
||||
{
|
||||
if(RS485_CH1_USART_CH->SR_f.ORE) {
|
||||
RS485_CH1_USART_CH->CR1_f.CORE = 1;
|
||||
USART_RecData(RS485_CH1_USART_CH);
|
||||
}
|
||||
if(RS485_CH1_USART_CH->SR_f.PE)
|
||||
RS485_CH1_USART_CH->CR1_f.CPE = 1;
|
||||
if(RS485_CH1_USART_CH->SR_f.FE)
|
||||
RS485_CH1_USART_CH->CR1_f.CFE = 1;
|
||||
}
|
||||
|
||||
static void RS485Ch1UsartRxIrqCallback(void)
|
||||
{
|
||||
uint8_t rData = RS485Ch1UartRec();
|
||||
RS485Ch1RxIrqCallback(rData);
|
||||
}
|
||||
|
||||
void RS485Ch1_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(RS485_CH1_USART_RX_PORT, RS485_CH1_USART_RX_PIN, &stcPortInit);
|
||||
PORT_Init(RS485_CH1_USART_TX_PORT, RS485_CH1_USART_TX_PIN, &stcPortInit);
|
||||
|
||||
stcInitCfg.enClkMode = UsartIntClkCkNoOutput;
|
||||
stcInitCfg.enClkDiv = UsartClkDiv_16;
|
||||
stcInitCfg.enDataLength = UsartDataBits8;
|
||||
stcInitCfg.enDirection = UsartDataLsbFirst;
|
||||
stcInitCfg.enStopBit = UsartOneStopBit;
|
||||
stcInitCfg.enParity = UsartParityNone;
|
||||
stcInitCfg.enSampleMode = UsartSampleBit8;
|
||||
stcInitCfg.enDetectMode = UsartStartBitFallEdge;
|
||||
stcInitCfg.enHwFlow = UsartRtsEnable;
|
||||
|
||||
PWC_Fcg1PeriphClockCmd(RS485_CH1_FCG1_PERIPH, Enable);
|
||||
|
||||
PORT_SetFunc(RS485_CH1_USART_RX_PORT, RS485_CH1_USART_RX_PIN, RS485_CH1_USART_RX_FUNC, Disable);
|
||||
PORT_SetFunc(RS485_CH1_USART_TX_PORT, RS485_CH1_USART_TX_PIN, RS485_CH1_USART_TX_FUNC, Disable);
|
||||
|
||||
enRet = USART_UART_Init(RS485_CH1_USART_CH, &stcInitCfg);
|
||||
if(enRet != Ok) {
|
||||
Error_Handler();
|
||||
}
|
||||
enRet = USART_SetBaudrate(RS485_CH1_USART_CH, BaudRate);
|
||||
if(enRet != Ok) {
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
stcIrqRegiCfg.enIRQn = RS485CH1_UART_IRQn;
|
||||
stcIrqRegiCfg.pfnCallback = &RS485Ch1UsartRxIrqCallback;
|
||||
stcIrqRegiCfg.enIntSrc = RS485_CH1_USART_RI_NUM;
|
||||
enIrqRegistration(&stcIrqRegiCfg);
|
||||
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2);
|
||||
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
|
||||
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
|
||||
|
||||
stcIrqRegiCfg.enIRQn = RS485CH1_UART_EI_IRQn;
|
||||
stcIrqRegiCfg.pfnCallback = &RS485Ch1UsartErrIrqCallback;
|
||||
stcIrqRegiCfg.enIntSrc = RS485_CH1_USART_EI_NUM;
|
||||
enIrqRegistration(&stcIrqRegiCfg);
|
||||
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2);
|
||||
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
|
||||
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
|
||||
|
||||
USART_FuncCmd(RS485_CH1_USART_CH, UsartTx, Enable);
|
||||
USART_FuncCmd(RS485_CH1_USART_CH, UsartRx, Enable);
|
||||
USART_FuncCmd(RS485_CH1_USART_CH, UsartRxInt, Enable);
|
||||
}
|
||||
|
||||
void RS485Ch1UartSend(uint8_t *sData, uint16_t sLen)
|
||||
{
|
||||
RS485_CH1_TX();
|
||||
for(int i = 0; i < sLen; i++) {
|
||||
USART_SendData(RS485_CH1_USART_CH, sData[i]);
|
||||
while(USART_GetStatus(RS485_CH1_USART_CH, UsartTxComplete) == Reset);
|
||||
}
|
||||
RS485_CH1_RX();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* RS485 Ch2 (USART3)
|
||||
****************************************************************************************/
|
||||
static uint8_t RS485Ch2UartRec(void)
|
||||
{
|
||||
uint16_t u16Data = USART_RecData(RS485_CH2_USART_CH);
|
||||
return (uint8_t)u16Data;
|
||||
}
|
||||
|
||||
static void RS485Ch2UsartErrIrqCallback(void)
|
||||
{
|
||||
if(RS485_CH2_USART_CH->SR_f.ORE) {
|
||||
RS485_CH2_USART_CH->CR1_f.CORE = 1;
|
||||
USART_RecData(RS485_CH2_USART_CH);
|
||||
}
|
||||
if(RS485_CH2_USART_CH->SR_f.PE)
|
||||
RS485_CH2_USART_CH->CR1_f.CPE = 1;
|
||||
if(RS485_CH2_USART_CH->SR_f.FE)
|
||||
RS485_CH2_USART_CH->CR1_f.CFE = 1;
|
||||
}
|
||||
|
||||
static void RS485Ch2UsartRxIrqCallback(void)
|
||||
{
|
||||
uint8_t rData = RS485Ch2UartRec();
|
||||
RS485Ch2RxIrqCallback(rData);
|
||||
}
|
||||
|
||||
void RS485Ch2_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(RS485_CH2_USART_RX_PORT, RS485_CH2_USART_RX_PIN, &stcPortInit);
|
||||
PORT_Init(RS485_CH2_USART_TX_PORT, RS485_CH2_USART_TX_PIN, &stcPortInit);
|
||||
|
||||
stcInitCfg.enClkMode = UsartIntClkCkNoOutput;
|
||||
stcInitCfg.enClkDiv = UsartClkDiv_16;
|
||||
stcInitCfg.enDataLength = UsartDataBits8;
|
||||
stcInitCfg.enDirection = UsartDataLsbFirst;
|
||||
stcInitCfg.enStopBit = UsartOneStopBit;
|
||||
stcInitCfg.enParity = UsartParityNone;
|
||||
stcInitCfg.enSampleMode = UsartSampleBit8;
|
||||
stcInitCfg.enDetectMode = UsartStartBitFallEdge;
|
||||
stcInitCfg.enHwFlow = UsartRtsEnable;
|
||||
|
||||
PWC_Fcg1PeriphClockCmd(RS485_CH2_FCG1_PERIPH, Enable);
|
||||
|
||||
PORT_SetFunc(RS485_CH2_USART_RX_PORT, RS485_CH2_USART_RX_PIN, RS485_CH2_USART_RX_FUNC, Disable);
|
||||
PORT_SetFunc(RS485_CH2_USART_TX_PORT, RS485_CH2_USART_TX_PIN, RS485_CH2_USART_TX_FUNC, Disable);
|
||||
|
||||
enRet = USART_UART_Init(RS485_CH2_USART_CH, &stcInitCfg);
|
||||
if(enRet != Ok) {
|
||||
Error_Handler();
|
||||
}
|
||||
enRet = USART_SetBaudrate(RS485_CH2_USART_CH, BaudRate);
|
||||
if(enRet != Ok) {
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
stcIrqRegiCfg.enIRQn = RS485CH2_UART_IRQn;
|
||||
stcIrqRegiCfg.pfnCallback = &RS485Ch2UsartRxIrqCallback;
|
||||
stcIrqRegiCfg.enIntSrc = RS485_CH2_USART_RI_NUM;
|
||||
enIrqRegistration(&stcIrqRegiCfg);
|
||||
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2);
|
||||
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
|
||||
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
|
||||
|
||||
stcIrqRegiCfg.enIRQn = RS485CH2_UART_EI_IRQn;
|
||||
stcIrqRegiCfg.pfnCallback = &RS485Ch2UsartErrIrqCallback;
|
||||
stcIrqRegiCfg.enIntSrc = RS485_CH2_USART_EI_NUM;
|
||||
enIrqRegistration(&stcIrqRegiCfg);
|
||||
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2);
|
||||
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
|
||||
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
|
||||
|
||||
USART_FuncCmd(RS485_CH2_USART_CH, UsartTx, Enable);
|
||||
USART_FuncCmd(RS485_CH2_USART_CH, UsartRx, Enable);
|
||||
USART_FuncCmd(RS485_CH2_USART_CH, UsartRxInt, Enable);
|
||||
}
|
||||
|
||||
void RS485Ch2UartSend(uint8_t *sData, uint16_t sLen)
|
||||
{
|
||||
RS485_CH2_TX();
|
||||
for(int i = 0; i < sLen; i++) {
|
||||
USART_SendData(RS485_CH2_USART_CH, sData[i]);
|
||||
while(USART_GetStatus(RS485_CH2_USART_CH, UsartTxComplete) == Reset);
|
||||
}
|
||||
RS485_CH2_RX();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* GPIO - RS485收发控制引脚 (PC7=Ch1方向, PB13=Ch2方向), PC10供电不动
|
||||
****************************************************************************************/
|
||||
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);
|
||||
|
||||
/* RS485 Ch1 方向控制 PC7: 高=发送, 低=接收 */
|
||||
PORT_Init(RS485_CH1_CTRL_PORT, RS485_CH1_CTRL_PIN, &stcPortInit);
|
||||
RS485_CH1_RX();
|
||||
|
||||
/* RS485 Ch2 方向控制 PB13 */
|
||||
PORT_Init(RS485_CH2_CTRL_PORT, RS485_CH2_CTRL_PIN, &stcPortInit);
|
||||
RS485_CH2_RX();
|
||||
}
|
||||
|
||||
void Error_Handler(void)
|
||||
@@ -276,58 +379,44 @@ void Error_Handler(void)
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* Watch Dog
|
||||
* Watch Dog - HC32F460 SWDT由ICG硬件启动, 周期喂狗
|
||||
****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: FeedDog
|
||||
* 功能描述: 看门狗喂狗函数
|
||||
* 参 数: 无
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
void FeedDog(void)
|
||||
{
|
||||
#if (WATCH_DOG == 1)
|
||||
#if (WATCH_DOG == 1)
|
||||
SWDT_RefreshCounter();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSP_Init(void)
|
||||
{
|
||||
SystemClockConfig();
|
||||
GPIO_Config();
|
||||
DbgUart_Config(500000);
|
||||
RS485Ch1_Config(500000);
|
||||
|
||||
FeedDog();
|
||||
SysTick_Init(1000);
|
||||
FeedDog();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* Flash操作
|
||||
****************************************************************************************/
|
||||
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]);
|
||||
if(EFM_SingleProgram(Addr + i * 4, wData[i]) != Ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EFM_Lock();
|
||||
}
|
||||
|
||||
static void FlashRead(uint32_t *rData, uint8_t rLen)
|
||||
static void FlashRead(uint32_t u32Addr, 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));
|
||||
}
|
||||
@@ -335,30 +424,28 @@ static void FlashRead(uint32_t *rData, uint8_t rLen)
|
||||
|
||||
void ReadBootPara(BootPara rData)
|
||||
{
|
||||
FlashRead((uint32_t *)rData, sizeof(BootPara_t));
|
||||
FlashRead(BOOT_PARA_ADDRESS, (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]);
|
||||
if(EFM_SingleProgram(BOOT_PARA_ADDRESS + i * 4, Data[i]) != Ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Lock EFM. */
|
||||
EFM_Lock();
|
||||
}
|
||||
|
||||
@@ -367,47 +454,28 @@ 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) {
|
||||
|
||||
/* 只擦APP区, 不擦参数区(BOOT_PARA_ADDRESS) */
|
||||
for(int Addr = APP_ADDRESS; Addr < BOOT_PARA_ADDRESS; Addr += FLASH_SECTOR_SIZE) {
|
||||
EFM_SectorErase(Addr);
|
||||
FeedDog();
|
||||
}
|
||||
EFM_Lock();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* User Irq CallBack
|
||||
* User Irq CallBack (weak)
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+308
-167
@@ -1,21 +1,36 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.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];
|
||||
/*设备唯一编码 - 固定在Flash 0x4000位置(协议规定: Mac[0]=VerInfo, Mac[1:3]=PrjNum, Mac[4:5]=GwNum)
|
||||
参照hc32l170_boot方式用宏构造6字节MAC, 网关APP从该地址读取本机MAC编码*/
|
||||
const uint8_t GwMacConst[6] __attribute__((section(".ARM.__at_0x00004000"))) = {
|
||||
(0x80 | GATEWAY_VER_INFO), // Mac[0] = VerInfo: Bit7固定1, Bit6:0版本
|
||||
(GATEWAY_PRJ_NUM >> 16) & 0xFF, // Mac[1]
|
||||
(GATEWAY_PRJ_NUM >> 8) & 0xFF, // Mac[2]
|
||||
GATEWAY_PRJ_NUM & 0xFF, // Mac[3]
|
||||
(GATEWAY_GW_NUM >> 8) & 0xFF, // Mac[4]
|
||||
GATEWAY_GW_NUM & 0xFF // Mac[5]
|
||||
};
|
||||
/*运行用MAC, 首次从0x4000读入, 之后从参数区同步*/
|
||||
static uint8_t s_DevMac[6] = {0};
|
||||
|
||||
uint32_t pdwCrc32Tbl[256];
|
||||
BootLoader_t BL;
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: InitCrc32Table
|
||||
* 功能描述: CRC32查表初始化
|
||||
*****************************************************************************************/
|
||||
void InitCrc32Table(uint32_t* Crc32Tbl)
|
||||
{
|
||||
for (int wCnt = 0; wCnt!= 256; wCnt++){
|
||||
for(int wCnt = 0; wCnt < 256; wCnt++) {
|
||||
uint32_t dwCrc = wCnt;
|
||||
for (int ucCnt = 0; ucCnt != 8; ucCnt++){
|
||||
if (dwCrc & 1){
|
||||
for(int ucCnt = 0; ucCnt < 8; ucCnt++) {
|
||||
if(dwCrc & 1) {
|
||||
dwCrc = (dwCrc >> 1) ^ 0xEDB88320;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
dwCrc >>= 1;
|
||||
}
|
||||
}
|
||||
@@ -23,11 +38,15 @@ void InitCrc32Table(uint32_t* Crc32Tbl)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: GetCrc32
|
||||
* 功能描述: 计算APP区CRC32校验值
|
||||
*****************************************************************************************/
|
||||
uint32_t GetCrc32(int dwLen)
|
||||
{
|
||||
uint32_t Data;
|
||||
uint32_t dwCrc32Data = 0xFFFFFFFF;
|
||||
for (int dwCnt = 0; dwCnt!= dwLen; ++dwCnt){
|
||||
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];
|
||||
@@ -35,97 +54,89 @@ uint32_t GetCrc32(int dwLen)
|
||||
return ~dwCrc32Data;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: CRC_Modbus
|
||||
* 功能描述: Modbus CRC16校验
|
||||
*****************************************************************************************/
|
||||
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length)
|
||||
{
|
||||
uint16_t crc = 0xffff;
|
||||
uint16_t crc = 0xFFFF;
|
||||
uint16_t index, i;
|
||||
|
||||
uint16_t index,i;
|
||||
|
||||
for(index = 0 ; index < length;index++) {
|
||||
for(index = 0; index < length; index++) {
|
||||
crc ^= para[index];
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(crc & 1) {
|
||||
crc >>= 1;
|
||||
crc ^= wBase;
|
||||
}
|
||||
else
|
||||
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;
|
||||
//}
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: JumpToApp
|
||||
* 功能描述: 跳转APP
|
||||
*****************************************************************************************/
|
||||
static bool JumpToApp(uint32_t AppAddr)
|
||||
{
|
||||
uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
|
||||
uint32_t u32StackTop = *((__IO uint32_t *)AppAddr);
|
||||
uint32_t JumpAddress;
|
||||
func_ptr_t JumpToApplication;
|
||||
|
||||
if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + SRAM_SIZE))) {
|
||||
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);
|
||||
|
||||
/*关闭全局中断, 停SysTick, 禁用Boot用过的NVIC中断, 避免跳转后残留中断干扰APP启动*/
|
||||
__disable_irq();
|
||||
SysTick->CTRL = 0;
|
||||
SysTick->LOAD = 0;
|
||||
SysTick->VAL = 0;
|
||||
NVIC_DisableIRQ(RS485CH1_UART_IRQn);
|
||||
NVIC_DisableIRQ(RS485CH1_UART_EI_IRQn);
|
||||
NVIC_ClearPendingIRQ(RS485CH1_UART_IRQn);
|
||||
NVIC_ClearPendingIRQ(RS485CH1_UART_EI_IRQn);
|
||||
__set_MSP(*((__IO uint32_t *)AppAddr));
|
||||
JumpToApplication();
|
||||
return true;
|
||||
}
|
||||
return Error;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AppWriteFlash
|
||||
* 功能描述: 写APP数据到Flash (每包200字节)
|
||||
*****************************************************************************************/
|
||||
void AppWriteFlash(uint32_t AddrOffset, uint8_t *wData, int wLen)
|
||||
{
|
||||
uint8_t sData[20], sLen;
|
||||
FlashWrite(APP_ADDRESS + AddrOffset, (uint32_t *)wData, wLen / 4);
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: SendResponseCmd
|
||||
* 功能描述: 发送响应帧 (0x7D + DevMac)
|
||||
*****************************************************************************************/
|
||||
static void SendResponseCmd(uint8_t Cmd, uint16_t PayLoad)
|
||||
{
|
||||
uint8_t sData[24];
|
||||
uint16_t sLen;
|
||||
uint16_t crc16;
|
||||
|
||||
FrameH Frame = (FrameH)sData;
|
||||
|
||||
Frame->Header = 0x7a;
|
||||
Frame->SlvAddr = 0x01;
|
||||
|
||||
Frame->Header = 0x7D;
|
||||
memcpy(Frame->DevMac, s_DevMac, 6);
|
||||
Frame->Cmd = Cmd;
|
||||
|
||||
if(Cmd == 0x01) {
|
||||
|
||||
if(Cmd == UPDATE_CMD_SLAVE_RES) {
|
||||
Frame->PayloadLen = 1;
|
||||
sData[sizeof(FrameHeader_t)] = PayLoad;
|
||||
sData[sizeof(FrameHeader_t)] = (uint8_t)PayLoad;
|
||||
}
|
||||
else if(Cmd == 0x02) {
|
||||
else if(Cmd == UPDATE_CMD_SLAVE_REQ_DATA) {
|
||||
Frame->PayloadLen = 4;
|
||||
GDReq GDData = (GDReq)&sData[sizeof(FrameHeader_t)];
|
||||
GDData->PackageIndex = PayLoad;
|
||||
@@ -133,25 +144,49 @@ void SendGetCmd(uint8_t Cmd, uint16_t PayLoad)
|
||||
}
|
||||
sLen = sizeof(FrameHeader_t) + Frame->PayloadLen;
|
||||
crc16 = CRC_Modbus(CRC16_BASE, sData, sLen);
|
||||
sData[sLen++] = crc16;
|
||||
sData[sLen++] = (crc16 >> 8) & 0x00ff;
|
||||
|
||||
DebugUartSend(sData, sLen);
|
||||
sData[sLen++] = crc16 & 0xFF;
|
||||
sData[sLen++] = (crc16 >> 8) & 0xFF;
|
||||
|
||||
RS485Ch1UartSend(sData, sLen);
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AnalyzeData
|
||||
* 功能描述: 解析接收帧 (0x81升级请求 / 0x82数据包)
|
||||
*****************************************************************************************/
|
||||
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) {
|
||||
|
||||
/*校验MAC地址是否匹配(支持广播全0xFF)*/
|
||||
int ret = memcmp(Frame->DevMac, s_DevMac, 6);
|
||||
if(ret != 0) {
|
||||
bool isBroadcast = true;
|
||||
for(int i = 0; i < 6; i++) {
|
||||
if(Frame->DevMac[i] != 0xFF) {
|
||||
isBroadcast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!isBroadcast) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*命令处理*/
|
||||
if(Frame->Cmd == UPDATE_CMD_MASTER_REQ) {
|
||||
if(BL.Status != BL_IDLE) {
|
||||
return false;
|
||||
}
|
||||
UDReq UpData = (UDReq)&rData[sizeof(FrameHeader_t)];
|
||||
BL.Para.AppFlag = 0;
|
||||
BL.Para.UpdateFlag = APP_UPDATE_FLAG;
|
||||
@@ -159,66 +194,169 @@ bool AnalyzeData(uint8_t *rData, uint16_t rLen)
|
||||
BL.Para.PackageCnt = UpData->PackageNum;
|
||||
BL.Para.AppSize = UpData->AppSize;
|
||||
WriteBootPara(&BL.Para);
|
||||
/*回0x01 ACK应答, 确认收到升级请求, 载荷=0x20*/
|
||||
SendResponseCmd(UPDATE_CMD_SLAVE_RES, 0x20);
|
||||
BL.BootLoader1mSDlyCnt = 20;
|
||||
BL.Status = BL_RESET;
|
||||
SendGetCmd(0x01, 1);
|
||||
return true;
|
||||
}
|
||||
else if(Frame->Cmd == 0x82) {
|
||||
if(BL.UpDateFlag == false)
|
||||
else if(Frame->Cmd == UPDATE_CMD_MASTRE_RES_DATA) {
|
||||
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);
|
||||
/*写数据到Flash*/
|
||||
AppWriteFlash(BL.AppPackageIdx * 200, &rData[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 {
|
||||
/*全部数据处理完成, 校验CRC32*/
|
||||
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.AppFlag = APP_START_FLAG;
|
||||
BL.Para.UpdateFlag = 0;
|
||||
BL.Para.DevType = DEV_TYPE;
|
||||
WriteBootPara(&BL.Para);
|
||||
BL.BootLoader1mSDlyCnt = 100;
|
||||
BL.Status = BL_RESET;
|
||||
}
|
||||
else {
|
||||
BL.Para.AppFlag = 0;
|
||||
BL.Para.UpdateFlag = 0;
|
||||
WriteBootPara(&BL.Para);
|
||||
BL.UpDateFlag = false;
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: BootLoader1mSRoutine
|
||||
* 功能描述: BootLoader 1ms定时(由SysTick中断调用)
|
||||
*****************************************************************************************/
|
||||
static void BootLoader1mSRoutine(void)
|
||||
{
|
||||
if(BL.BootLoader1mSDlyCnt) {
|
||||
BL.BootLoader1mSDlyCnt--;
|
||||
}
|
||||
|
||||
if(BL.UartRevTimeOutCnt > 0) {
|
||||
BL.UartRevTimeOutCnt--;
|
||||
}
|
||||
|
||||
BL.FeedDogDlyCnt++;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: SysTick_IrqHandler
|
||||
* 功能描述: SysTick中断
|
||||
*****************************************************************************************/
|
||||
void SysTick_IrqHandler(void)
|
||||
{
|
||||
BootLoader1mSRoutine();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: FeedDogHandler
|
||||
* 功能描述: 看门狗喂狗
|
||||
*****************************************************************************************/
|
||||
void FeedDogHandler(void)
|
||||
{
|
||||
if(BL.FeedDogDlyCnt >= 200) {
|
||||
FeedDog();
|
||||
BL.FeedDogDlyCnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: RS485Ch1RxIrqCallback
|
||||
* 功能描述: RS485通道1接收中断回调(每字节), 组帧(0x7D)
|
||||
*****************************************************************************************/
|
||||
static uint16_t rLen;
|
||||
static uint8_t rBuff[300];
|
||||
static bool Header;
|
||||
static uint16_t PayLen;
|
||||
|
||||
void RS485Ch1RxIrqCallback(uint8_t RxData)
|
||||
{
|
||||
if(BL.UartRevTimeOutCnt == 0) {
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
PayLen = 0;
|
||||
}
|
||||
BL.UartRevTimeOutCnt = 3;
|
||||
|
||||
if(Header == false && (RxData == 0x7D)) {
|
||||
Header = true;
|
||||
rLen = 0;
|
||||
PayLen = 0;
|
||||
rBuff[rLen++] = RxData;
|
||||
}
|
||||
else if(Header == true) {
|
||||
if(rLen >= sizeof(rBuff)) {
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
return;
|
||||
}
|
||||
rBuff[rLen++] = RxData;
|
||||
if(rLen == 9) {
|
||||
PayLen = RxData;
|
||||
if(PayLen > 256) {
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(rLen == sizeof(FrameHeader_t) + PayLen + 2) {
|
||||
BL.RxLen = rLen;
|
||||
memcpy(BL.RxBuff, rBuff, BL.RxLen);
|
||||
BL.RxFlag = true;
|
||||
Header = false;
|
||||
rLen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: BootLoaderLoopHandler
|
||||
* 功能描述: BootLoader主循环
|
||||
*****************************************************************************************/
|
||||
void BootLoaderLoopHandler(void)
|
||||
{
|
||||
if(BL.RxFlag) {
|
||||
{
|
||||
/*帧解析 - BL_RESET状态下不处理新帧, 避免复位等待期被0x81打断*/
|
||||
if(BL.RxFlag && BL.Status != BL_RESET) {
|
||||
BL.RxFlag = false;
|
||||
AnalyzeData(BL.RxBuff, BL.RxLen);
|
||||
TURN_OFF_STATE_LED();
|
||||
}
|
||||
|
||||
switch(BL.Status){
|
||||
|
||||
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;
|
||||
|
||||
if(JumpToApp(APP_ADDRESS) == false) {
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BL_ERASE_FLASH:
|
||||
FeedDog();
|
||||
EraseFlash();
|
||||
@@ -229,21 +367,23 @@ void BootLoaderLoopHandler(void)
|
||||
BL.RevErrCnt = 0;
|
||||
BL.UpDateFlag = true;
|
||||
break;
|
||||
|
||||
|
||||
case BL_GET_DATA:
|
||||
if(BL.BootLoader1mSDlyCnt > 0)
|
||||
if(BL.BootLoader1mSDlyCnt > 0) {
|
||||
break;
|
||||
SendGetCmd(0x02, BL.AppPackageIdx);
|
||||
}
|
||||
/*请求下一包数据 - 通过RS485应答*/
|
||||
SendResponseCmd(UPDATE_CMD_SLAVE_REQ_DATA, 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) {
|
||||
@@ -261,78 +401,79 @@ void BootLoaderLoopHandler(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: SetDefaultBootPara
|
||||
* 功能描述: 填充BootPara_t中所有默认配置(服务器/Lora/通道/RS485), 由Boot直接配置
|
||||
*****************************************************************************************/
|
||||
static void SetDefaultBootPara(BootPara_t *Para)
|
||||
{
|
||||
Para->SvrAddr[0] = GATEWAY_SVR_ADDR0;
|
||||
Para->SvrAddr[1] = GATEWAY_SVR_ADDR1;
|
||||
Para->SvrAddr[2] = GATEWAY_SVR_ADDR2;
|
||||
Para->SvrAddr[3] = GATEWAY_SVR_ADDR3;
|
||||
Para->SvrPort = GATEWAY_SVR_PORT;
|
||||
Para->LoraFreq = GATEWAY_LORA_FREQ;
|
||||
Para->Much = GATEWAY_MUCH;
|
||||
Para->Auch = GATEWAY_AUCH;
|
||||
Para->Duch = GATEWAY_DUCH;
|
||||
Para->CuchMask = GATEWAY_CUCH_MASK;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: main
|
||||
* 功能描述: 主函数
|
||||
*****************************************************************************************/
|
||||
int32_t main(void)
|
||||
{
|
||||
BSP_Init();
|
||||
InitCrc32Table(pdwCrc32Tbl);
|
||||
|
||||
|
||||
/*从固定地址0x4000读入网关MAC编码*/
|
||||
memcpy(&s_DevMac[0], &GwMacConst[0], 6);
|
||||
|
||||
/*读取boot参数*/
|
||||
ReadBootPara(&BL.Para);
|
||||
if(BL.Para.DevType != DEV_TYPE) { //设备类型错误,清除升级参数
|
||||
BL.Status = BL_IDLE;
|
||||
|
||||
/*设备判断*/
|
||||
if(BL.Para.GwMac[0] == 0xFF && BL.Para.GwMac[1] == 0xFF) {
|
||||
/*首次运行GwMac无效*/
|
||||
if(BL.Para.FirstRunFlag == 0xFFFFFFFF) {
|
||||
BL.Status = BL_START_APP;
|
||||
}
|
||||
else {
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
BL.Para.AppFlag = 0;
|
||||
BL.Para.UpdateFlag = 0;
|
||||
BL.Para.DevAddr = 0x01;
|
||||
BL.Para.DevType = DEV_TYPE;
|
||||
BL.Para.FirstRunFlag = 0;
|
||||
memcpy(&BL.Para.GwMac[0], &s_DevMac[0], 6);
|
||||
SetDefaultBootPara(&BL.Para);
|
||||
WriteBootPara(&BL.Para);
|
||||
}
|
||||
else if(BL.Para.AppFlag == APP_START_FLAG) {
|
||||
BL.Status = BL_START_APP;
|
||||
else {
|
||||
/*更新MAC地址*/
|
||||
memcpy(&s_DevMac[0], &BL.Para.GwMac[0], 6);
|
||||
|
||||
/*兼容旧参数区: 默认配置未写入(0xFF)时补默认值*/
|
||||
if(BL.Para.SvrAddr[0] == 0xFF && BL.Para.SvrAddr[1] == 0xFF) {
|
||||
SetDefaultBootPara(&BL.Para);
|
||||
WriteBootPara(&BL.Para);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
BL.Status = BL_IDLE;
|
||||
}
|
||||
}
|
||||
else if(BL.Para.UpdateFlag == APP_UPDATE_FLAG) {
|
||||
BL.Status = BL_ERASE_FLASH;
|
||||
}
|
||||
while (1) {
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,486 +0,0 @@
|
||||
#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