ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
gpib.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file gpib.h
6 * @brief GPIB-over-LAN (Prologix-style) controller command codec (PROTOCORE_ENABLE_GPIB) - a zero-heap
7 * codec for the Prologix-compatible `++` command set that drives a bench of legacy IEEE-488
8 * (GPIB) instruments through a Prologix GPIB-Ethernet / GPIB-USB adapter (raw socket on TCP
9 * 1234). The bridge into pre-LAN test gear that will never speak SCPI-over-TCP directly.
10 *
11 * The device is the host: it sends `++` commands (a line starting with an unescaped `++`) to
12 * configure/control the adapter, and data lines (anything else) that the adapter forwards over GPIB
13 * to the addressed instrument. This codec builds the commands (@ref protocore_gpib_command and the typed
14 * @ref protocore_gpib_addr / @ref protocore_gpib_read / @ref protocore_gpib_spoll / @ref protocore_gpib_eos helpers),
15 * builds an escaped data line (@ref protocore_gpib_build_data - a leading ESC before a CR / LF / ESC / `+` byte in the
16 * payload, then an unescaped newline terminator), classifies a line (@ref protocore_gpib_is_command), and parses the
17 * responses (@ref protocore_gpib_parse_decimal for the serial-poll status byte / SRQ / address, @ref
18 * protocore_gpib_parse_version). Pure codec, host-tested; the socket / serial link is the application's.
19 *
20 * Reference: Prologix GPIB-ETHERNET / GPIB-USB Controller manuals (prologix.biz).
21 *
22 * @author Douglas Quigg (dstroy0)
23 * @date 2026
24 */
25
26#ifndef PROTOCORE_GPIB_H
27#define PROTOCORE_GPIB_H
28
29#include "protocore_config.h" // the entry point: protocore_types.h for the widths
30
31#if PROTOCORE_ENABLE_GPIB
32
34
35/** @brief The Prologix GPIB-Ethernet raw-socket TCP port. */
36#define PROTOCORE_GPIB_PORT 1234
37/** @brief The Prologix NetFinder UDP discovery port. */
38#define PROTOCORE_GPIB_DISCOVERY_PORT 3040
39
40/** @brief GPIB terminator appended to data sent to the instrument (`++eos`). */
41typedef enum PROTO_ENUM_PACKED
42{
43 GPIB_EOS_CRLF = 0, ///< GPIB_EOS_CR + GPIB_EOS_LF
44 GPIB_EOS_CR = 1, ///< GPIB_EOS_CR
45 GPIB_EOS_LF = 2, ///< GPIB_EOS_LF
46 GPIB_EOS_PROTOCORE_NONE = 3, ///< none (use for binary payloads)
47} GpibEos;
48
49/** @brief Read-termination mode (`++read`). */
50typedef enum PROTO_ENUM_PACKED
51{
52 UNTIL_TIMEOUT, ///< `++read` - read until the inter-character timeout only (NOT until EOI)
53 UNTIL_EOI, ///< `++read eoi` - read until EOI or timeout
54 UNTIL_CHAR, ///< `++read <char>` - read until the given character or timeout
55} GpibRead;
56
57/**
58 * @brief Build a generic `++` command line: `"++"` + @p cmd + `'\n'` (e.g. `protocore_gpib_command(...,
59 * "mode 1")` -> `"++mode 1\n"`, `"eoi 1"`, `"clr"`, `"ver"`, `"read_tmo_ms 500"`).
60 * @return characters written (excluding the NUL), or 0 on overflow / bad input.
61 */
62size_t protocore_gpib_command(char *buf, size_t cap, const char *cmd);
63
64/**
65 * @brief Build `++addr <pad>[ <sad>]` - set the instrument GPIB address.
66 * @param pad primary address (0-30).
67 * @param sad optional secondary address (96-126); pass < 0 for none.
68 * @return characters written (excluding NUL), or 0 on overflow / bad @p pad.
69 */
70size_t protocore_gpib_addr(char *buf, size_t cap, uint8_t pad, int sad);
71
72/**
73 * @brief Build a `++read` command in one of its three forms.
74 * @param ch the read-until character (decimal), used only when @p mode is @ref UNTIL_CHAR.
75 * @return characters written (excluding NUL), or 0 on overflow.
76 */
77size_t protocore_gpib_read(char *buf, size_t cap, GpibRead mode, uint8_t ch);
78
79/**
80 * @brief Build `++spoll` (serial poll). With @p pad < 0, polls the currently-addressed instrument;
81 * otherwise `++spoll <pad>[ <sad>]`. The response is the status byte as a decimal string.
82 * @return characters written (excluding NUL), or 0 on overflow.
83 */
84size_t protocore_gpib_spoll(char *buf, size_t cap, int pad, int sad);
85
86/** @brief Build `++eos <n>` - the GPIB terminator appended to instrument data. */
87size_t protocore_gpib_eos(char *buf, size_t cap, GpibEos eos);
88
89/**
90 * @brief Build an escaped data line to send to the addressed instrument: each CR (13) / LF (10) /
91 * ESC (27) / `+` (43) byte in @p src is preceded by an ESC (27), then an unescaped `'\n'`
92 * line terminator is appended. (Data received FROM instruments is never escaped.)
93 * @return total bytes written (NOT NUL-terminated - the payload may be binary), or 0 on overflow.
94 */
95size_t protocore_gpib_build_data(uint8_t *buf, size_t cap, const uint8_t *src, size_t len);
96
97/** @brief True if @p line is a controller command (starts with an unescaped `++`), else it is data. */
98proto_bool protocore_gpib_is_command(const char *line, size_t len);
99
100/**
101 * @brief Parse a decimal integer response (trims surrounding spaces / CR / LF) - the `++spoll`
102 * status byte, the `++srq` 0/1, or a `++addr` primary address.
103 * @return true on a clean decimal; false otherwise.
104 */
105proto_bool protocore_gpib_parse_decimal(const char *s, size_t len, uint32_t *out);
106
107/**
108 * @brief Parse a `++addr` query response: a primary address, optionally a space + secondary.
109 * @param pad receives the primary address.
110 * @param sad receives the secondary address, or -1 if none was present.
111 * @return true on a clean response; false otherwise.
112 */
113proto_bool protocore_gpib_parse_addr(const char *s, size_t len, uint8_t *pad, int *sad);
114
115/**
116 * @brief Parse a `++ver` response: locate the version token after `"version "`. @p ver points INTO
117 * @p s (trailing CR/LF trimmed from @p ver_len).
118 * @return true if a version token was found; false otherwise.
119 */
120proto_bool protocore_gpib_parse_version(const char *s, size_t len, const char **ver, size_t *ver_len);
121
123
124#endif // PROTOCORE_ENABLE_GPIB
125
126#endif // PROTOCORE_GPIB_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97