forked from MightyPork/TinyFrame
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTinyFrame_Types.hpp
More file actions
202 lines (158 loc) · 7.82 KB
/
TinyFrame_Types.hpp
File metadata and controls
202 lines (158 loc) · 7.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/******************************************************************************
MIT License
TinyFramePlusPlus Library.
https://github.com/marcelnabeck/TinyFramePlusPlus
Copyright(c) 2017-2018 Ondřej Hruška
Copyright(c) 2022 Marcel Nabeck
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef TINYFRAME_TYPES_HPP
#define TINYFRAME_TYPES_HPP
#include <cstdint> // uint8_t etc
#include <cstdlib> // size_t
namespace TinyFrame_n{
// Checksum type (0 = none, 8 = ~XOR, 16 = CRC16 0x8005, 32 = CRC32)
enum class CKSUM_t{
NONE = 0, // no checksums
CUSTOM8 = 1, // Custom 8-bit checksum
CUSTOM16 = 2, // Custom 16-bit checksum
CUSTOM32 = 3, // Custom 32-bit checksum
XOR = 8, // inverted xor of all payload bytes
CRC8 = 9, // Dallas/Maxim CRC8 (1-wire)
CRC16 = 10, // CRC16 with the polynomial 0x8005 (x^16 + x^15 + x^2 + 1)
CRC32 = 11, // CRC32 with the polynomial 0xedb88320
CRC8_TABLELESS = 12, // Tableless, Dallas/Maxim CRC8 (1-wire)
CRC16_TABLELESS = 13, // Tableless, CRC16 with the polynomial 0x8005 (x^16 + x^15 + x^2 + 1)
CRC32_TABLELESS = 14, // Tableless, CRC32 with the polynomial 0xedb88320
};
enum class ErrorMsg_t : uint8_t{
NONE = 0U,
MUTEX_LOCKED_TX, // TF already locked for tx!
LISTENER_ADD_ID, // Failed to add ID listener
LISTENER_ADD_TYPE, // Failed to add type listener
LISTENER_ADD_GENERIC, // Failed to add generic listener
LISTENER_REMOVE_ID, // ID listener to remove not found
LISTENER_REMOVE_TYPE, // Type listener to remove not found
LISTENER_REMOVE_GENERIC, // Generic listener to remove not found
LISTENER_RENEW_ID, // Renew listener: not found
LISTENER_EXPIRED_ID, // ID listener has expired
MESSAGE_UNKNOWN_TYPE, // Unhandled message, type
TIMEOUT_PARSER, // Parser timeout
CRC_MISMATCH_HEADER, // Rx head cksum mismatch
CRC_MISMATCH_BODY, // Body cksum mismatch
TOOLONG_PAYLOAD, // Rx payload too long
};
//region Resolve data types
typedef size_t LEN; // LEN_BYTES
typedef size_t TYPE; // TYPE_BYTES
typedef size_t ID; // ID_BYTES
// TODO: runtime checks
// #if ID_BYTES != 1 and ID_BYTES != 2 and ID_BYTES != 4
// #error Bad value of ID_BYTES, must be 1, 2 or 4
// #endif
typedef size_t TICKS; // used for timeout tick counters - should be large enough for all used timeouts
typedef size_t COUNT; // used in loops iterating over listeners
#define _FN
template <CKSUM_t CKSUM_TYPE>
struct CKSUM_TYPE_MAP;
template <> struct CKSUM_TYPE_MAP<CKSUM_t::NONE> {using type = uint8_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::XOR> {using type = uint8_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CRC8> {using type = uint8_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CUSTOM8> {using type = uint8_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CRC8_TABLELESS> {using type = uint8_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CRC16> {using type = uint16_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CUSTOM16> {using type = uint16_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CRC16_TABLELESS> {using type = uint16_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CRC32> {using type = uint32_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CUSTOM32> {using type = uint32_t;};
template <> struct CKSUM_TYPE_MAP<CKSUM_t::CRC32_TABLELESS> {using type = uint32_t;};
template<CKSUM_t CKSUM_TYPE>
using CKSUM = typename CKSUM_TYPE_MAP<CKSUM_TYPE>::type;
//endregion
//---------------------------------------------------------------------------
/** Peer bit enum (used for init) */
enum class Peer{
SLAVE = 0,
MASTER = 1,
};
/** Response from listeners */
enum class Result{
NEXT = 0, //!< Not handled, let other listeners handle it
STAY = 1, //!< Handled, stay
RENEW = 2, //!< Handled, stay, renew - useful only with listener timeout
CLOSE = 3, //!< Handled, remove self
};
// ---------------------------------- INTERNAL ----------------------------------
// This is publicly visible only to allow static init.
enum class State_ {
TFState_SOF = 0, //!< Wait for SOF
TFState_LEN, //!< Wait for Number Of Bytes
TFState_HEAD_CKSUM, //!< Wait for header Checksum
TFState_ID, //!< Wait for ID
TFState_TYPE, //!< Wait for message type
TFState_DATA, //!< Receive payload
TFState_DATA_CKSUM //!< Wait for Checksum
};
constexpr struct TinyFrameConfig_t{
//----------------------------- FRAME FORMAT ---------------------------------
// The format can be adjusted to fit your particular application needs
// If the connection is reliable, you can disable the SOF byte and checksums.
// That can save up to 9 bytes of overhead.
// ,-----+-----+-----+------+------------+- - - -+-------------,
// | SOF | ID | LEN | TYPE | HEAD_CKSUM | DATA | DATA_CKSUM |
// | 0-1 | 1-4 | 1-4 | 1-4 | 0-4 | ... | 0-4 | <- size (bytes)
// '-----+-----+-----+------+------------+- - - -+-------------'
// !!! BOTH PEERS MUST USE THE SAME SETTINGS !!!
// Adjust sizes as desired (1,2,4)
uint8_t ID_BYTES = 1U;
uint8_t LEN_BYTES = 2U;
uint8_t TYPE_BYTES = 1U;
// Use a SOF byte to mark the start of a frame
uint8_t USE_SOF_BYTE = 1U;
// Value of the SOF byte (if USE_SOF_BYTE == 1)
uint8_t SOF_BYTE = 0x01U;
// Timeout for receiving & parsing a frame
// ticks = number of calls to Tick()
uint8_t PARSER_TIMEOUT_TICKS = 10U;
}CONFIG_DEFAULT;
/** Data structure for sending / receiving messages */
struct Msg{
ID frame_id; //!< message ID
bool is_response; //!< internal flag, set when using the Respond function. frame_id is then kept unchanged.
TYPE type; //!< received or sent message type
/**
* Buffer of received data, or data to send.
*
* - If (data == nullptr) in an ID listener, that means the listener timed out and
* the user should free any userdata and take other appropriate actions.
*
* - If (data == nullptr) and length is not zero when sending a frame, that starts a multi-part frame.
* This call then must be followed by sending the payload and closing the frame.
*/
const uint8_t *data;
LEN len; //!< length of the payload
/**
* Custom user data for the ID listener.
*
* This data will be stored in the listener slot and passed to the ID callback
* via those same fields on the received message.
*/
void *userdata;
void *userdata2;
};
} // TinyFrame_n
#endif // TINYFRAME_TYPES_HPP