forked from janpom/davega
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathvesc_comm.cpp
148 lines (126 loc) · 4.01 KB
/
vesc_comm.cpp
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
/*
This file is part of the Roxie firmware.
Roxie firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Roxie firmware is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Roxie firmware. If not, see <https://www.gnu.org/licenses/>.
*/
#include "vesc_comm.h"
#include "crc.h"
#include "roxie_config.h"
#ifdef ARDUINO_NANO_EVERY
HardwareSerial &vesc_serial = Serial1;
#else
HardwareSerial &vesc_serial = Serial;
#endif
#define PACKET_GET_VALUES_TYPE 4
#define PACKET_LENGTH_IDENTIFICATION_BYTE_SHORT 2
#define PACKET_LENGTH_IDENTIFICATION_BYTE_LONG 3
#define PACKET_TERMINATION_BYTE 3
uint8_t GET_VALUES_PACKET[] = {0x02, 0x01, 0x04, 0x40, 0x84, 0x03};
uint8_t expected_packet_length(uint8_t payload_length)
{
return (1 + 1 + payload_length + 2 + 1);
}
VescComm::~VescComm()
{
if (_packet != NULL)
free(_packet);
}
void VescComm::init(uint32_t baud)
{
vesc_serial.begin(baud);
}
uint8_t VescComm::fetch_packet(uint16_t timeout)
{
#ifndef SIM_VALUES
DEB("fetching packet");
vesc_serial.write(GET_VALUES_PACKET, sizeof(GET_VALUES_PACKET));
return receive_packet(timeout);
#endif
//DEB("Using simulated values");
_bytes_read = 78;
return 0;
}
uint8_t VescComm::receive_packet(uint16_t timeout)
{
int32_t start = millis();
_bytes_read = 0;
while (millis() - start < timeout)
{
if (vesc_serial.available())
_packet[_bytes_read++] = vesc_serial.read();
if (_bytes_read >= _max_packet_length)
break;
if (_bytes_read >= 2 && _packet[0] != PACKET_LENGTH_IDENTIFICATION_BYTE_SHORT)
{
uint8_t payload_length = _packet[1];
if (_bytes_read >= expected_packet_length(payload_length))
break;
}
}
//read any left-over bytes without storing
while (vesc_serial.available())
{
// TODO: warning
vesc_serial.read();
}
return _bytes_read;
}
bool VescComm::is_expected_packet()
{
for(int i = 0; i < _bytes_read; i++)
{
Serial.print(String(_packet[i]) + " ");
}
DEB("bytes read : " + String(_bytes_read) + " bytes)");
if (_bytes_read < 3)
{
DEB("packet too short (" + String(_bytes_read) + " bytes)");
return false;
}
if (_packet[0] != PACKET_LENGTH_IDENTIFICATION_BYTE_SHORT)
{
DEB("unexpected length id byte: expected " + String(PACKET_LENGTH_IDENTIFICATION_BYTE_SHORT) +
", got " + String(_packet[0]));
return false;
}
if (_packet[2] != PACKET_GET_VALUES_TYPE)
{
DEB("unexpected packet type: expected " + String(PACKET_GET_VALUES_TYPE) +
", got " + String(_packet[2]));
return false;
}
uint8_t payload_length = _packet[1];
if (_bytes_read != expected_packet_length(payload_length))
{
DEB("packet length (" + String(_bytes_read) + ") does not correspond to the payload length (" +
String(payload_length) + ")");
return false;
}
uint16_t crc = get_word(payload_length + 2);
uint16_t expected_crc = crc16(&_packet[2], payload_length);
if (crc != expected_crc)
{
DEB("CRC error: expected " + String(expected_crc) + ", got " + String(crc));
return false;
}
return true;
}
uint16_t VescComm::get_word(uint8_t index)
{
return ((uint16_t)_packet[index]) << 8 | ((uint16_t)_packet[index + 1]);
}
uint32_t VescComm::get_long(uint8_t index)
{
return ((uint32_t)_packet[index]) << 24 |
((uint32_t)_packet[index + 1]) << 16 |
((uint32_t)_packet[index + 2]) << 8 |
((uint32_t)_packet[index + 3]);
}