-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathXR25streamreader.hh
172 lines (144 loc) · 4.61 KB
/
XR25streamreader.hh
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
/* XR25streamreader.hh - Parse Renault XR25 frame stream
*
* Copyright (C) Javier Lopez-Gomez, 2016
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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.
*/
#ifndef XR25STREAMREADER_HH
#define XR25STREAMREADER_HH
#include <atomic>
#include <functional>
#include <iostream>
#include <memory>
#include <pthread.h>
#include <thread>
enum XR25InFlags : unsigned char {
IN_AC_REQUEST = 0x02,
IN_AC_COMPRES = 0x04,
IN_THROTTLE_0 = 0x08,
IN_PARKED = 0x10,
IN_THROTTLE_1 = 0x20,
};
enum XR25OutFlags : unsigned char {
OUT_PUMP_ENABLE = 0x01,
OUT_IDLE_REGULATION = 0x02,
OUT_WASTEGATE_REG = 0x04,
OUT_LAMBDA_LOOP = 0x08,
OUT_EGR_ENABLE = 0x20,
OUT_CHECK_ENGINE = 0x80,
};
enum XR25FaultFlags0 : unsigned char {
FAULT_WATER_OPEN_C = 0x01,
FAULT_WATER_SHORT_C = 0x02,
FAULT_AIR_OPEN_C = 0x04,
FAULT_AIR_SHORT_C = 0x08,
FAULT_TPS_LOW = 0x40,
FAULT_TPS_HIGH = 0x80,
};
enum XR25FaultFlags1 : unsigned char {
FAULT_MAP = 0x04,
FAULT_SPD_SENSOR = 0x10,
FAULT_LAMBDA_TMP = 0x20,
FAULT_LAMBDA = 0x80,
};
enum XR25FaultFlags2 : unsigned char {
FAULT_EEPROM_CHECKSUM = 0x20,
FAULT_PROG_CHECKSUM = 0x80,
};
enum XR25FaultFlags3 : unsigned char {
FAULT_INJECTORS = 0x10,
};
enum XR25FaultFlags4 : unsigned char {
FAULT_PUMP = 0x01,
FAULT_WASTEGATE = 0x04,
FAULT_EGR = 0x08,
FAULT_IDLE_REG = 0x20,
};
/* XR25 frames start with 0xff 0x00; 0xff ocurrences in the frame sent on the
* wire as 0xff 0xff.
*
* 0xff 0x00 0xaa 0xbb 0xcc 0xdd . . . 0xff 0x00 . . .
* |-------| | | | |---- byte 3 |-------|
* header1 | | |--------- byte 2 header2
* | |-------------- byte 1
* |------------------ byte 0
*/
struct XR25Frame {
unsigned char program_vrsn;
unsigned char calib_vrsn;
XR25InFlags in_flags;
XR25OutFlags out_flags;
int map;
int rpm;
int throttle;
XR25FaultFlags1 fault_flags_1;
unsigned char eng_pinging;
int injection_us;
int advance;
XR25FaultFlags0 fault_flags_0;
unsigned char fault_fugitive;
XR25FaultFlags2 fault_flags_2;
XR25FaultFlags4 fault_flags_4;
XR25FaultFlags3 fault_flags_3;
float temp_water;
float temp_air;
float battvalue;
float lambdavalue;
int idle_regulation;
int idle_period;
unsigned char eng_pinging_delay;
int atmos_pressure;
unsigned char afr_correction;
int spd_km_h;
};
/* Equivalent to '(x & bit1) ? bit2 : 0' but this is faster;
* borrowed from include/linux/mman.h: _calc_vm_trans.
*/
#define remap_bit(x, bit1, bit2) \
((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) : ((x) & (bit1)) / ((bit1) / (bit2)))
class XR25FrameParser {
public:
/** Parses a frame and return a 'struct XR25Frame'.
* @param c Translated frame ("0xff 0xff" converted to 0xff)
* @param length Length in octets
* @param fra Reference to 'struct XR25Frame'; implementors write here
* @return true if the frame @a c was parsed
*/
virtual bool parse_frame(const unsigned char c[], int length, XR25Frame &fra) = 0;
};
class XR25StreamReader {
private:
typedef std::function<void(const unsigned char[], int, XR25Frame &)> post_parse_t;
std::istream &_in;
std::atomic_bool _synchronized;
std::atomic_int _sync_err_count, _frames_per_sec, _fra_count;
post_parse_t _post_parse;
std::unique_ptr<std::thread> _thrd;
void frame_recv(XR25FrameParser &parser, const unsigned char[], int, XR25Frame &);
void read_frames(XR25FrameParser &parser);
public:
XR25StreamReader(std::istream &s, post_parse_t p = nullptr)
: _in(s), _synchronized(0), _sync_err_count(0), _frames_per_sec(0), _fra_count(0), _post_parse(p),
_thrd(nullptr) {}
~XR25StreamReader() { stop(); }
bool is_synchronized() { return _synchronized.load(); }
int get_sync_err_count() { return _sync_err_count.load(); }
int get_frames_per_sec() { return _frames_per_sec.load(); }
int get_fra_count() { return _fra_count.load(); }
/** Read frames non-blocking; call stop() to cancel thread
* @param parser The XR25FrameParser to use
*/
void start(XR25FrameParser &parser);
/** Stop internal thread; see start()
*/
void stop();
};
#endif /* XR25STREAMREADER_HH */