DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
profibus.h
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 profibus.h
6 * @brief PROFIBUS-DP FDL telegram codec (DETWS_ENABLE_PROFIBUS).
7 *
8 * PROFIBUS-DP is the Siemens RS-485 master/slave fieldbus (the DP-V0 cyclic I/O exchange). Its FDL data
9 * link uses fixed telegram formats delimited by a start byte (SD):
10 *
11 * - **SD1 (0x10)**: no data - `SD1 DA SA FC FCS ED` (a request/status telegram).
12 * - **SD2 (0x68)**: variable data - `SD2 LE LEr SD2 DA SA FC [data...] FCS ED`, where LE = length of
13 * (DA + SA + FC + data), repeated as LEr for redundancy.
14 * - **SD3 (0xA2)**: fixed 8 data bytes (not built here).
15 *
16 * DA = destination, SA = source, FC = frame control. The FCS is the arithmetic sum (mod 256) of DA + SA
17 * + FC + data. ED (end delimiter) is 0x16. This builds/validates the SD1 and SD2 telegrams a DP master
18 * exchanges with slaves; the RS-485 UART timing + the DP-V0 state machine are the device step. Pure,
19 * zero heap, no stdlib, host-testable.
20 */
21
22#ifndef DETERMINISTICESPASYNCWEBSERVER_PROFIBUS_H
23#define DETERMINISTICESPASYNCWEBSERVER_PROFIBUS_H
24
25#include "ServerConfig.h"
26#include <stddef.h>
27#include <stdint.h>
28
29#if DETWS_ENABLE_PROFIBUS
30
31// PROFIBUS telegram delimiters + Frame Control values: wire bytes, so integer constants in a struct.
32struct Profibus
33{
34 static constexpr uint8_t PB_SD1 = 0x10; ///< start delimiter: no data.
35 static constexpr uint8_t PB_SD2 = 0x68; ///< start delimiter: variable data.
36 static constexpr uint8_t PB_SD3 = 0xA2; ///< start delimiter: fixed 8 data.
37 static constexpr uint8_t PB_SD4 = 0xDC; ///< token telegram.
38 static constexpr uint8_t PB_ED = 0x16; ///< end delimiter.
39 // Frame Control (FC) common values.
40 static constexpr uint8_t PB_FC_REQUEST_FDL_STATUS = 0x49; ///< request FDL status (with FCB/FCV).
41 static constexpr uint8_t PB_FC_SRD_LOW = 0x6C; ///< Send and Request Data, low priority.
42 static constexpr uint8_t PB_FC_SRD_HIGH = 0x7C; ///< Send and Request Data, high priority.
43};
44
45/** @brief PROFIBUS FCS: arithmetic sum (mod 256) of @p len bytes (DA + SA + FC + data). */
46uint8_t detws_pb_fcs(const uint8_t *bytes, size_t len);
47
48/**
49 * @brief Build an SD1 (no-data) telegram: SD1 DA SA FC FCS ED. @return 6, or 0 on overflow.
50 */
51size_t detws_pb_build_sd1(uint8_t da, uint8_t sa, uint8_t fc, uint8_t *out, size_t cap);
52
53/**
54 * @brief Build an SD2 (variable-data) telegram: SD2 LE LEr SD2 DA SA FC data FCS ED.
55 * @param data the data unit (may be null if data_len == 0).
56 * @param data_len 0..246 (the DP process data).
57 * @return the telegram length (6 + 3 + data_len... = 9 + data_len), or 0 on overflow / bad args.
58 */
59size_t detws_pb_build_sd2(uint8_t da, uint8_t sa, uint8_t fc, const uint8_t *data, size_t data_len, uint8_t *out,
60 size_t cap);
61
62/** @brief A parsed PROFIBUS telegram (data points into the input, null for SD1). */
63struct PbTelegram
64{
65 uint8_t sd; ///< the start delimiter (PB_SD1 / PB_SD2).
66 uint8_t da;
67 uint8_t sa;
68 uint8_t fc;
69 const uint8_t *data;
70 size_t data_len;
71};
72
73/** @brief Validate + parse an SD1 or SD2 telegram (FCS + ED checked). @return true if well-formed. */
74bool detws_pb_parse(const uint8_t *frame, size_t len, PbTelegram *out);
75
76#endif // DETWS_ENABLE_PROFIBUS
77#endif // DETERMINISTICESPASYNCWEBSERVER_PROFIBUS_H
User-facing configuration for DeterministicESPAsyncWebServer.