EV3UartProtocolParserSensorSide
/home/shenghao/eclipse-workspace/EV3UartProtocolParserSensorSide/EV3UartProtocolParserSensorSide.cpp
Go to the documentation of this file.
1 
12 #include <stdint.h>
13 
15 
16 using namespace EV3UartGenerator;
17 
18 uint8_t Parser::payload_length(const uint8_t hdr) {
19  return two_pow((hdr >> 0x03) & 0x07);
20 }
21 
23  // Check type first
24  HeaderInformation info {
25  false, (hdr & 0xc7), 0x00
26  };
27 
28  const uint8_t payload_len_code { (hdr >> 0x03) & 0x07 };
29 
30  switch (info.header_sanitized) {
31  case (static_cast<uint8_t>(Magics::SYS::SYS_BASE)
32  | static_cast<uint8_t>(Magics::SYS::ACK)):
33  if (!payload_len_code)
34  info.header_valid = true;
35  break;
36 
37  case (static_cast<uint8_t>(Magics::SYS::SYS_BASE)
38  | static_cast<uint8_t>(Magics::SYS::NACK)):
39  if (!payload_len_code)
40  info.header_valid = true;
41  break;
42 
43  case (static_cast<uint8_t>(Magics::CMD::CMD_BASE)
44  | static_cast<uint8_t>(Magics::CMD::SELECT)):
45  if (payload_len_code == 0) {
46  info.header_valid = true;
47  info.payload_length = payload_length(hdr);
48  }
49  break;
50 
51  case (static_cast<uint8_t>(Magics::CMD::CMD_BASE)
52  | static_cast<uint8_t>(Magics::CMD::WRITE)):
53  if (payload_len_code < 6) {
54  info.header_valid = true;
55  info.payload_length = payload_length(hdr);
56  }
57  break;
58 
59  default:
60  break;
61  }
62 
63  return info;
64 }
65 
67 
68 }
69 
70 ParserReturn Parser::update(uint8_t input) {
71  ParserReturn rtn { };
72 
73  switch (current_state) {
74  case State::WAIT_HEADER:
75  {
76  HeaderInformation info { analyze_header(input) };
77  buffer[0] = input;
78  if (info.header_valid) {
79  if (info.payload_length > 0) { // NOT SYS - is a CMD header
80  // CMD - setup byte counters
81  message_payload_length = info.payload_length;
82  message_pending_bytes = (info.payload_length + 0x01); // + 1 FCS
84  // Advance state
85  current_state = next_state(current_state);
86  } else { // SYS - translate and return
87  switch (info.header_sanitized & 0x07) { // Mask out irrelevant bits
88  case static_cast<uint8_t>(Magics::SYS::NACK):
90  break;
91  case static_cast<uint8_t>(Magics::SYS::ACK):
93  break;
94  }
95  // No state advance
96  }
97  } else {
99  }
100  }
101  break;
103  const uint8_t write_index { ((message_payload_length + 0x01)
104  - message_pending_bytes) + 0x01 };
105  buffer[write_index] = input;
106  message_pending_bytes -= 0x01;
107 
108  if (message_pending_bytes) {
110  } else {
111  rtn.len = message_payload_length; // len must be valid for RECEIVED_CMD_*
112  if (Framing::checksum(buffer, message_payload_length + 1) // + 1 for header
113  != buffer[write_index]) { // Checksum Error
115  } else { // Checksum OK
116  switch (buffer[0] & 0x07) { // Mask out irrelevant bits
117  case static_cast<uint8_t>(Magics::CMD::SELECT):
119  break;
120  case static_cast<uint8_t>(Magics::CMD::WRITE):
122  break;
123  }
124  }
125  current_state = next_state(current_state); // Increment state
126  }
127  break;
128  }
129 
130  rtn.hdr = buffer[0];
131  return rtn;
132 }
133 
134 uint8_t* Parser::data() {
135  return (buffer + 1);
136 }
137 
138 const uint8_t* Parser::data() const {
139  return (buffer + 1);
140 }
141 
143  current_state = State::STATE_START;
144 }
145 }
146 
147 
Parser is waiting for the checksum byte.
HeaderInformation analyze_header(const uint8_t hdr)
Parser is waiting for the header byte.