13uint8_t df1_bcc(
const uint8_t *data,
size_t len)
16 for (
size_t i = 0; i < len; i++)
17 s = (uint8_t)(s + data[i]);
18 return (uint8_t)(0u - s);
22static uint16_t crc16(uint16_t crc,
const uint8_t *data,
size_t len)
24 for (
size_t i = 0; i < len; i++)
27 for (
int b = 0; b < 8; b++)
28 crc = (crc & 1) ? (uint16_t)((crc >> 1) ^ 0xA001) : (uint16_t)(crc >> 1);
33uint16_t df1_crc(
const uint8_t *data,
size_t len)
35 return crc16(0x0000, data, len);
38size_t df1_build_frame(uint8_t *buf,
size_t cap,
const uint8_t *data,
size_t data_len, Df1Check check)
40 if (!buf || (data_len && !data))
42 size_t stuffed = data_len;
43 for (
size_t i = 0; i < data_len; i++)
44 if (data[i] == DF1_DLE)
46 size_t checklen = (check == Df1Check::DF1_CHECK_CRC) ? 2 : 1;
47 size_t total = 2 + stuffed + 2 + checklen;
54 for (
size_t i = 0; i < data_len; i++)
57 if (data[i] == DF1_DLE)
63 if (check == Df1Check::DF1_CHECK_CRC)
65 uint8_t etx = DF1_ETX;
66 uint16_t c = crc16(0x0000, data, data_len);
67 c = crc16(c, &etx, 1);
68 buf[p++] = (uint8_t)(c & 0xFF);
69 buf[p++] = (uint8_t)(c >> 8);
73 buf[p++] = df1_bcc(data, data_len);
78bool df1_parse_frame(
const uint8_t *buf,
size_t len, Df1Check check, uint8_t *out,
size_t out_cap,
size_t *out_len)
80 size_t checklen = (check == Df1Check::DF1_CHECK_CRC) ? 2 : 1;
81 if (!buf || !out || len < 4 + checklen)
83 if (buf[0] != DF1_DLE || buf[1] != DF1_STX)
91 if (buf[i] == DF1_DLE)
95 uint8_t next = buf[i + 1];
103 else if (next == DF1_ETX)
122 if (check == Df1Check::DF1_CHECK_CRC)
126 uint8_t etx = DF1_ETX;
127 uint16_t c = crc16(0x0000, out, o);
128 c = crc16(c, &etx, 1);
129 uint16_t got = (uint16_t)(buf[i] | ((uint16_t)buf[i + 1] << 8));
137 if (df1_bcc(out, o) != buf[i])
Allen-Bradley DF1 full-duplex frame codec (DETWS_ENABLE_DF1) - zero-heap framing + DLE byte-stuffing ...