DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
interbus.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 interbus.cpp
6 * @brief INTERBUS summation-frame codec (see interbus.h).
7 */
8
10
11#if DETWS_ENABLE_INTERBUS
12
13uint16_t detws_interbus_fcs(const uint8_t *bytes, size_t len)
14{
15 // CRC-16/CCITT-FALSE: poly 0x1021, init 0xFFFF, no reflection, xorout 0.
16 uint16_t crc = 0xFFFF;
17 for (size_t i = 0; i < len; i++)
18 {
19 crc ^= (uint16_t)bytes[i] << 8;
20 for (int b = 0; b < 8; b++)
21 crc = (crc & 0x8000) ? (uint16_t)((crc << 1) ^ 0x1021) : (uint16_t)(crc << 1);
22 }
23 return crc;
24}
25
26size_t detws_interbus_build(const uint16_t *words, size_t word_count, uint8_t *out, size_t cap)
27{
28 if (!out || (word_count && !words))
29 return 0;
30 size_t n = 2 + word_count * 2 + 2; // loopback + words + FCS
31 if (n > cap)
32 return 0;
33 size_t i = 0;
34 out[i++] = (uint8_t)(INTERBUS_LOOPBACK >> 8);
35 out[i++] = (uint8_t)INTERBUS_LOOPBACK;
36 for (size_t w = 0; w < word_count; w++)
37 {
38 out[i++] = (uint8_t)(words[w] >> 8); // big-endian
39 out[i++] = (uint8_t)words[w];
40 }
41 uint16_t crc = detws_interbus_fcs(out, i); // FCS over loopback + words
42 out[i++] = (uint8_t)(crc >> 8);
43 out[i++] = (uint8_t)crc;
44 return i;
45}
46
47bool detws_interbus_parse(const uint8_t *frame, size_t len, uint16_t *out_words, size_t max_words, size_t *out_count)
48{
49 if (!frame || !out_words || !out_count || len < 4) // loopback + FCS minimum
50 return false;
51 if (((frame[0] << 8) | frame[1]) != INTERBUS_LOOPBACK)
52 return false;
53 if ((len - 4) % 2 != 0) // the words region must be whole 16-bit words
54 return false;
55 size_t word_count = (len - 4) / 2;
56 if (word_count > max_words)
57 return false;
58 uint16_t want = detws_interbus_fcs(frame, len - 2);
59 uint16_t got = (uint16_t)((frame[len - 2] << 8) | frame[len - 1]);
60 if (want != got)
61 return false;
62 for (size_t w = 0; w < word_count; w++)
63 out_words[w] = (uint16_t)((frame[2 + w * 2] << 8) | frame[2 + w * 2 + 1]);
64 *out_count = word_count;
65 return true;
66}
67
68#endif // DETWS_ENABLE_INTERBUS
INTERBUS summation-frame fieldbus codec (DETWS_ENABLE_INTERBUS).