diff --git a/lark1s/lark1s.c b/lark1s/lark1s.c index eafc539..3422428 100644 --- a/lark1s/lark1s.c +++ b/lark1s/lark1s.c @@ -12,13 +12,9 @@ #define LARK1S_SIZE_DATA (52) /* writable register */ #define LARK1S_REG_GAS3_CALI_ZERO_RECORD (0x1012) -#define LARK1S_SIZE_GAS3_CALI_ZERO_RECORD (1) #define LARK1S_REG_GAS3_CALI_SPAN_RECORD (0x1028) -#define LARK1S_SIZE_GAS3_CALI_SPAN_RECORD (1) #define LARK1S_REG_GAS3_CALI_ACTIVE (0x103E) -#define LARK1S_SIZE_GAS3_CALI_ACTIVE (1) #define LARK1S_REG_GAS3_CALI_RESTORE (0x1042) -#define LARK1S_SIZE_GAS3_CALI_RESTORE (1) /* status register */ #define LARK1S_REG_STATUS (0x0600) #define LARK1S_SIZE_STATUS (11) @@ -108,9 +104,6 @@ static int lark1s_frame_check(uint8_t *p, uint16_t len) { struct crc16_result_s crc; - if (len < 5) { - return LARK1S_PARSE_FRAME_ERROR; - } if (p[0] != mb_addr) { return LARK1S_PARSE_MB_ADDR_NOT_MATCH; } @@ -154,6 +147,9 @@ int lark1s_parse_sn(uint8_t *buffer, int length, char *sn) int ret; int i = 0; + if (length != LARK1S_SIZE_SN * 2 + 5) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; @@ -195,6 +191,9 @@ int lark1s_parse_gas3_info(uint8_t *buffer, int length, struct lark1s_gas_info_s int ret; int i = 0; + if (length != LARK1S_SIZE_GAS3_INFO * 2 + 5) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; @@ -243,6 +242,9 @@ int lark1s_parse_data(uint8_t *buffer, int length, struct lark1s_data_s *data) int ret; int i = 0; + if (length != LARK1S_SIZE_DATA * 2 + 5) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; @@ -264,67 +266,222 @@ int lark1s_parse_data(uint8_t *buffer, int length, struct lark1s_data_s *data) return LARK1S_PARSE_OK; } -int lark1s_req_gas3_cali_zero_record(uint8_t *buffer); +int lark1s_req_gas3_cali_zero_record(uint8_t *buffer, uint16_t type) +{ + struct crc16_result_s crc; + int i = 0; + + buffer[i++] = mb_addr; + buffer[i++] = MODBUS_FUNCTION_CODE_WRITE_SINGLE; + buffer[i++] = (LARK1S_REG_GAS3_CALI_ZERO_RECORD >> 8) & 0xFF; + buffer[i++] = LARK1S_REG_GAS3_CALI_ZERO_RECORD & 0xFF; + buffer[i++] = (type >> 8) & 0xFF; + buffer[i++] = type & 0xFF; + crc16_8005_calc(buffer, i, &crc); + buffer[i++] = crc.crcl; + buffer[i++] = crc.crch; + + return i; +} + int lark1s_parse_gas3_cali_zero_record(uint8_t *buffer, int length) { int ret; + int i = 0; + if (length != 8) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; } + i++; + if (buffer[i++] != MODBUS_FUNCTION_CODE_WRITE_SINGLE) { + return LARK1S_PARSE_FUNCTION_CODE_ERROR; + } + if(LARK1S_REG_GAS3_CALI_ZERO_RECORD != MB_GET_HWORD(buffer + i)) { + return LARK1S_PARSE_CALI_REG_ERROR; + } return LARK1S_PARSE_OK; } -int lark1s_req_gas3_cali_span_record(uint8_t *buffer, uint32_t concentration); +int lark1s_req_gas3_cali_span_record(uint8_t *buffer, uint32_t concentration) +{ + struct crc16_result_s crc; + int i = 0; + + buffer[i++] = mb_addr; + buffer[i++] = MODBUS_FUNCTION_CODE_WRITE_MULTI; + buffer[i++] = (LARK1S_REG_GAS3_CALI_SPAN_RECORD >> 8) & 0xFF; + buffer[i++] = LARK1S_REG_GAS3_CALI_SPAN_RECORD & 0xFF; + buffer[i++] = 0; + buffer[i++] = 2; /* register number */ + buffer[i++] = 4; /* data byte number */ + buffer[i++] = (concentration >> 24) & 0xFF; + buffer[i++] = (concentration >> 16) & 0xFF; + buffer[i++] = (concentration >> 8) & 0xFF; + buffer[i++] = concentration & 0xFF; + crc16_8005_calc(buffer, i, &crc); + buffer[i++] = crc.crcl; + buffer[i++] = crc.crch; + + return i; +} + int lark1s_parse_gas3_cali_span_record(uint8_t *buffer, int length) { int ret; + int i = 0; + if (length != 8) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; } + i++; + if (buffer[i++] != MODBUS_FUNCTION_CODE_WRITE_MULTI) { + return LARK1S_PARSE_FUNCTION_CODE_ERROR; + } + if(LARK1S_REG_GAS3_CALI_SPAN_RECORD != MB_GET_HWORD(buffer + i)) { + return LARK1S_PARSE_CALI_REG_ERROR; + } + if(2 != MB_GET_HWORD(buffer + i + 2)) { + return LARK1S_PARSE_DATA_LENGTH_ERROR; + } return LARK1S_PARSE_OK; } -int lark1s_req_gas3_cali_active(uint8_t *buffer); +int lark1s_req_gas3_cali_active(uint8_t *buffer, uint16_t type) +{ + struct crc16_result_s crc; + int i = 0; + + buffer[i++] = mb_addr; + buffer[i++] = MODBUS_FUNCTION_CODE_WRITE_SINGLE; + buffer[i++] = (LARK1S_REG_GAS3_CALI_ACTIVE >> 8) & 0xFF; + buffer[i++] = LARK1S_REG_GAS3_CALI_ACTIVE & 0xFF; + buffer[i++] = (type >> 8) & 0xFF; + buffer[i++] = type & 0xFF; + crc16_8005_calc(buffer, i, &crc); + buffer[i++] = crc.crcl; + buffer[i++] = crc.crch; + + return i; +} + int lark1s_parse_gas3_cali_active(uint8_t *buffer, int length) { int ret; + int i = 0; + if (length != 8) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; } + i++; + if (buffer[i++] != MODBUS_FUNCTION_CODE_WRITE_SINGLE) { + return LARK1S_PARSE_FUNCTION_CODE_ERROR; + } + if(LARK1S_REG_GAS3_CALI_ACTIVE != MB_GET_HWORD(buffer + i)) { + return LARK1S_PARSE_CALI_REG_ERROR; + } return LARK1S_PARSE_OK; } -int lark1s_req_gas3_cali_restore(uint8_t *buffer); +int lark1s_req_gas3_cali_restore(uint8_t *buffer) +{ + struct crc16_result_s crc; + int i = 0; + + buffer[i++] = mb_addr; + buffer[i++] = MODBUS_FUNCTION_CODE_WRITE_SINGLE; + buffer[i++] = (LARK1S_REG_GAS3_CALI_RESTORE >> 8) & 0xFF; + buffer[i++] = LARK1S_REG_GAS3_CALI_RESTORE & 0xFF; + buffer[i++] = 0x00; + buffer[i++] = 0xFF; + crc16_8005_calc(buffer, i, &crc); + buffer[i++] = crc.crcl; + buffer[i++] = crc.crch; + + return i; +} + int lark1s_parse_gas3_cali_restore(uint8_t *buffer, int length) { int ret; + int i = 0; + if (length != 8) { + return LARK1S_PARSE_FRAME_ERROR; + } ret = lark1s_frame_check(buffer, length); if (ret) { return ret; } + i++; + if (buffer[i++] != MODBUS_FUNCTION_CODE_WRITE_SINGLE) { + return LARK1S_PARSE_FUNCTION_CODE_ERROR; + } + if(LARK1S_REG_GAS3_CALI_RESTORE != MB_GET_HWORD(buffer + i)) { + return LARK1S_PARSE_CALI_REG_ERROR; + } return LARK1S_PARSE_OK; } -int lark1s_req_status(uint8_t *buffer); +int lark1s_req_status(uint8_t *buffer) +{ + struct crc16_result_s crc; + int i = 0; + + buffer[i++] = mb_addr; + buffer[i++] = MODBUS_FUNCTION_CODE_READ_INPUT; + buffer[i++] = (LARK1S_REG_STATUS >> 8) & 0xFF; + buffer[i++] = LARK1S_REG_STATUS & 0xFF; + buffer[i++] = (LARK1S_SIZE_STATUS >> 8) & 0xFF; + buffer[i++] = LARK1S_SIZE_STATUS & 0xFF; + crc16_8005_calc(buffer, i, &crc); + buffer[i++] = crc.crcl; + buffer[i++] = crc.crch; + + return i; +} + int lark1s_parse_status(uint8_t *buffer, int length, struct lark1s_status_s *status) { int ret; + int i = 0; ret = lark1s_frame_check(buffer, length); if (ret) { return ret; } + i++; + if (buffer[i++] != MODBUS_FUNCTION_CODE_READ_INPUT) { + return LARK1S_PARSE_FUNCTION_CODE_ERROR; + } + if (buffer[i++] != LARK1S_SIZE_STATUS * 2) { + return LARK1S_PARSE_DATA_LENGTH_ERROR; + } + status->zero_record[0] = MB_GET_HWORD(buffer + i + 0); + status->zero_record[1] = MB_GET_HWORD(buffer + i + 2); + status->zero_record[2] = MB_GET_HWORD(buffer + i + 4); + status->zero_record[3] = MB_GET_HWORD(buffer + i + 6); + status->span_record[0] = MB_GET_HWORD(buffer + i + 8); + status->span_record[1] = MB_GET_HWORD(buffer + i + 10); + status->span_record[2] = MB_GET_HWORD(buffer + i + 12); + status->span_record[3] = MB_GET_HWORD(buffer + i + 14); + status->active = MB_GET_HWORD(buffer + i + 16); + status->restore = MB_GET_HWORD(buffer + i + 18); return LARK1S_PARSE_OK; } diff --git a/lark1s/lark1s.h b/lark1s/lark1s.h index c0f234a..99f55b7 100644 --- a/lark1s/lark1s.h +++ b/lark1s/lark1s.h @@ -9,6 +9,11 @@ #define LARK1S_PARSE_FRAME_ERROR (3) #define LARK1S_PARSE_CRC_ERROR (4) #define LARK1S_PARSE_DATA_LENGTH_ERROR (5) +#define LARK1S_PARSE_CALI_REG_ERROR (6) + +#define LARK1S_CALI_ZERO (0xFFFE) +#define LARK1S_CALI_SPAN (0xFFFD) +#define LARK1S_CALI_ZERO_SPAN (0xFFFC) struct lark1s_gas_info_s { uint32_t gas_id; @@ -60,11 +65,11 @@ int lark1s_req_gas3_info(uint8_t *buffer); int lark1s_parse_gas3_info(uint8_t *buffer, int length, struct lark1s_gas_info_s *info); int lark1s_req_data(uint8_t *buffer); int lark1s_parse_data(uint8_t *buffer, int length, struct lark1s_data_s *data); -int lark1s_req_gas3_cali_zero_record(uint8_t *buffer); +int lark1s_req_gas3_cali_zero_record(uint8_t *buffer, uint16_t type); int lark1s_parse_gas3_cali_zero_record(uint8_t *buffer, int length); int lark1s_req_gas3_cali_span_record(uint8_t *buffer, uint32_t concentration); int lark1s_parse_gas3_cali_span_record(uint8_t *buffer, int length); -int lark1s_req_gas3_cali_active(uint8_t *buffer); +int lark1s_req_gas3_cali_active(uint8_t *buffer, uint16_t type); int lark1s_parse_gas3_cali_active(uint8_t *buffer, int length); int lark1s_req_gas3_cali_restore(uint8_t *buffer); int lark1s_parse_gas3_cali_restore(uint8_t *buffer, int length); diff --git a/linux/main.c b/linux/main.c index 093b41e..991080e 100644 --- a/linux/main.c +++ b/linux/main.c @@ -7,9 +7,9 @@ #include #include "../lark1s/lark1s.h" -#define MB_ADDRESS 9 -#define MB_RESP_TIME 1 -#define BUFFER_SIZE 1024 +#define MB_ADDRESS (7) +#define MB_RESP_TIME (1) +#define BUFFER_SIZE (1024) uint8_t buffer_w[BUFFER_SIZE]; uint8_t buffer_r[BUFFER_SIZE]; @@ -23,15 +23,20 @@ void print_sn(int fd, uint8_t *out, uint8_t *in) write(fd, out, ret); } else { printf("Error: lark1s_req_sn failed\r\n"); + return; } sleep(MB_RESP_TIME); ret = read(fd, in, BUFFER_SIZE); ret = lark1s_parse_sn(in, ret, sn); if (ret) { printf("Error: lark1s_parse_sn failed, %d\r\n", ret); + return; } else { printf("SN: "); for (int j = 0; j < 16; j++) { + if (sn[j] <= ' ') { + continue; + } printf("%c", sn[j]); } printf("\r\n"); @@ -48,22 +53,30 @@ void print_gas3_info(int fd, uint8_t *out, uint8_t *in) write(fd, out, ret); } else { printf("Error: lark1s_req_gas3_info failed\r\n"); + return; } sleep(MB_RESP_TIME); ret = read(fd, in, BUFFER_SIZE); ret = lark1s_parse_gas3_info(in, ret, &info); if (ret) { printf("Error: lark1s_parse_gas_info failed, %d\r\n", ret); + return; } else { printf("gas3_info.gas_id: %d\r\n", info.gas_id); printf("gas3_info.gas_name: "); for (int j = 0; j < 12; j++) { + if (info.gas_name[j] <= ' ') { + continue; + } printf("%c", info.gas_name[j]); } printf("\r\n"); printf("gas3_info.unit_id: %d\r\n", info.unit_id); printf("gas3_info.unit_name: "); for (int j = 0; j < 8; j++) { + if (info.unit_name[j] <= ' ') { + continue; + } printf("%c", info.unit_name[j]); } printf("\r\n"); @@ -82,12 +95,14 @@ void print_data(int fd, uint8_t *out, uint8_t *in) write(fd, out, ret); } else { printf("Error: lark1s_req_data failed\r\n"); + return; } sleep(MB_RESP_TIME); ret = read(fd, in, BUFFER_SIZE); ret = lark1s_parse_data(in, ret, &data); if (ret) { printf("Error: lark1s_parse_data failed, %d\r\n", ret); + return; } else { printf("data.det_temp: %d\r\n", data.det_temp); printf("data.air_pressure: %d\r\n", data.air_pressure); @@ -98,8 +113,253 @@ void print_data(int fd, uint8_t *out, uint8_t *in) } } +void print_status(int fd, uint8_t *out, uint8_t *in) +{ + struct lark1s_status_s status; + int ret; + + ret = lark1s_req_status(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_status failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_status(in, ret, &status); + if (ret) { + printf("Error: lark1s_parse_status failed, %d\r\n", ret); + return; + } else { + printf("status.zero_record: %d\r\n", status.zero_record[2]); + printf("status.span_record: %d\r\n", status.span_record[2]); + printf("status.active: %d\r\n", status.active); + printf("status.restore: %d\r\n", status.restore); + } +} + +void cali_zero(int fd, uint8_t *out, uint8_t *in) +{ + struct lark1s_status_s status; + int ret; + + /* zero record */ + ret = lark1s_req_gas3_cali_zero_record(out, LARK1S_CALI_ZERO); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_gas3_cali_zero_record failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_gas3_cali_zero_record(in, ret); + if (ret) { + printf("Error: lark1s_parse_gas3_cali_zero_record failed, %d\r\n", ret); + return; + } + /* get zero record status */ + ret = lark1s_req_status(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_status failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_status(in, ret, &status); + if (ret) { + printf("Error: lark1s_parse_status failed, %d\r\n", ret); + return; + } else { + if (0 == status.zero_record[2]) { + printf("cali zero record success\r\n"); + } else { + printf("cali zero record failed, ret = %d\r\n", status.zero_record[2]); + return; + } + } + /* zero active */ + ret = lark1s_req_gas3_cali_active(out, LARK1S_CALI_ZERO); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_gas3_cali_zero_active failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_gas3_cali_active(in, ret); + if (ret) { + printf("Error: lark1s_parse_gas3_cali_zero_active failed, %d\r\n", ret); + return; + } + /* get zero active status */ + ret = lark1s_req_status(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_status failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_status(in, ret, &status); + if (ret) { + printf("Error: lark1s_parse_status failed, %d\r\n", ret); + return; + } else { + if (0 == status.active) { + printf("cali zero active success\r\n"); + } else { + printf("cali zero active failed, ret = %d\r\n", status.active); + return; + } + } +} + +void cali_span(int fd, uint8_t *out, uint8_t *in, int concentration) +{ + struct lark1s_status_s status; + int ret; + + /* span record */ + ret = lark1s_req_gas3_cali_span_record(out, concentration); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_gas3_cali_span_record failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_gas3_cali_span_record(in, ret); + if (ret) { + printf("Error: lark1s_parse_gas3_cali_span_record failed, %d\r\n", ret); + return; + } + /* get span record status */ + ret = lark1s_req_status(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_status failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_status(in, ret, &status); + if (ret) { + printf("Error: lark1s_parse_status failed, %d\r\n", ret); + return; + } else { + if (0 == status.span_record[2]) { + printf("cali span record success\r\n"); + } else { + printf("cali span record failed, ret = %d\r\n", status.span_record[2]); + return; + } + } + /* span active */ + ret = lark1s_req_gas3_cali_active(out, LARK1S_CALI_SPAN); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_gas3_cali_span_active failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_gas3_cali_active(in, ret); + if (ret) { + printf("Error: lark1s_parse_gas3_cali_span_active failed, %d\r\n", ret); + return; + } + /* get span active status */ + ret = lark1s_req_status(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_status failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_status(in, ret, &status); + if (ret) { + printf("Error: lark1s_parse_status failed, %d\r\n", ret); + return; + } else { + if (0 == status.active) { + printf("cali span active success\r\n"); + } else { + printf("cali span active failed, ret = %d\r\n", status.active); + return; + } + } +} + +void cali_restore(int fd, uint8_t *out, uint8_t *in) +{ + struct lark1s_status_s status; + int ret; + + ret = lark1s_req_gas3_cali_restore(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_gas3_cali_restore failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_gas3_cali_restore(in, ret); + if (ret) { + printf("Error: lark1s_parse_gas3_cali_restore failed, %d\r\n", ret); + return; + } + /* get restore status */ + ret = lark1s_req_status(out); + if (ret) { + write(fd, out, ret); + } else { + printf("Error: lark1s_req_status failed\r\n"); + return; + } + sleep(MB_RESP_TIME); + ret = read(fd, in, BUFFER_SIZE); + ret = lark1s_parse_status(in, ret, &status); + if (ret) { + printf("Error: lark1s_parse_status failed, %d\r\n", ret); + return; + } else { + if (0 == status.active) { + printf("cali restore success\r\n"); + } else { + printf("cali restore failed, ret = %d\r\n", status.active); + return; + } + } +} + +void print_help(void) +{ + printf("Usage:\r\n"); + printf("1: print sn\r\n"); + printf("2: print gas3 info\r\n"); + printf("3: print data\r\n"); + printf("4: print status\r\n"); + printf("5: cali restore\r\n"); + printf("0: cali zero\r\n"); + printf("other number: cali span\r\n"); + printf("\r\n"); +} + int main(void) { int fd; + int sel; struct termios options; fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY | O_NDELAY); @@ -118,12 +378,28 @@ int main(void) { tcsetattr(fd, TCSANOW, &options); lark1s_set_mb_address(MB_ADDRESS); + print_help(); while (1) { - print_sn(fd, buffer_w, buffer_r); - print_gas3_info(fd, buffer_w, buffer_r); - print_data(fd, buffer_w, buffer_r); + scanf("%d", &sel); + if (sel == 1) { + print_sn(fd, buffer_w, buffer_r); + } else if (sel == 2) { + print_gas3_info(fd, buffer_w, buffer_r); + } else if (sel == 3) { + print_data(fd, buffer_w, buffer_r); + } else if (sel == 4) { + print_status(fd, buffer_w, buffer_r); + } else if (sel == 5) { + cali_restore(fd, buffer_w, buffer_r); + } else if (sel == 0) { + cali_zero(fd, buffer_w, buffer_r); + } else if (sel > 0) { + cali_span(fd, buffer_w, buffer_r, sel); + } else { + } printf("\r\n"); + print_help(); fflush(stdout); }