Skip to content

Commit d0c0884

Browse files
committed
Add CART abstraction. Not yet fully working
1 parent 9c37a02 commit d0c0884

File tree

8 files changed

+362
-175
lines changed

8 files changed

+362
-175
lines changed

platformio.ini

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,3 @@ monitor_speed = 19200
1616
lib_deps =
1717
olikraus/U8g2@^2.34.4
1818
mathertel/OneButton@^2.0.3
19-
20-
[env:native]
21-
platform = native
22-
debug_test = *
23-
lib_deps = mathertel/OneButton@^2.0.3

src/Cart.cpp

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#include "Cart.h"
2+
3+
const uint8_t Cart::startMessage[18] = {
4+
0x00, 0x00, 0x00, 0x00,
5+
0x00, 0x00, 0x00, 0x00,
6+
0x00, 0x00, 0x00, 0x00,
7+
0x01, 0x04, 0x00, 0x00,
8+
0x00, 0x05
9+
};
10+
11+
Cart::Cart(SoftwareSerial* softwareSerial, uint8_t pin_re) {
12+
this->softwareSerial = softwareSerial;
13+
this->pin_re = pin_re;
14+
pinMode(pin_re, OUTPUT);
15+
}
16+
17+
void Cart::sendStartMessage() {
18+
digitalWrite(pin_re, RE_WRITE);
19+
20+
for(uint8_t i = 0; i<sizeof(startMessage); i++) {
21+
softwareSerial->write(startMessage[i]);
22+
delayMicroseconds(420);
23+
}
24+
25+
digitalWrite(pin_re, RE_READ);
26+
}
27+
28+
void Cart::setBaudrate(long baudrate) {
29+
softwareSerial->begin(baudrate);
30+
switch (baudrate) {
31+
case 2400:
32+
delay.word = 1420;
33+
delay.byte = 60;
34+
break;
35+
case 9600:
36+
delay.word = 426;
37+
delay.byte = 15;
38+
break;
39+
}
40+
41+
isSynced = false;
42+
}
43+
44+
45+
void Cart::loop() {
46+
47+
// if in diag param slot, we don't wait for bytes
48+
// just send the parameter and return
49+
if (mode == DIAG_PARAM_SLOT) {
50+
if (sentDiagnosticParameter && diagnosticParameterPointer == (frameNumber-1)*2) {
51+
//Serial.println("Sending diag params");
52+
delayMicroseconds(delay.word);
53+
digitalWrite(pin_re, RE_WRITE);
54+
softwareSerial->write(diagnosticParameter[diagnosticParameterPointer]);
55+
delayMicroseconds(delay.byte);
56+
softwareSerial->write(diagnosticParameter[diagnosticParameterPointer+1]);
57+
digitalWrite(pin_re, RE_READ);
58+
59+
diagnosticParameterPointer+=2;
60+
61+
if (diagnosticParameterPointer > 7) {
62+
diagnosticParameterPointer = 0;
63+
diagnosticParameterSend = true;
64+
}
65+
66+
}
67+
68+
mode = DATA_SLOT;
69+
return;
70+
}
71+
72+
// read next byte and check if we have a full word already
73+
if (pushAvailableToBuffer()) {
74+
75+
wordBufferPointer++;
76+
if (wordBufferPointer < 2) {
77+
// buffer not full, wait for next byte
78+
return;
79+
}
80+
81+
// always look out for sync word and stop everything else if
82+
// we find one
83+
if (isBufferSync()) {
84+
// look for ID slot
85+
mode = ID_SLOT;
86+
87+
// reset for next word
88+
wordBufferPointer = 0;
89+
resetBuffer();
90+
return;
91+
}
92+
93+
switch(mode) {
94+
case WAIT_SYNC:
95+
// do nothing as we wait for next sync;
96+
break;
97+
case ID_SLOT:
98+
if (frameNumber > 15) {
99+
frameNumber = 0;
100+
isSynced = true;
101+
Serial.println("Sync full");
102+
}
103+
104+
// if the we find the wrong frame number, we start again
105+
if (frameNumber != (wordBuffer[1] & 0xF)) {
106+
frameNumber = 0;
107+
mode = WAIT_SYNC;
108+
Serial.println("Found id slot with invalid frame number");
109+
break;
110+
}
111+
// increase the frameNumber here.
112+
// like this we can be sure that we don't miss a frame.
113+
// downside is, that we always have to subtract one to check the frameNumber afterwards...
114+
frameNumber++;
115+
116+
// for now don't care about the rest of the id slot
117+
118+
if (frameNumber-1 < 4) {
119+
mode = DIAG_PARAM_SLOT;
120+
} else {
121+
mode = STATUS_SLOT;
122+
}
123+
break;
124+
case DIAG_PARAM_SLOT:
125+
// this cannot be reached, as we don't care about word
126+
// reading in this mode
127+
break;
128+
case STATUS_SLOT:
129+
if (frameNumber-1 == 4) {
130+
currentDiagnosticMode = wordBuffer[0];
131+
}
132+
mode = DATA_SLOT;
133+
break;
134+
case DATA_SLOT:
135+
// only read one word and wait for next frame
136+
//onReadDataMessage(wordBuffer[0], wordBuffer[1]);
137+
mode = WAIT_SYNC;
138+
break;
139+
}
140+
141+
// reset for next word
142+
wordBufferPointer = 0;
143+
resetBuffer();
144+
}
145+
146+
}
147+
148+
void Cart::setDiagnosticParameter(const uint8_t diagnosticParameter[]) {
149+
memcpy(this->diagnosticParameter, diagnosticParameter, 8);
150+
sentDiagnosticParameter = true;
151+
diagnosticParameterSend = false;
152+
}
153+
154+
bool Cart::isBufferSync() {
155+
return !(wordBuffer[0] | wordBuffer[1]);
156+
}
157+
158+
uint8_t Cart::pushAvailableToBuffer() {
159+
if (softwareSerial->available()) {
160+
pushBuffer(softwareSerial->read());
161+
return 1;
162+
} else {
163+
return 0;
164+
}
165+
}
166+
167+
void Cart::pushBuffer(uint8_t val) {
168+
wordBuffer[0] = wordBuffer[1];
169+
wordBuffer[1] = val;
170+
}
171+
172+
void Cart::resetBuffer() {
173+
wordBuffer[0] = 0xff;
174+
wordBuffer[1] = 0xff;
175+
}

src/Cart.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#pragma once
2+
3+
#include <Arduino.h>
4+
#include <SoftwareSerial.h>
5+
6+
#define RE_READ 0x0
7+
#define RE_WRITE 0x1
8+
9+
class Cart {
10+
11+
public:
12+
typedef void (*callback_t)(const uint8_t, const uint8_t);
13+
14+
callback_t onReadDataMessage;
15+
16+
void setDiagnosticParameter(const uint8_t diagnosticParameter[]);
17+
// when false, sending diagnostic parameter is disabled
18+
bool sentDiagnosticParameter = false;
19+
// when true, the diagnostic parameter has been send at least one time
20+
bool diagnosticParameterSend = false;
21+
22+
uint8_t currentDiagnosticMode = 0;
23+
24+
void setBaudrate(long baudrate);
25+
void sendStartMessage();
26+
27+
void loop();
28+
bool isSynced = false;
29+
30+
Cart(SoftwareSerial* softwareSerial, uint8_t pin_re);
31+
32+
private:
33+
34+
enum Mode {
35+
WAIT_SYNC,
36+
ID_SLOT,
37+
DIAG_PARAM_SLOT,
38+
STATUS_SLOT,
39+
DATA_SLOT,
40+
} mode = WAIT_SYNC;
41+
42+
struct delay_s {
43+
uint16_t word; // ns
44+
uint16_t byte; // ns
45+
} delay;
46+
47+
const static uint8_t startMessage[18];
48+
49+
SoftwareSerial *softwareSerial;
50+
uint8_t pin_re;
51+
52+
void pushBuffer(uint8_t val);
53+
uint8_t pushAvailableToBuffer();
54+
void resetBuffer();
55+
56+
uint8_t diagnosticParameter[8];
57+
uint8_t diagnosticParameterPointer = 0;
58+
59+
uint8_t frameNumber = 0;
60+
bool isBufferSync();
61+
62+
uint8_t wordBufferPointer = 0;
63+
uint8_t wordBuffer[2];
64+
};

0 commit comments

Comments
 (0)