Prusa-MMU-Private
PrusaMultiMaterialUpgradev3firmwareforMK3SMK4
protocol.h
Go to the documentation of this file.
1 #pragma once
3 #include <stdint.h>
4 #include "crc.h"
5 
6 namespace modules {
7 
11 
12 namespace protocol {
13 
15 enum class RequestMsgCodes : uint8_t {
16  unknown = 0,
17  Query = 'Q',
18  Tool = 'T',
19  Load = 'L',
20  Mode = 'M',
21  Unload = 'U',
22  Reset = 'X',
23  Finda = 'P',
24  Version = 'S',
25  Button = 'B',
26  Eject = 'E',
27  Write = 'W',
28  Cut = 'K',
29  FilamentType = 'F',
30  FilamentSensor = 'f',
31  Home = 'H',
32  Read = 'R'
33 };
34 
36 enum class ResponseMsgParamCodes : uint8_t {
37  unknown = 0,
38  Processing = 'P',
39  Error = 'E',
40  Finished = 'F',
41  Accepted = 'A',
42  Rejected = 'R',
43  Button = 'B' // the MMU registered a button press and is sending it to the printer for processing
44 };
45 
47 struct RequestMsg {
49  uint8_t value;
50  uint16_t value2;
51 
55  uint8_t crc8;
56 
57  constexpr uint8_t ComputeCRC8() const {
58  uint8_t crc = 0;
59  crc = modules::crc::CRC8::CCITT_updateCX(0, (uint8_t)code);
60  crc = modules::crc::CRC8::CCITT_updateCX(crc, value);
62  return crc;
63  }
64 
67  inline constexpr RequestMsg(RequestMsgCodes code, uint8_t value)
68  : code(code)
69  , value(value)
70  , value2(0)
71  , crc8(ComputeCRC8()) {
72  }
73 
78  inline constexpr RequestMsg(RequestMsgCodes code, uint8_t address, uint16_t value)
79  : code(code)
80  , value(address)
81  , value2(value)
82  , crc8(ComputeCRC8()) {
83  }
84 
85  constexpr uint8_t CRC() const { return crc8; }
86 };
87 
89 struct ResponseMsg {
92  uint16_t paramValue;
93 
94  constexpr uint8_t ComputeCRC8() const {
95  uint8_t crc = request.ComputeCRC8();
96  crc = modules::crc::CRC8::CCITT_updateCX(crc, (uint8_t)paramCode);
98  return crc;
99  }
100 
105  : request(request)
108  this->request.crc8 = ComputeCRC8();
109  }
110 
111  constexpr uint8_t CRC() const { return request.crc8; }
112 };
113 
117  uint16_t value;
118  inline constexpr ResponseCommandStatus(ResponseMsgParamCodes code, uint16_t value)
119  : code(code)
120  , value(value) {}
121 };
122 
124 enum class DecodeStatus : uint_fast8_t {
126  NeedMoreData,
127  Error,
128 };
129 
134 class Protocol {
135 public:
136  inline Protocol()
137  : rqState(RequestStates::Code)
138  , requestMsg(RequestMsgCodes::unknown, 0)
139  , rspState(ResponseStates::RequestCode)
140  , responseMsg(RequestMsg(RequestMsgCodes::unknown, 0), ResponseMsgParamCodes::unknown, 0) {
141  }
142 
145  DecodeStatus DecodeRequest(uint8_t c);
146 
149  DecodeStatus DecodeResponse(uint8_t c);
150 
154  static uint8_t EncodeRequest(const RequestMsg &msg, uint8_t *txbuff);
155 
159  static uint8_t EncodeWriteRequest(uint8_t address, uint16_t value, uint8_t *txbuff);
160 
163  static constexpr uint8_t MaxRequestSize() { return 13; }
164 
167  static constexpr uint8_t MaxResponseSize() { return 14; }
168 
174  static uint8_t EncodeResponseCmdAR(const RequestMsg &msg, ResponseMsgParamCodes ar, uint8_t *txbuff);
175 
181  static uint8_t EncodeResponseReadFINDA(const RequestMsg &msg, uint8_t findaValue, uint8_t *txbuff);
182 
188  static uint8_t EncodeResponseQueryOperation(const RequestMsg &msg, ResponseCommandStatus rcs, uint8_t *txbuff);
189 
196  static uint8_t EncodeResponseRead(const RequestMsg &msg, bool accepted, uint16_t value2, uint8_t *txbuff);
197 
199  inline const RequestMsg GetRequestMsg() const { return requestMsg; }
200 
202  inline const ResponseMsg GetResponseMsg() const { return responseMsg; }
203 
206  rqState = RequestStates::Code;
207  }
208 
211  rspState = ResponseStates::RequestCode;
212  }
213 
214 #ifndef UNITTEST
215 private:
216 #endif
217  enum class RequestStates : uint8_t {
218  Code,
219  Value,
220  Address,
221  WriteValue,
222  CRC,
223  Error
224  };
225 
226  RequestStates rqState;
227  RequestMsg requestMsg;
228 
229  enum class ResponseStates : uint8_t {
230  RequestCode,
231  RequestValue,
232  ParamCode,
233  ParamValue,
234  CRC,
235  Error
236  };
237 
238  ResponseStates rspState;
239  ResponseMsg responseMsg;
240 
241  static constexpr bool IsNewLine(uint8_t c) {
242  return c == '\n' || c == '\r';
243  }
244  static constexpr bool IsDigit(uint8_t c) {
245  return c >= '0' && c <= '9';
246  }
247  static constexpr bool IsCRCSeparator(uint8_t c) {
248  return c == '*';
249  }
250  static constexpr bool IsHexDigit(uint8_t c) {
251  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
252  }
253  static constexpr uint8_t Char2Nibble(uint8_t c) {
254  switch (c) {
255  case '0':
256  case '1':
257  case '2':
258  case '3':
259  case '4':
260  case '5':
261  case '6':
262  case '7':
263  case '8':
264  case '9':
265  return c - '0';
266  case 'a':
267  case 'b':
268  case 'c':
269  case 'd':
270  case 'e':
271  case 'f':
272  return c - 'a' + 10;
273  default:
274  return 0;
275  }
276  }
277 
278  static constexpr uint8_t Nibble2Char(uint8_t n) {
279  switch (n) {
280  case 0:
281  case 1:
282  case 2:
283  case 3:
284  case 4:
285  case 5:
286  case 6:
287  case 7:
288  case 8:
289  case 9:
290  return n + '0';
291  case 0xa:
292  case 0xb:
293  case 0xc:
294  case 0xd:
295  case 0xe:
296  case 0xf:
297  return n - 10 + 'a';
298  default:
299  return 0;
300  }
301  }
302 
304  static uint8_t UInt8ToHex(uint8_t value, uint8_t *dst);
305 
307  static uint8_t UInt16ToHex(uint16_t value, uint8_t *dst);
308 
309  static uint8_t BeginEncodeRequest(const RequestMsg &msg, uint8_t *dst);
310 
311  static uint8_t AppendCRC(uint8_t crc, uint8_t *dst);
312 };
313 
314 } // namespace protocol
315 } // namespace modules
316 
317 namespace mp = modules::protocol;
static mp::Protocol protocol
Global instance of the protocol codec.
Definition: application.cpp:31
static constexpr uint8_t CCITT_updateW(uint8_t crc, uint16_t w)
Compute/update CRC8 CCIIT from 16bits (convenience wrapper)
Definition: crc.h:30
Definition: protocol.h:134
static uint8_t EncodeRequest(const RequestMsg &msg, uint8_t *txbuff)
Definition: protocol.cpp:128
static uint8_t EncodeWriteRequest(uint8_t address, uint16_t value, uint8_t *txbuff)
Definition: protocol.cpp:140
static uint8_t EncodeResponseReadFINDA(const RequestMsg &msg, uint8_t findaValue, uint8_t *txbuff)
Definition: protocol.cpp:280
static uint8_t EncodeResponseQueryOperation(const RequestMsg &msg, ResponseCommandStatus rcs, uint8_t *txbuff)
Definition: protocol.cpp:284
DecodeStatus DecodeRequest(uint8_t c)
Definition: protocol.cpp:29
const ResponseMsg GetResponseMsg() const
Definition: protocol.h:202
static uint8_t EncodeResponseRead(const RequestMsg &msg, bool accepted, uint16_t value2, uint8_t *txbuff)
Definition: protocol.cpp:295
static constexpr uint8_t MaxRequestSize()
Definition: protocol.h:163
void ResetRequestDecoder()
resets the internal request decoding state (typically after an error)
Definition: protocol.h:205
DecodeStatus DecodeResponse(uint8_t c)
Definition: protocol.cpp:153
static uint8_t EncodeResponseCmdAR(const RequestMsg &msg, ResponseMsgParamCodes ar, uint8_t *txbuff)
Definition: protocol.cpp:261
static constexpr uint8_t MaxResponseSize()
Definition: protocol.h:167
void ResetResponseDecoder()
resets the internal response decoding state (typically after an error)
Definition: protocol.h:210
const RequestMsg GetRequestMsg() const
Definition: protocol.h:199
The MMU communication protocol implementation and related stuff.
Definition: protocol.cpp:15
DecodeStatus
Message decoding return values.
Definition: protocol.h:124
@ MessageCompleted
message completed and successfully lexed
@ Error
input character broke message decoding
@ NeedMoreData
message incomplete yet, waiting for another byte to come
ResponseMsgParamCodes
Definition of response message parameter codes.
Definition: protocol.h:36
RequestMsgCodes
Definition of request message codes.
Definition: protocol.h:15
The modules namespace contains models of MMU's components.
Definition: command_base.h:8
A request message - requests are being sent by the printer into the MMU.
Definition: protocol.h:47
constexpr RequestMsg(RequestMsgCodes code, uint8_t value)
Definition: protocol.h:67
uint16_t value2
in case or write messages - value to be written into the register
Definition: protocol.h:50
uint8_t crc8
Definition: protocol.h:55
uint8_t value
value of the request message or address of variable to read/write
Definition: protocol.h:49
constexpr RequestMsg(RequestMsgCodes code, uint8_t address, uint16_t value)
Definition: protocol.h:78
RequestMsgCodes code
code of the request message
Definition: protocol.h:48
Combined commandStatus and its value into one data structure (optimization purposes)
Definition: protocol.h:115
A response message - responses are being sent from the MMU into the printer as a response to a reques...
Definition: protocol.h:89
ResponseMsgParamCodes paramCode
code of the parameter
Definition: protocol.h:91
uint16_t paramValue
value of the parameter
Definition: protocol.h:92
RequestMsg request
response is always preceeded by the request message
Definition: protocol.h:90
constexpr ResponseMsg(RequestMsg request, ResponseMsgParamCodes paramCode, uint16_t paramValue)
Definition: protocol.h:104