11#if DETWS_ENABLE_MELSEC
16static size_t put16le(uint8_t *p, uint16_t v)
18 p[0] = (uint8_t)(v & 0xFF);
19 p[1] = (uint8_t)(v >> 8);
23static uint16_t get16le(
const uint8_t *p)
25 return (uint16_t)(p[0] | ((uint16_t)p[1] << 8));
28size_t melsec_build_read(uint8_t *buf,
size_t cap, uint8_t device_code, uint32_t head_device, uint16_t points,
29 uint16_t monitoring_timer)
31 if (!buf || cap < MELSEC_3E_READ_REQ_LEN)
34 buf[p++] = MELSEC_3E_REQ_SUBHEADER0;
35 buf[p++] = MELSEC_3E_REQ_SUBHEADER1;
36 buf[p++] = MELSEC_NETWORK_DEFAULT;
37 buf[p++] = MELSEC_PC_DEFAULT;
38 p += put16le(buf + p, MELSEC_DEST_IO_DEFAULT);
39 buf[p++] = MELSEC_DEST_MULTIDROP_DEFAULT;
42 p += put16le(buf + p, MELSEC_3E_READ_REQ_DATA_LEN);
43 p += put16le(buf + p, monitoring_timer);
44 p += put16le(buf + p, MELSEC_CMD_BATCH_READ);
45 p += put16le(buf + p, MELSEC_SUBCMD_WORD);
46 buf[p++] = (uint8_t)(head_device & 0xFF);
47 buf[p++] = (uint8_t)((head_device >> 8) & 0xFF);
48 buf[p++] = (uint8_t)((head_device >> 16) & 0xFF);
49 buf[p++] = device_code;
50 p += put16le(buf + p, points);
54bool melsec_parse_response(
const uint8_t *buf,
size_t len, MelsecResponse *out)
57 if (!buf || !out || len < MELSEC_3E_RES_MIN_LEN)
59 if (buf[0] != MELSEC_3E_RES_SUBHEADER0 || buf[1] != MELSEC_3E_RES_SUBHEADER1)
61 uint16_t data_length = get16le(buf + MELSEC_3E_RES_LEN_OFFSET);
62 if (data_length < MELSEC_ENDCODE_LEN)
64 if (MELSEC_3E_RES_DATALEN_BASE + (
size_t)data_length > len)
66 out->end_code = get16le(buf + MELSEC_3E_RES_DATALEN_BASE);
67 out->data = buf + MELSEC_3E_RES_DATA_OFFSET;
68 out->data_len = (size_t)data_length - MELSEC_ENDCODE_LEN;
Mitsubishi MELSEC MC protocol (binary 3E frame) codec (DETWS_ENABLE_MELSEC) - zero-heap batch-read re...