-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CART abstraction. Not yet fully working
- Loading branch information
Showing
8 changed files
with
362 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
#include "Cart.h" | ||
|
||
const uint8_t Cart::startMessage[18] = { | ||
0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, | ||
0x01, 0x04, 0x00, 0x00, | ||
0x00, 0x05 | ||
}; | ||
|
||
Cart::Cart(SoftwareSerial* softwareSerial, uint8_t pin_re) { | ||
this->softwareSerial = softwareSerial; | ||
this->pin_re = pin_re; | ||
pinMode(pin_re, OUTPUT); | ||
} | ||
|
||
void Cart::sendStartMessage() { | ||
digitalWrite(pin_re, RE_WRITE); | ||
|
||
for(uint8_t i = 0; i<sizeof(startMessage); i++) { | ||
softwareSerial->write(startMessage[i]); | ||
delayMicroseconds(420); | ||
} | ||
|
||
digitalWrite(pin_re, RE_READ); | ||
} | ||
|
||
void Cart::setBaudrate(long baudrate) { | ||
softwareSerial->begin(baudrate); | ||
switch (baudrate) { | ||
case 2400: | ||
delay.word = 1420; | ||
delay.byte = 60; | ||
break; | ||
case 9600: | ||
delay.word = 426; | ||
delay.byte = 15; | ||
break; | ||
} | ||
|
||
isSynced = false; | ||
} | ||
|
||
|
||
void Cart::loop() { | ||
|
||
// if in diag param slot, we don't wait for bytes | ||
// just send the parameter and return | ||
if (mode == DIAG_PARAM_SLOT) { | ||
if (sentDiagnosticParameter && diagnosticParameterPointer == (frameNumber-1)*2) { | ||
//Serial.println("Sending diag params"); | ||
delayMicroseconds(delay.word); | ||
digitalWrite(pin_re, RE_WRITE); | ||
softwareSerial->write(diagnosticParameter[diagnosticParameterPointer]); | ||
delayMicroseconds(delay.byte); | ||
softwareSerial->write(diagnosticParameter[diagnosticParameterPointer+1]); | ||
digitalWrite(pin_re, RE_READ); | ||
|
||
diagnosticParameterPointer+=2; | ||
|
||
if (diagnosticParameterPointer > 7) { | ||
diagnosticParameterPointer = 0; | ||
diagnosticParameterSend = true; | ||
} | ||
|
||
} | ||
|
||
mode = DATA_SLOT; | ||
return; | ||
} | ||
|
||
// read next byte and check if we have a full word already | ||
if (pushAvailableToBuffer()) { | ||
|
||
wordBufferPointer++; | ||
if (wordBufferPointer < 2) { | ||
// buffer not full, wait for next byte | ||
return; | ||
} | ||
|
||
// always look out for sync word and stop everything else if | ||
// we find one | ||
if (isBufferSync()) { | ||
// look for ID slot | ||
mode = ID_SLOT; | ||
|
||
// reset for next word | ||
wordBufferPointer = 0; | ||
resetBuffer(); | ||
return; | ||
} | ||
|
||
switch(mode) { | ||
case WAIT_SYNC: | ||
// do nothing as we wait for next sync; | ||
break; | ||
case ID_SLOT: | ||
if (frameNumber > 15) { | ||
frameNumber = 0; | ||
isSynced = true; | ||
Serial.println("Sync full"); | ||
} | ||
|
||
// if the we find the wrong frame number, we start again | ||
if (frameNumber != (wordBuffer[1] & 0xF)) { | ||
frameNumber = 0; | ||
mode = WAIT_SYNC; | ||
Serial.println("Found id slot with invalid frame number"); | ||
break; | ||
} | ||
// increase the frameNumber here. | ||
// like this we can be sure that we don't miss a frame. | ||
// downside is, that we always have to subtract one to check the frameNumber afterwards... | ||
frameNumber++; | ||
|
||
// for now don't care about the rest of the id slot | ||
|
||
if (frameNumber-1 < 4) { | ||
mode = DIAG_PARAM_SLOT; | ||
} else { | ||
mode = STATUS_SLOT; | ||
} | ||
break; | ||
case DIAG_PARAM_SLOT: | ||
// this cannot be reached, as we don't care about word | ||
// reading in this mode | ||
break; | ||
case STATUS_SLOT: | ||
if (frameNumber-1 == 4) { | ||
currentDiagnosticMode = wordBuffer[0]; | ||
} | ||
mode = DATA_SLOT; | ||
break; | ||
case DATA_SLOT: | ||
// only read one word and wait for next frame | ||
//onReadDataMessage(wordBuffer[0], wordBuffer[1]); | ||
mode = WAIT_SYNC; | ||
break; | ||
} | ||
|
||
// reset for next word | ||
wordBufferPointer = 0; | ||
resetBuffer(); | ||
} | ||
|
||
} | ||
|
||
void Cart::setDiagnosticParameter(const uint8_t diagnosticParameter[]) { | ||
memcpy(this->diagnosticParameter, diagnosticParameter, 8); | ||
sentDiagnosticParameter = true; | ||
diagnosticParameterSend = false; | ||
} | ||
|
||
bool Cart::isBufferSync() { | ||
return !(wordBuffer[0] | wordBuffer[1]); | ||
} | ||
|
||
uint8_t Cart::pushAvailableToBuffer() { | ||
if (softwareSerial->available()) { | ||
pushBuffer(softwareSerial->read()); | ||
return 1; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
void Cart::pushBuffer(uint8_t val) { | ||
wordBuffer[0] = wordBuffer[1]; | ||
wordBuffer[1] = val; | ||
} | ||
|
||
void Cart::resetBuffer() { | ||
wordBuffer[0] = 0xff; | ||
wordBuffer[1] = 0xff; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#pragma once | ||
|
||
#include <Arduino.h> | ||
#include <SoftwareSerial.h> | ||
|
||
#define RE_READ 0x0 | ||
#define RE_WRITE 0x1 | ||
|
||
class Cart { | ||
|
||
public: | ||
typedef void (*callback_t)(const uint8_t, const uint8_t); | ||
|
||
callback_t onReadDataMessage; | ||
|
||
void setDiagnosticParameter(const uint8_t diagnosticParameter[]); | ||
// when false, sending diagnostic parameter is disabled | ||
bool sentDiagnosticParameter = false; | ||
// when true, the diagnostic parameter has been send at least one time | ||
bool diagnosticParameterSend = false; | ||
|
||
uint8_t currentDiagnosticMode = 0; | ||
|
||
void setBaudrate(long baudrate); | ||
void sendStartMessage(); | ||
|
||
void loop(); | ||
bool isSynced = false; | ||
|
||
Cart(SoftwareSerial* softwareSerial, uint8_t pin_re); | ||
|
||
private: | ||
|
||
enum Mode { | ||
WAIT_SYNC, | ||
ID_SLOT, | ||
DIAG_PARAM_SLOT, | ||
STATUS_SLOT, | ||
DATA_SLOT, | ||
} mode = WAIT_SYNC; | ||
|
||
struct delay_s { | ||
uint16_t word; // ns | ||
uint16_t byte; // ns | ||
} delay; | ||
|
||
const static uint8_t startMessage[18]; | ||
|
||
SoftwareSerial *softwareSerial; | ||
uint8_t pin_re; | ||
|
||
void pushBuffer(uint8_t val); | ||
uint8_t pushAvailableToBuffer(); | ||
void resetBuffer(); | ||
|
||
uint8_t diagnosticParameter[8]; | ||
uint8_t diagnosticParameterPointer = 0; | ||
|
||
uint8_t frameNumber = 0; | ||
bool isBufferSync(); | ||
|
||
uint8_t wordBufferPointer = 0; | ||
uint8_t wordBuffer[2]; | ||
}; |
Oops, something went wrong.