ASCII Serial Com
Serial communication library between computers, microcontrollers, FPGAs, etc. Uses only ASCII. Not the most efficient protocol, but meant to be easy to read
Loading...
Searching...
No Matches
ascii_serial_com.h
Go to the documentation of this file.
1#ifndef ASCII_SERIAL_COM_H
2#define ASCII_SERIAL_COM_H
3
4/** \file */
5
6#include <inttypes.h>
7#include <stdbool.h>
8#include <stddef.h>
9#include <stdint.h>
10
11#include "asc_exception.h"
12#include "circular_buffer.h"
13
14#define MAXMESSAGELEN 64
15#define MAXDATALEN 54
16#define MAXSPAYLOADEN (MAXDATALEN - 3)
17#define NCHARCHECKSUM 4
18
19////////////////////////////////////////////////////
20////////////////////////////////////////////////////
21//////////////// Public Interface //////////////////
22////////////////////////////////////////////////////
23////////////////////////////////////////////////////
24
25/** \brief ASCII Serial Com Interface State struct
26 *
27 * Keeps track of the state of the ASCII Serial Com interface
28 *
29 * Normally, for a device, usage would go something like:
30 *
31 * 1) allocate the ascii_serial_com
32 *
33 * 2) initialize it with ascii_serial_com_init
34 *
35 * 3) Get the input buffer with ascii_serial_com_get_input_buffer and output
36 * buffer with ascii_serial_com_get_output_buffer
37 *
38 * 4) poll on the input stream/file/peripheral (and output
39 * stream/file/peripheral if the output buffer is not empty)
40 *
41 * 5) read from the input stream/file/peripheral
42 *
43 * 6) push_back or push_back_block what is read to the input_buffer
44 *
45 * 7) run ascii_serial_com_get_message_from_input_buffer, if a message is
46 * received (unpacked) then act on it (possibly reply with
47 * ascii_serial_com_put_message_in_output_buffer)
48 *
49 * 8) pop from output_buffer and write to output stream/file/peripheral
50 *
51 * 9) go back to 4)
52 *
53 */
55 circular_buffer_uint8 in_buf; /**< Input buffer */
56 circular_buffer_uint8 out_buf; /**< Output buffer */
57 uint8_t
58 raw_buffer[2 * MAXMESSAGELEN]; /**< Raw buffer used by circular buffers */
59 uint8_t
60 send_stream_frame_counter; /**< counter put in sent streaming messages */
61 uint8_t receive_stream_frame_counter; /**< counter streaming messages for
62 checking received messages */
63 bool receive_stream_frame_counter_initialized; /**< true after receiving first
64 s message */
65 bool ignoreCRCMismatch; /**< if true, ignore CRC errors. default false */
67
68/** \brief ASCII Serial Com Interface init method
69 *
70 * Initialize interface
71 *
72 * \param asc is a pointer to an uninitialized ascii_serial_com struct
73 *
74 */
76
77/** \brief ASCII Serial Com Pack and put message in output buffer
78 *
79 * Packs the message into the output format and push it onto the output buffer
80 * USER'S RESPONSIBILITY TO MAKE SURE MESSAGE CAN FIT IN OUTPUT CIRCULAR
81 * BUFFER. Message length is dataLen + (MAXMESSAGELEN-MAXDATALEN)
82 *
83 * \param asc is a pointer to an initialized ascii_serial_com struct
84 *
85 * \param ascVersion: the single char ASCII Serial Com version (probably '0')
86 *
87 * \param appVersion: the single char application version (user application
88 * info)
89 *
90 * \param command: the single char command will be written to this byte
91 *
92 * \param data: The message data
93 *
94 * \param dataLen: The length of the data
95 *
96 * May raise ASC_ERROR_DATA_TOO_LONG or the errors
97 * ascii_serial_com_compute_checksum raises
98 *
99 */
101 ascii_serial_com *asc, char ascVersion, char appVersion, char command,
102 const char *data, size_t dataLen);
103
104/** \brief ASCII Serial Com pop message from input buffer and unpack
105 *
106 * Unpacks the first message found in the input buffer
107 *
108 * \param asc is a pointer to an initialized ascii_serial_com struct
109 *
110 * All other parameters are outputs. Command will be set to \0 if no message
111 * found in buffer
112 *
113 * \param ascVersion: the single char ASCII-Serial-Com version
114 * in the message will be written here
115 *
116 * \param appVersion: the single char application version in the message will be
117 * written here
118 *
119 * \param command: the single char command will be written to this byte
120 *
121 * \param data: The message data will be put here. Should point to a MAXDATALEN
122 * long buffer
123 *
124 * \param dataLen: The length of the data put in data
125 *
126 * May raise ASC_ERROR_INVALID_FRAME or ASC_ERROR_INVALID_FRAME_PERIOD
127 */
129 char *ascVersion,
130 char *appVersion,
131 char *command, char *data,
132 size_t *dataLen);
133
134/** \brief ASCII Serial Com get input buffer
135 *
136 * Get a pointer to the input buffer.
137 *
138 * \param asc is a pointer to an initialized ascii_serial_com struct
139 *
140 * \return a pointer to the input buffer.
141 */
143
144/** \brief ASCII Serial Com get output buffer
145 *
146 * Get a pointer to the output buffer.
147 *
148 * \param asc is a pointer to an initialized ascii_serial_com struct
149 *
150 * \return a pointer to the output buffer.
151 */
154
155/** \brief ASCII Serial Com Pack and put 's' message in output buffer
156 *
157 * Packs the message into the output format and push it onto the output buffer
158 * USER'S RESPONSIBILITY TO MAKE SURE MESSAGE CAN FIT IN OUTPUT CIRCULAR
159 * BUFFER. Message length is dataLen + (MAXMESSAGELEN-MAXDATALEN)
160 *
161 * This sends streaming data. If this is a device, you should only do this
162 * once you've received an 'n' message and stop after receiving an 'f' message.
163 *
164 * \param asc is a pointer to an initialized ascii_serial_com struct
165 *
166 * \param ascVersion: the single char ASCII Serial Com version (probably '0')
167 *
168 * \param appVersion: the single char application version (user application
169 * info)
170 *
171 * \param data: The message data
172 *
173 * \param dataLen: The length of the data, must be <= MAXSPAYLOADEN
174 *
175 * May raise ASC_ERROR_DATA_TOO_LONG or the errors
176 * ascii_serial_com_compute_checksum raises
177 *
178 */
180 char ascVersion,
181 char appVersion,
182 const char *data,
183 size_t dataLen);
184
185/** \brief ASCII Serial Com put error message in out buffer
186 *
187 * Called when you want to return an error message related to some input
188 * message
189 *
190 * The same parameters as ascii_serial_com_put_message_in_output_buffer, except
191 * data isn't const (should it be const?) and errorCode
192 *
193 */
195 char ascVersion,
196 char appVersion, char command,
197 char *data, size_t dataLen,
198 enum asc_exception errorCode);
199
200void ascii_serial_com_set_ignore_CRC_mismatch(ascii_serial_com *asc);
201
202void ascii_serial_com_unset_ignore_CRC_mismatch(ascii_serial_com *asc);
203
204////////////////////////////////////////////////////
205////////////////////////////////////////////////////
206//////////////// Private Methods ///////////////////
207////////////////////////////////////////////////////
208////////////////////////////////////////////////////
209
210/** \brief ASCII Serial Com compute checksum of message
211 *
212 * Computes the checksum of the last message in the input or output buffer.
213 * Specifically finds the last substring starting with the last '>' and ending
214 * in the last '.'.
215 *
216 * \param asc is a pointer to an initialized ascii_serial_com struct
217 *
218 * \param checksumOut: pointer to already initialized buffer NCHARCHECKSUM long
219 *
220 * \param outputBuffer: if true, use output buffer, if false use input buffer
221 *
222 * Raises ASC_ERROR_INVALID_FRAME or ASC_ERROR_INVALID_FRAME_PERIOD if frame
223 * invalid
224 *
225 */
226void ascii_serial_com_compute_checksum(ascii_serial_com *asc, char *checksumOut,
227 bool outputBuffer);
228
229/** \brief convert uint8 to hex string
230 *
231 * Converts uint8 to capital hex string, 2-bytes long, zero padded
232 *
233 * \param num: the number to convert to hex
234 *
235 * \param outstr: a pointer to a 2-byte long string that will hold the result
236 *
237 * \param caps: hex letters are caps A-F if true, and lowercase a-f if false
238 *
239 */
240void convert_uint8_to_hex(uint8_t num, char *outstr, bool caps);
241
242/** \brief convert uint16 to hex string
243 *
244 * Converts uint16 to capital hex string, 4-bytes long, zero padded
245 *
246 * \param num: the number to convert to hex
247 *
248 * \param outstr: a pointer to a 4-byte long string that will hold the result
249 *
250 * \param caps: hex letters are caps A-F if true, and lowercase a-f if false
251 *
252 */
253void convert_uint16_to_hex(uint16_t num, char *outstr, bool caps);
254
255/** \brief convert uint32 to hex string
256 *
257 * Converts uint32 to capital hex string, 8-bytes long, zero padded
258 *
259 * \param num: the number to convert to hex
260 *
261 * \param outstr: a pointer to a 8-byte long string that will hold the result
262 *
263 * \param caps: hex letters are caps A-F if true, and lowercase a-f if false
264 *
265 */
266void convert_uint32_to_hex(uint32_t num, char *outstr, bool caps);
267
268/** \brief convert hex string to uint8
269 *
270 * Converts hex string to uint8
271 *
272 * \param str: a pointer to a 2-byte long string that holds the hex input
273 *
274 * \return the uint8_t
275 *
276 * May throw ASC_ERROR_NOT_HEX_CHAR
277 */
278uint8_t convert_hex_to_uint8(const char *instr);
279
280/** \brief convert hex string to uint16
281 *
282 * Converts hex string to uint16
283 *
284 * \param str: a pointer to a 4-byte long string that holds the hex input
285 *
286 * \return the uint16_t
287 *
288 * May throw ASC_ERROR_NOT_HEX_CHAR
289 *
290 */
291uint16_t convert_hex_to_uint16(const char *instr);
292
293/** \brief convert hex string to uint32
294 *
295 * Converts hex string to uint32
296 *
297 * \param str: a pointer to a 8-byte long string that holds the hex input
298 *
299 * \return the uint32_t
300 *
301 * May throw ASC_ERROR_NOT_HEX_CHAR
302 *
303 */
304uint32_t convert_hex_to_uint32(const char *instr);
305
306#endif
asc_exception
Exception type to be used with CException.
struct __ascii_serial_com_struct ascii_serial_com
ASCII Serial Com Interface State struct.
void convert_uint8_to_hex(uint8_t num, char *outstr, bool caps)
convert uint8 to hex string
circular_buffer_uint8 * ascii_serial_com_get_output_buffer(ascii_serial_com *asc)
ASCII Serial Com get output buffer.
void convert_uint16_to_hex(uint16_t num, char *outstr, bool caps)
convert uint16 to hex string
void ascii_serial_com_put_s_message_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, const char *data, size_t dataLen)
ASCII Serial Com Pack and put 's' message in output buffer.
void ascii_serial_com_init(ascii_serial_com *asc)
ASCII Serial Com Interface init method.
uint16_t convert_hex_to_uint16(const char *instr)
convert hex string to uint16
void ascii_serial_com_put_message_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, char command, const char *data, size_t dataLen)
ASCII Serial Com Pack and put message in output buffer.
void ascii_serial_com_get_message_from_input_buffer(ascii_serial_com *asc, char *ascVersion, char *appVersion, char *command, char *data, size_t *dataLen)
ASCII Serial Com pop message from input buffer and unpack.
uint8_t convert_hex_to_uint8(const char *instr)
convert hex string to uint8
uint32_t convert_hex_to_uint32(const char *instr)
convert hex string to uint32
void ascii_serial_com_put_error_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, char command, char *data, size_t dataLen, enum asc_exception errorCode)
ASCII Serial Com put error message in out buffer.
void ascii_serial_com_compute_checksum(ascii_serial_com *asc, char *checksumOut, bool outputBuffer)
ASCII Serial Com compute checksum of message.
circular_buffer_uint8 * ascii_serial_com_get_input_buffer(ascii_serial_com *asc)
ASCII Serial Com get input buffer.
void convert_uint32_to_hex(uint32_t num, char *outstr, bool caps)
convert uint32 to hex string
ASCII Serial Com Interface State struct.
circular_buffer_uint8 in_buf
uint8_t raw_buffer[2 *MAXMESSAGELEN]
circular_buffer_uint8 out_buf
circular buffer struct