11#if DETWS_ENABLE_MBPLUS
15uint16_t detws_mbplus_crc(
const uint8_t *bytes,
size_t len)
18 uint16_t crc = 0xFFFF;
19 for (
size_t i = 0; i < len; i++)
22 for (
int b = 0; b < 8; b++)
23 crc = (crc & 1) ? (uint16_t)((crc >> 1) ^ 0x8408) : (uint16_t)(crc >> 1);
25 return (uint16_t)~crc;
28size_t detws_mbplus_build(uint8_t address, uint8_t control,
const uint8_t *payload,
size_t payload_len, uint8_t *out,
31 if (!out || (payload_len && !payload) || address < 1 || address > Mbplus::MBPLUS_MAX_STATION)
33 size_t n = 1 + 1 + 1 + payload_len + 2 + 1;
37 out[i++] = Mbplus::MBPLUS_FLAG;
43 memcpy(out + i, payload, payload_len);
46 uint16_t crc = detws_mbplus_crc(out + body, (i - body));
47 out[i++] = (uint8_t)crc;
48 out[i++] = (uint8_t)(crc >> 8);
49 out[i++] = Mbplus::MBPLUS_FLAG;
53bool detws_mbplus_parse(
const uint8_t *frame,
size_t len, MbPlusFrame *out)
56 if (!frame || !out || len < 6)
58 if (frame[0] != Mbplus::MBPLUS_FLAG || frame[len - 1] != Mbplus::MBPLUS_FLAG)
61 size_t body_end = len - 1;
62 size_t crc_pos = body_end - 2;
63 size_t covered = crc_pos - 1;
64 uint16_t want = detws_mbplus_crc(frame + 1, covered);
65 uint16_t got = (uint16_t)(frame[crc_pos] | (frame[crc_pos + 1] << 8));
68 out->address = frame[1];
69 out->control = frame[2];
70 out->payload = (covered > 2) ? (frame + 3) :
nullptr;
71 out->payload_len = covered - 2;
75uint8_t detws_mbplus_next_token(uint8_t current, uint8_t max_station)
79 return (current >= max_station) ? 1 : (uint8_t)(current + 1);
Modbus Plus HDLC token-bus frame codec (DETWS_ENABLE_MBPLUS).