15uint8_t pc_pb_fcs(
const uint8_t *bytes,
size_t len)
18 for (
size_t i = 0; i < len; i++)
20 sum = (uint8_t)(sum + bytes[i]);
25size_t pc_pb_build_sd1(uint8_t da, uint8_t sa, uint8_t fc, uint8_t *out,
size_t cap)
31 out[0] = Profibus::PB_SD1;
35 uint8_t body[3] = {da, sa, fc};
36 out[4] = pc_pb_fcs(body, 3);
37 out[5] = Profibus::PB_ED;
41size_t pc_pb_build_sd2(uint8_t da, uint8_t sa, uint8_t fc,
const uint8_t *data,
size_t data_len, uint8_t *out,
44 if (!out || (data_len && !data) || data_len > 246)
49 size_t n = 4 + 3 + data_len + 2;
54 uint8_t le = (uint8_t)(3 + data_len);
56 out[i++] = Profibus::PB_SD2;
59 out[i++] = Profibus::PB_SD2;
65 memcpy(out + i, data, data_len);
69 out[i++] = pc_pb_fcs(out + 4, le);
70 out[i++] = Profibus::PB_ED;
74size_t pc_pb_build_sd3(uint8_t da, uint8_t sa, uint8_t fc,
const uint8_t *data, uint8_t *out,
size_t cap)
76 if (!out || !data || cap < 14)
80 out[0] = Profibus::PB_SD3;
84 memcpy(out + 4, data, 8);
85 out[12] = pc_pb_fcs(out + 1, 11);
86 out[13] = Profibus::PB_ED;
91static bool pb_parse_sd3(
const uint8_t *frame,
size_t len, PbTelegram *out)
97 if (pc_pb_fcs(frame + 1, 11) != frame[12] || frame[13] != Profibus::PB_ED)
101 out->sd = Profibus::PB_SD3;
105 out->data = frame + 4;
111static bool pb_parse_sd1(
const uint8_t *frame,
size_t len, PbTelegram *out)
114 uint8_t body[3] = {frame[1], frame[2], frame[3]};
115 if (pc_pb_fcs(body, 3) != frame[4] || frame[5] != Profibus::PB_ED)
119 out->sd = Profibus::PB_SD1;
129static bool pb_parse_sd2(
const uint8_t *frame,
size_t len, PbTelegram *out)
135 uint8_t le = frame[1];
136 if (frame[2] != le || frame[3] != Profibus::PB_SD2)
144 size_t total = 4 + le + 2;
149 if (pc_pb_fcs(frame + 4, le) != frame[4 + le] || frame[4 + le + 1] != Profibus::PB_ED)
153 out->sd = Profibus::PB_SD2;
158 out->data = dl ? (frame + 7) : nullptr;
163bool pc_pb_parse(
const uint8_t *frame,
size_t len, PbTelegram *out)
165 if (!frame || !out || len < 6)
169 if (frame[0] == Profibus::PB_SD3)
171 return pb_parse_sd3(frame, len, out);
173 if (frame[0] == Profibus::PB_SD1)
175 return pb_parse_sd1(frame, len, out);
177 if (frame[0] == Profibus::PB_SD2)
179 return pb_parse_sd2(frame, len, out);
PROFIBUS-DP FDL telegram codec (PC_ENABLE_PROFIBUS).