DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
cclink.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file cclink.cpp
6 * @brief CC-Link cyclic fieldbus frame codec (see cclink.h).
7 */
8
10
11#if DETWS_ENABLE_CCLINK
12
13#include <string.h>
14
15uint8_t detws_cclink_sum(const uint8_t *bytes, size_t len)
16{
17 uint8_t sum = 0;
18 for (size_t i = 0; i < len; i++)
19 sum = (uint8_t)(sum + bytes[i]);
20 return sum;
21}
22
23size_t detws_cclink_build(uint8_t station, uint8_t command, const uint8_t *bits, size_t bit_len, const uint8_t *words,
24 size_t word_len, uint8_t *out, size_t cap)
25{
26 if (!out || (bit_len && !bits) || (word_len && !words) || station > 63)
27 return 0;
28 size_t n = 2 + bit_len + word_len + 1;
29 if (n > cap)
30 return 0;
31 size_t i = 0;
32 out[i++] = station;
33 out[i++] = command;
34 if (bit_len)
35 {
36 memcpy(out + i, bits, bit_len);
37 i += bit_len;
38 }
39 if (word_len)
40 {
41 memcpy(out + i, words, word_len);
42 i += word_len;
43 }
44 out[i] = detws_cclink_sum(out, i); // checksum over station..last data
45 i++;
46 return i;
47}
48
49bool detws_cclink_parse(const uint8_t *frame, size_t len, CcLinkFrame *out)
50{
51 if (!frame || !out || len < 3) // station + command + checksum
52 return false;
53 size_t body = len - 1;
54 if (detws_cclink_sum(frame, body) != frame[body])
55 return false;
56 out->station = frame[0];
57 out->command = frame[1];
58 out->payload = (body > 2) ? (frame + 2) : nullptr;
59 out->payload_len = body - 2;
60 return true;
61}
62
63bool detws_cclink_get_bit(const uint8_t *bits, size_t bit_len, size_t index)
64{
65 if (!bits || index / 8 >= bit_len)
66 return false;
67 return (bits[index / 8] >> (index % 8)) & 1u;
68}
69
70void detws_cclink_set_bit(uint8_t *bits, size_t bit_len, size_t index, bool value)
71{
72 if (!bits || index / 8 >= bit_len)
73 return;
74 uint8_t mask = (uint8_t)(1u << (index % 8));
75 if (value)
76 bits[index / 8] |= mask;
77 else
78 bits[index / 8] &= (uint8_t)~mask;
79}
80
81uint16_t detws_cclink_get_word(const uint8_t *words, size_t word_len, size_t index)
82{
83 size_t off = index * 2;
84 if (!words || off + 1 >= word_len)
85 return 0;
86 return (uint16_t)(words[off] | (words[off + 1] << 8)); // little-endian
87}
88
89#endif // DETWS_ENABLE_CCLINK