15uint8_t pc_cclink_sum(
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_cclink_build(uint8_t station, uint8_t command,
const uint8_t *bits,
size_t bit_len,
const uint8_t *words,
26 size_t word_len, uint8_t *out,
size_t cap)
28 if (!out || (bit_len && !bits) || (word_len && !words) || station > 63)
32 size_t n = 2 + bit_len + word_len + 1;
42 memcpy(out + i, bits, bit_len);
47 memcpy(out + i, words, word_len);
50 out[i] = pc_cclink_sum(out, i);
55bool pc_cclink_parse(
const uint8_t *frame,
size_t len, CcLinkFrame *out)
57 if (!frame || !out || len < 3)
61 size_t body = len - 1;
62 if (pc_cclink_sum(frame, body) != frame[body])
66 out->station = frame[0];
67 out->command = frame[1];
68 out->payload = (body > 2) ? (frame + 2) :
nullptr;
69 out->payload_len = body - 2;
73bool pc_cclink_get_bit(
const uint8_t *bits,
size_t bit_len,
size_t index)
75 if (!bits || index / 8 >= bit_len)
79 return (bits[index / 8] >> (index % 8)) & 1u;
82void pc_cclink_set_bit(uint8_t *bits,
size_t bit_len,
size_t index,
bool value)
84 if (!bits || index / 8 >= bit_len)
88 uint8_t
mask = (uint8_t)(1u << (index % 8));
91 bits[index / 8] |=
mask;
95 bits[index / 8] &= (uint8_t)~mask;
99uint16_t pc_cclink_get_word(
const uint8_t *words,
size_t word_len,
size_t index)
101 size_t off = index * 2;
102 if (!words || off + 1 >= word_len)
106 return (uint16_t)(words[off] | (words[off + 1] << 8));
CC-Link (CLPA) cyclic fieldbus frame codec (PC_ENABLE_CCLINK).
uint32_t mask(uint8_t width)
Mask of width low bits (width 32 handled without a 32-bit shift, which is UB).