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
+ }
0 commit comments