Files
kunlun/app/grapp/iot_proto_dl645.h
2024-09-28 14:24:04 +08:00

568 lines
20 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#ifndef IOT_PROTO_DL645_H
#define IOT_PROTO_DL645_H
#include "iot_grapp.h"
#include "iot_proto_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(push) // save the pack status
#pragma pack(1) // 1 byte align
/* frame start char definition */
#define PROTO_645_START_CHAR 0x68
/* frame end char definition */
#define PROTO_645_END_CHAR 0x16
#define PROTO_645_CONTROL_POS (8)
/* the second start char position */
#define PROTO_645_SECOND_HEAD_POS (7)
/* meter address read frame length for DL/T 645-2007 */
#define PROTO_645_2007_READ_DATA_PKT_LEN 16
/* data identification length for DL/T 645-2007 */
#define PROTO_645_2007_DI_LEN (4)
/* Message direction: master->slave */
#define PROTO_645_DIR_MASTER 0
/* Message direction: slave->master */
#define PROTO_645_DIR_SLAVE 1
/* control function code definition for DL/T 645-2007 */
/* for cco report sta join or leave */
#define PROTO_645_2007_FN_REPORT_STA_STATE 0x07
/* read data control */
#define PROTO_645_2007_FN_READ_DATA 0x11
/* read data have Subsequent data frames */
#define PROTO_645_2007_FN_READ_DATA_C 0x12
#define PROTO_645_2007_FN_READ_ADDR 0x13
#define PROTO_645_2007_FN_WRITE_DATA 0x14
#define PROTO_645_2007_ERR_OK 0
#define PROTO_645_2007_ERR_OTHER 0x01
/* Follow data flag: means following data available */
#define DL645_FOLLOW_AVAILABLE (1)
/* Follow data flag: means no following data */
#define DL645_FOLLOW_INVALID (0)
/* value of resv set to 2 means DL645 frame*/
#define DL645_07_RESV0_RESV 0x02
/* Invalid di */
#define PROTO_645_INVALID_DI (0xffffffffu)
#define DL645_PARSE_FRM_MIN_LEN (12)
#define DL645_PARSE_FRM_MAX_LEN (255 + DL645_PARSE_FRM_MIN_LEN)
#define DL645_PREB_DATA_LEN (4)
#define DL645_FRM_DATA_MAX_LEN (GE_FRM_MAX_LEN)
/* nack frame length for DL/T 645-2007 */
#define DL645_NACK_FRM_LEN (13)
/* ack frame length for DL/T 645-2007 */
#define DL645_ACK_FRM_LEN (12)
#define DL645_DI_LEN 4
/************ local command, not open to customers ***********/
/* close hardware watchdog */
#define DL645_07_DI_CLOSE_HW_WATCHDOG (0x07000001u)
/* enable ckq read mode to handle ckq reading 645 meter data */
#define DL645_07_DI_CKQ_READ_MODE_EN (0x07000002u)
/* read 645 meter data in cqk mode */
#define DL645_07_DI_CKQ_MODE_READ (0x07000003u)
/* read 645 edge start time、starting/stopping time
each overtime handle */
#define DL645_07_DI_EDGE_TIME_PARAM_INNER (0x07000004u)
/*************************************************************/
/************ local command, open to customers ***************/
/* trans dl645 */
#define DL645_07_DI_DL645_TYPE (0x0800000Au)
/* trans modbus */
#define DL645_07_DI_MODBUS_TYPE (0x0800000Bu)
/* set/query uart config param */
#define DL645_07_DI_UART_PARAM (0x08000010u)
/* conrol voltage output */
#define DL645_07_DI_CTRL_VOUT (0x08000011u)
/* query device boot information */
#define DL645_07_DI_QUERY_BOOT_INFO (0x08000012u)
/* read monitor signal open/close */
#define DL645_07_DI_READ_MONITOR_SIGNAL (0x08000013u)
/* get delaytime */
#define DL645_07_DI_DELAYTIME (0x08000016u)
/* set/query edge interval time and overtime */
#define DL645_07_DI_EDGE_TIME_PARAM (0x08000020u)
/* query edge cmd count */
#define DL645_07_DI_QUERY_EDGE_CMD_CNT (0x08000021u)
/* set/query edge 645 cmd */
#define DL645_07_DI_EDGE_645_MIN_CMD (0x08000022u)
/* set/query edge 645 cmd */
#define DL645_07_DI_EDGE_645_MAX_CMD (0x0800002Bu)
/* set/query edge MODBUS cmd */
#define DL645_07_DI_EDGE_MODBUS_MIN_CMD (0x08000040u)
/* set/query edge MODBUS cmd */
#define DL645_07_DI_EDGE_MODBUS_MAX_CMD (0x08000049u)
/* set/query edge cmd buadrate */
#define DL645_07_DI_EDGE_CMD_BAUD (0x08000050u)
/*************************************************************/
#define DL645_ERR_OK (0)
#define DL645_ERR_OTHER_ERROR (0x1 << 0)
#define DL645_ERR_NO_REQ_DATA (0x1 << 1)
#define DL645_ERR_PARAMETER_ERROR (0x1 << 3)
#define DL645_LOCALMODE_CACHE_MAX_NUM (6)
#define HPLC_3P0_JY_EN_OUT12V_PIN (22)
#define HPLC_3P0_JY_EN_OUT3V3_PIN (23)
#define HPLC_3P0_JY_MONITOR_PIN (9)
#define HPLC_3P0_JY_HW_WDG_PIN (28)
/* to calc adc volt to rela data */
#define HPLC_3P0_JY_VOUT12V_RATE (11)
#define HPLC_3P0_JY_VOUT3V3_RATE (2)
#define HPLC_3P0_JY_VOUT_ON 0xAA
#define HPLC_3P0_JY_VOUT_OFF 0x55
#define HPLC_3P0_JY_INVALID_VOL 0xFF
#define HPLC_3P0_JY_MONITOR_OPEN 0xAA
#define HPLC_3P0_JY_MONITOR_CLOSE 0x55
#define HPLC_3P0_JY_CLOSE_HW_WDG 0x55
#define proto_645_2007_di_to_byte(di, ptr) \
do { \
((uint8_t *)(ptr))[3] = (uint8_t)((di) >> 24); \
((uint8_t *)(ptr))[2] = (uint8_t)((di) >> 16); \
((uint8_t *)(ptr))[1] = (uint8_t)((di) >> 8); \
((uint8_t *)(ptr))[0] = (uint8_t)((di) & 0xff); \
} while(0)
#define proto_645_2007_byte_to_di(ptr, di) \
do { \
di = (((uint8_t *)(ptr))[3] << 24) + \
(((uint8_t *)(ptr))[2] << 16) + \
(((uint8_t *)(ptr))[1] << 8) + \
((uint8_t *)(ptr))[0]; \
} while(0)
#define iot_sta_check_extend_645_di(di) \
((di == DL645_07_DI_DL645_TYPE) || (di == DL645_07_DI_MODBUS_TYPE))
/* no local cmd now */
/* TO DO */
#define iot_sta_check_local_645_di(di) \
((di == DL645_07_DI_UART_PARAM) || \
(di == DL645_07_DI_CTRL_VOUT) || \
(di == DL645_07_DI_QUERY_BOOT_INFO) || \
(di == DL645_07_DI_READ_MONITOR_SIGNAL) || \
(di == DL645_07_DI_CLOSE_HW_WATCHDOG) || \
(di == DL645_07_DI_EDGE_TIME_PARAM) || \
(di == DL645_07_DI_QUERY_EDGE_CMD_CNT) || \
((di >= DL645_07_DI_EDGE_645_MIN_CMD) && \
(di <= DL645_07_DI_EDGE_645_MAX_CMD)) || \
((di >= DL645_07_DI_EDGE_MODBUS_MIN_CMD) && \
(di <= DL645_07_DI_EDGE_MODBUS_MAX_CMD)) || \
(di == DL645_07_DI_EDGE_CMD_BAUD) || \
(di == DL645_07_DI_EDGE_TIME_PARAM_INNER))
#define iot_sta_check_local_mode_645_di(di) \
(di == DL645_07_DI_CKQ_MODE_READ)
enum proto_645_local_mode_state_e {
DL645_LOCAL_MODE_INIT = 0,
DL645_LOCAL_MODE_STARTED = 1
};
typedef struct _proto_645_ctrl
{
/* function code. see PROTO645_2007(1997)_FN_XXX */
uint8_t fn :5,
/* 0 means no following data. 1 means following data available.
* see PROTO_645_FOLLOW_XXX
*/
follow :1,
/* 0 means normal ack. 1 means abnormal ack.
* see PROTO_645_ACK_XXX
*/
ack :1,
/* direction. 1 means from primary to secondary. 0 means from secondary
* to primary,see PROTO_645_DIR_XXX
*/
dir :1;
} proto_645_ctrl_t;
typedef struct _proto_645_set_uart_param_t
{
/* di */
uint32_t di;
/* password */
uint32_t passwd;
uint32_t user_code;
uint32_t baudrate;
uint8_t parity;
uint8_t data_bit;
uint8_t stop_bit;
} proto_645_set_uart_param_t;
typedef struct _proto_645_resp_uart_param_t
{
/* di */
uint32_t di;
uint32_t baudrate;
uint8_t parity;
uint8_t data_bit;
uint8_t stop_bit;
} proto_645_resp_uart_param_t;
typedef struct _proto_645_write_vout_param_t
{
/* di */
uint32_t di;
/* password */
uint32_t passwd;
uint32_t user_code;
uint8_t v3p3_on_off;
uint8_t v12_on_off;
} proto_645_write_vout_param_t;
typedef struct _proto_645_resp_vol_info_t
{
/* di */
uint32_t di;
uint8_t v3p3_on_off;
/* unit: 100mv */
uint8_t v3p3_vol;
uint8_t v12_on_off;
/* unit: 100mv */
uint8_t v12_vol;
} proto_645_resp_vol_info_t;
typedef struct _proto_645_resp_boot_info_t
{
/* di */
uint32_t di;
uint32_t total_boot_cnt;
uint8_t last_reboot_reason;
} proto_645_resp_boot_info_t;
typedef struct _proto_645_resp_monitor_signal_t
{
/* di */
uint32_t di;
uint8_t signal;
} proto_645_resp_monitor_signal_t;
typedef struct _proto_645_close_hw_wdg_t
{
/* di */
uint32_t di;
/* password */
uint32_t passwd;
uint32_t user_code;
uint8_t close_wdg;
uint8_t src_mac[IOT_MAC_ADDR_LEN];
} proto_645_close_hw_wdg_t;
typedef struct _proto_645_set_edge_time_t
{
/* di */
uint32_t di;
/* password */
uint32_t passwd;
uint32_t user_code;
/* unit:ms */
uint16_t cmd_inverval;
/* unit:ms */
uint16_t cmd_tol_tm;
} proto_645_set_edge_time_t;
typedef struct _edge_inner_time_info_t
{
/* delay time for starting polling */
uint16_t edge_start_tm;
/* time for starting and stopping state delay */
uint16_t cmd_starting_stopping_tm;
/* for each uart rx wait time */
uint16_t cmd_each_tm;
} edge_inner_time_info_t;
typedef struct _proto_645_set_edge_time_inner_t
{
/* di */
uint32_t di;
/* password */
uint32_t passwd;
uint32_t user_code;
edge_inner_time_info_t time_info;
} proto_645_set_edge_time_inner_t;
typedef struct _proto_645_edge_dev_cmd_t
{
/* di */
uint32_t di;
/* password */
uint32_t passwd;
uint32_t user_code;
uint8_t data[0];
} proto_645_edge_dev_cmd_t;
typedef struct _parse_645_data_t
{
uint16_t frm_len;
uint16_t data_len;
uint16_t pos;
/* control code */
uint8_t control;
/* di */
uint32_t di;
/* checksum */
uint8_t cs;
uint8_t mac[IOT_MAC_ADDR_LEN];
uint32_t passwd;
uint32_t user_code;
uint8_t data[0];
} parse_645_data_t;
typedef struct _proto_645_header {
/* start char, see 645_START_CHAR */
uint8_t start_char_1;
/* target mac address */
uint8_t addr[IOT_MAC_ADDR_LEN];
/* start char, see 645_START_CHAR */
uint8_t start_char_2;
/* control code */
proto_645_ctrl_t control;
/* data length */
uint8_t len;
/* data */
uint8_t data[0];
} proto_645_header_t;
typedef struct _proto_645_tailer
{
/* check sum */
uint8_t cs;
/* end char. see 645_END_CHAR */
uint8_t end_char;
} proto_645_tailer_t;
typedef struct _proto_645_localmode_data
{
/* di */
uint32_t di;
/* mac address */
uint8_t mac[IOT_MAC_ADDR_LEN];
/* record the data from meter*/
uint8_t data[DL645_PARSE_FRM_MAX_LEN];
} proto_645_localmode_data_t;
typedef struct _proto_645_localmode_data_cache
{
uint8_t head;
uint8_t tail;
proto_645_localmode_data_t meter_data[DL645_LOCALMODE_CACHE_MAX_NUM];
} proto_645_localmode_data_cache_t;
typedef struct _devtest_645_cmd_cache
{
/* if the cmd is valid or not */
uint8_t cmd_valid;
/* buffer to hold 645 cmd */
uint8_t cmd_buf[DL645_PARSE_FRM_MAX_LEN];
/* destination mac address */
uint8_t dst_mac[IOT_MAC_ADDR_LEN];
} devtest_645_cmd_cache_t;
#pragma pack(pop)
uint8_t iot_proto_645_calc_cs(proto_645_header_t *hdr);
/* creat frame to query mac */
void iot_proto_dl645_read_addr(uint8_t *data);
/**
* @brief iot_proto_645_format_check() - To pickup DL645 frames from a buffer
* @param recv_data: point to the buffer data
* @param pdata: point to ge data get the struct which will reseive the
ge frames
* @param ret_size: point to the data length of ge_buf, if a dl645 frame is
checked, the data length of ge_buf should add the frame
length.
* @ge_len_out: point to the ge length if it exist
* @retval: - check result, GET_NO_FRAME, GET_ONE_FRAME or
GET_HALF_FRAME
*/
uint8_t iot_proto_645_format_check(mcu_data_handle_t *recv_data,
uint8_t *pdata, uint16_t *ret_size, uint16_t *ge_len_out);
/**
* @brief iot_pack_dl645_to_ge() - To pack a dl645 frame into a ge FEA0 frame,
then sned to plc
* @param data_input: point to the data frame, dl645, if the value is NULL,
need not to copy the dl645 data to ge data field
* @param pdata: point to the ge data buffer
* @param data_len: point the data length of input frame
when output means length of the ge frame
* @param mac: point to the destination mac
* @param b_conless: tx type of ge frame, connless or not
*/
void iot_pack_dl645_to_ge(uint8_t* data_input, uint8_t *pdata,
uint16_t *data_len, uint8_t* mac, bool_t b_conless);
/**
* @brief iot_proto_645_frm_format_check() check the data is 645 frame or not.
* @param data: point to the data
* @param len: len of the data
* @param integrity the integrity of 645 frm, see
proto_check_frame_result_e
* @param retval: 0:645 frame,others:not 645 frame
*/
uint8_t iot_proto_645_frm_format_check(uint8_t *data, uint16_t len,
uint8_t *integrity);
#if PLC_SUPPORT_STA_ROLE
/**
* @brief iot_proto_pack_data_to_dl645() - To pack data into a dl645 frame,
* @param data_input: point to the data frame to be packed
* @param dl645_data: point to the output dl645 data buffer
* @param data_len: point the data length of input frame
when output means length of the dl645 frame
* @param di: di of dl645 frame
* @param mac: mac of dl645 frame
* @param fn: fn of dl645 frame
* @param dir: dir of dl645 frame
*/
void iot_proto_pack_data_to_dl645(uint8_t *data_input, uint8_t *dl645_data,
uint16_t *data_len, uint32_t di, uint8_t *mac, uint8_t fn, uint8_t dir);
/**
* @brief iot_handle_ge_to_dl645() - check the FEA0 frame is include a
collector ii or not, if exist, pick the
collector ii dl645 or modbus frame out, if
it is not exist, pick the dl645 frame out.
* @param data_input: point to the FEA0 frame witch need to be check, if dl645
or modbus frame exist, copy the modbus or dl645 frame
to the head of data_output
* @param data_output: point to the position the dl645 frame should copy to
* @retval: the data length of unpacked frame
*/
uint8_t iot_handle_ge_to_dl645(uint8_t *data_input, uint8_t *data_output);
/**
* @brief iot_sta_pack_extend_dl645_to_ge() - To pack a dl645 or modbus frame
into a dl645 frame, then pack the
dl645 frame into a ge frame
* @param data_input: point to the data frame, dl645 or modbus frame
* @param ge_data: point to the ge data
* @param data_len: when input means length of the dl645 or modbus frame
when output means length of the ge frame
* @param protcotype: type of data MODBUS or DL645.
MODBUS - DI1-DI4 will be 0x0800000B
DL645 - DI1-DI4 will be 0x0800000A
* @return: err or not
*/
uint8_t iot_sta_pack_extend_dl645_to_ge(uint8_t *data_input,
uint8_t *ge_data, uint16_t *data_len, uint8_t protcotype);
/**
* @brief iot_proto_645_local_mode_timer_handler() - To get out the 645 local
read mode and clear the cache
*/
void iot_proto_645_local_mode_timer_handler(void);
#else
/**
* @brief iot_handle_cco_delay_tm_pack_ge_to_dl645() - cco handle the delay time
message from plc
* @param data_input: data in ptr
* @param data_output: data out ptr
* @return: dl645 frm len
*/
uint8_t iot_handle_cco_delay_tm_pack_ge_to_dl645(uint8_t *data_input,
uint8_t *data_output);
#endif /* PLC_SUPPORT_STA_ROLE */
void iot_proto_645_header_init(proto_645_header_t *hdr,
uint8_t *addr, uint8_t fn, uint8_t dir, uint8_t ack, uint8_t follow);
void iot_proto_645_tail_init(proto_645_header_t *hdr);
/**
* @brief iot_proto_edge_msg_output_msg_handler() - proto handle the message from
edge
* @param msg_id: the message id
* @param arg: the msg
*/
void iot_proto_edge_msg_output_msg_handler(uint8_t msg_id, void *arg);
/**
* @brief iot_proto_645_ext_sub33_handle() - sub 0x33 of the every data in the
* 645 protocol data field.
* @param ds: pointer to data field.
* @param size: length of data field.
*/
void iot_proto_645_ext_sub33_handle(uint8_t *ds, uint32_t size);
/**
* @brief iot_proto_645_ext_add33_handle() - add 0x33 of the every data in the
* 645 protocol data field.
* @param ds: pointer to data field.
* @param size: length of data field.
*/
void iot_proto_645_ext_add33_handle(uint8_t *ds, uint32_t size);
/**
* @brief iot_proto_645_get_di_by_sub33() - get di from a 645 frame.
* @param data: pointer to data field of 645 frame.
* @param len: length of data field.
* @param di: di of 645 frame.
*/
uint32_t iot_proto_645_get_di_by_sub33(uint8_t *data, uint8_t len, uint32_t *di);
/**
* @brief iot_proto_645_build_resp_msg() dl645 pack response frame.
* @param hdr: point to data which should pack a frame.
* @param in_data: to fill in the data of 645 fram
* @param len: in_data len
* @param reason: error reason, 0 is no error
* @param fn: function control code
*/
void iot_proto_645_build_resp_msg(proto_645_header_t *hdr,
uint8_t *in_data, uint8_t len, uint8_t reason, uint8_t fn);
#ifdef __cplusplus
}
#endif
#endif /* end IOT_PROTO_DL645_H */