Its GPL and I am required by license to provide it on request, therefore here is the diff. I wont support it, nor would I recommend using it. This was just an experimental proof of concept. I make no claims that this the 'right' way. Also, developing on master. Tsk tsk. Ive learnt how to and am now using git/gitflow since I last looked at this in 2016
Code: Select all
# git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: src/adapter/adaptertypes.h
# modified: src/adapter/dispatcher.cpp
# modified: src/adapter/ecumsg.cpp
# modified: src/adapter/obd/j1850.h
# modified: src/adapter/obd/obdprofile.cpp
# modified: src/adapter/obd/padapter.h
# modified: src/adapter/obd/vpw.cpp
# modified: src/adapter/obd/vpw.h
#
no changes added to commit (use "git add" and/or "git commit -a")
# git diff
diff --git a/src/adapter/adaptertypes.h b/src/adapter/adaptertypes.h
old mode 100644
new mode 100755
index 19a02ba..07ce2b2
--- a/src/adapter/adaptertypes.h
+++ b/src/adapter/adaptertypes.h
@@ -16,10 +16,10 @@
using namespace std;
// Config settings
-const int OBD_IN_MSG_DLEN = 7;
+const int OBD_IN_MSG_DLEN = 256;
const int OBD_IN_MSG_LEN = OBD_IN_MSG_DLEN + 5; // 7 data + 4 header + 1 reserved
-const int RX_BUFFER_LEN = 100;
-const int RX_CMD_LEN = 20; // The incoming cmd
+const int RX_BUFFER_LEN = 256 + 5; // This is the max string size of the ELM command. So should be slightly more than packetsize *2
+const int RX_CMD_LEN = OBD_IN_MSG_LEN * 3 + 1; // The incoming cmd
const int USER_BUF_LEN = RX_CMD_LEN; // The previous cmd
//
@@ -60,6 +60,8 @@ enum AT_Requests {
PAR_WARMSTART,
PAR_WIRING_TEST,
PAR_USE_AUTO_SP,
+ PAR_VPW_4X,
+ PAR_RAW_PAYLOAD,
// int properties
PAR_CAN_CF = INT_PROPS_START,
PAR_CAN_CM,
@@ -69,7 +71,7 @@ enum AT_Requests {
PAR_WAKEUP_VAL,
// bytes properties
PAR_HEADER_BYTES = BYTES_PROPS_START,
- PAR_WM_HEADER
+ PAR_WM_HEADER,
};
struct ByteArray {
diff --git a/src/adapter/dispatcher.cpp b/src/adapter/dispatcher.cpp
old mode 100644
new mode 100755
index 6c511ea..378db0f
--- a/src/adapter/dispatcher.cpp
+++ b/src/adapter/dispatcher.cpp
@@ -22,7 +22,7 @@ static const char ErrMessage [] = "?";
static const char OkMessage [] = "OK";
static const char Version [] = "1.05";
static const char Interface [] = "ELM327 v1.4";
-static const char Copyright [] = "Copyright (c) 2009-2016 ObdDiag.Net";
+static const char Copyright [] = "Copyright (c) 2009-2016 ObdDiag.Net, 2016 PCMHacking.net";
static const char Copyright2 [] = "This is free software; see the source for copying conditions. There is NO";
static const char Copyright3 [] = "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.";
@@ -169,6 +169,7 @@ static void SetDefault()
config->setBoolProperty(PAR_SPACES, true);
config->setIntProperty(PAR_TIMEOUT, 0);
config->setIntProperty(PAR_ISO_INIT_ADDRESS, 0x33);
+ config->setBoolProperty(PAR_VPW_4X, false);
AdptSendReply(OkMessage);
}
@@ -190,7 +191,7 @@ static void OnSetDefault(const string& cmd, int par)
*/
static void OnProtocolDescribe(const string& cmd, int par)
{
- OBDProfile::instance()->getProtocolDescription();
+ OBDProfile::instance()->getProtocolDescription();
}
/**
@@ -350,7 +351,12 @@ static const DispatchType dispatchTbl[] = {
{ "TP", PAR_TRY_PROTOCOL, 1, 1, OnSetProtocol },
{ "WM", PAR_WM_HEADER, 1, 6, OnSetBytes },
{ "WS", PAR_WARMSTART, 0, 0, OnReset },
- { "Z", PAR_RESET_CPU, 0, 0, OnReset }
+ { "Z", PAR_RESET_CPU, 0, 0, OnReset },
+ { "V0", PAR_VPW_4X, 0, 0, OnSetValueFalse },
+ { "V1", PAR_VPW_4X, 0, 0, OnSetValueTrue },
+ { "R0", PAR_RAW_PAYLOAD, 0, 0, OnSetValueFalse },
+ { "R1", PAR_RAW_PAYLOAD, 0, 0, OnSetValueTrue },
+
};
static bool ValidateArgLength(const DispatchType& entry, const string& arg)
diff --git a/src/adapter/ecumsg.cpp b/src/adapter/ecumsg.cpp
old mode 100644
new mode 100755
index 69c3695..7a505df
--- a/src/adapter/ecumsg.cpp
+++ b/src/adapter/ecumsg.cpp
@@ -13,6 +13,7 @@ using namespace util;
const int HEADER_SIZE = 3;
+
class EcumsgISO9141 : public Ecumsg {
friend class Ecumsg;
public:
@@ -115,8 +116,10 @@ static void IsoAddChecksum(uint8_t* data, uint8_t& length)
*/
static void StripHeader(uint8_t* data, uint8_t& length)
{
- length -= HEADER_SIZE;
- memmove(&data[0], &data[HEADER_SIZE], length);
+ if (!AdapterConfig::instance()->getBoolProperty(PAR_RAW_PAYLOAD)) {
+ length -= HEADER_SIZE;
+ memmove(&data[0], &data[HEADER_SIZE], length);
+ }
}
/*
@@ -217,10 +220,12 @@ void Ecumsg::setHeader(const uint8_t* header)
*/
void EcumsgISO9141::addHeaderAndChecksum()
{
- // Shift data on 3 bytes to accommodate the header
- memmove(&data_[HEADER_SIZE], &data_[0], length_);
- length_ += HEADER_SIZE;
- memcpy(&data_[0], header_, HEADER_SIZE);
+ if (AdapterConfig::instance()->getBoolProperty(PAR_RAW_PAYLOAD)) {
+ // Shift data on 3 bytes to accommodate the header
+ memmove(&data_[HEADER_SIZE], &data_[0], length_);
+ length_ += HEADER_SIZE;
+ memcpy(&data_[0], header_, HEADER_SIZE);
+ }
IsoAddChecksum(data_, length_);
}
@@ -230,14 +235,15 @@ void EcumsgISO9141::addHeaderAndChecksum()
*/
void EcumsgISO14230::addHeaderAndChecksum()
{
- // Shift data on 3 bytes to accommodate the header
- memmove(&data_[HEADER_SIZE], &data_[0], length_);
- uint8_t len = length_;
- length_ += HEADER_SIZE;
- memcpy(&data_[0], header_, HEADER_SIZE);
-
- // The length is in the 1st byte
- data_[0] = (data_[0] & 0xC0) | len;
+ if (!AdapterConfig::instance()->getBoolProperty(PAR_RAW_PAYLOAD)) {
+ // Shift data on 3 bytes to accommodate the header
+ memmove(&data_[HEADER_SIZE], &data_[0], length_);
+ uint8_t len = length_;
+ length_ += HEADER_SIZE;
+ memcpy(&data_[0], header_, HEADER_SIZE);
+ // The length is in the 1st byte
+ data_[0] = (data_[0] & 0xC0) | len;
+ }
IsoAddChecksum(data_, length_);
}
@@ -247,11 +253,12 @@ void EcumsgISO14230::addHeaderAndChecksum()
*/
void EcumsgVPW::addHeaderAndChecksum()
{
- // Shift data on 3 bytes to accommodate the header
- memmove(&data_[HEADER_SIZE], &data_[0], length_);
- length_ += HEADER_SIZE;
- memcpy(&data_[0], header_, HEADER_SIZE);
-
+ if (!AdapterConfig::instance()->getBoolProperty(PAR_RAW_PAYLOAD)) {
+ // Shift data on 3 bytes to accommodate the header
+ memmove(&data_[HEADER_SIZE], &data_[0], length_);
+ length_ += HEADER_SIZE;
+ memcpy(&data_[0], header_, HEADER_SIZE);
+ }
J1850AddChecksum(data_, length_);
}
@@ -260,10 +267,12 @@ void EcumsgVPW::addHeaderAndChecksum()
*/
void EcumsgPWM::addHeaderAndChecksum()
{
- // Shift data on 3 bytes to accommodate the header
- memmove(&data_[HEADER_SIZE], &data_[0], length_);
- length_ += HEADER_SIZE;
- memcpy(&data_[0], header_, HEADER_SIZE);
+ if (!AdapterConfig::instance()->getBoolProperty(PAR_RAW_PAYLOAD)) {
+ // Shift data on 3 bytes to accommodate the header
+ memmove(&data_[HEADER_SIZE], &data_[0], length_);
+ length_ += HEADER_SIZE;
+ memcpy(&data_[0], header_, HEADER_SIZE);
+ }
J1850AddChecksum(data_, length_);
}
diff --git a/src/adapter/obd/j1850.h b/src/adapter/obd/j1850.h
old mode 100644
new mode 100755
index c0dbab7..01587de
--- a/src/adapter/obd/j1850.h
+++ b/src/adapter/obd/j1850.h
@@ -14,9 +14,9 @@
enum J1850Limits {
J1850_BYTES_MIN = 1,
- J1850_BYTES_MAX = 12,
+ J1850_BYTES_MAX = 256 + 5,
OBD2_BYTES_MIN = 5, // 3(header) + 1(data) + 1(checksum)
- OBD2_BYTES_MAX = 11 // 3(header) + 7(data) + 1(checksum)
+ OBD2_BYTES_MAX = 256 + 5 // 3(header) + 7(data) + 1(checksum)
};
// J1850 Timeouts
@@ -44,7 +44,25 @@ enum VpwTimeouts {
TV3_RX_MAX = 239,
TV5_RX_MIN = 239,
TV6_RX_MIN = 280,
- VPW_RX_MID = 96
+ VPW_RX_MID = 96,
+
+ TV1_4X_TX_NOM = 64/4,
+ TV2_4X_TX_NOM = 128/4,
+ TV3_4X_TX_NOM = 200/4,
+ TV4_4X_TX_MIN = 261/4,
+ TV6_4X_TX_MIN = 280/4,
+ TV5_4X_TX_NOM = 300/4,
+ TV5_4X_TX_MAX = 5000/4,
+ TV6_4X_TX_NOM = 300/4,
+ TV1_4X_TX_ADJ = 64/4,
+ TV2_4X_TX_ADJ = 128/4,
+ TV1_4X_RX_MIN = 34/4,
+ TV2_4X_RX_MAX = 163/4,
+ TV3_4X_RX_MIN = 163/4,
+ TV3_4X_RX_MAX = 239/4,
+ TV5_4X_RX_MIN = 239/4,
+ TV6_4X_RX_MIN = 280/4,
+ VPW_4X_RX_MID = 96/4
};
// PWM Timeouts, in usec
diff --git a/src/adapter/obd/obdprofile.cpp b/src/adapter/obd/obdprofile.cpp
old mode 100644
new mode 100755
index f10a917..861c49c
--- a/src/adapter/obd/obdprofile.cpp
+++ b/src/adapter/obd/obdprofile.cpp
@@ -78,6 +78,7 @@ int OBDProfile::setProtocol(int num, bool refreshConnection)
break;
case PROT_J1850_VPW:
adapter_ = ProtocolAdapter::getAdapter(ADPTR_VPW);
+ adapter_->setSpeed();
break;
case PROT_ISO9141:
adapter_ = ProtocolAdapter::getAdapter(ADPTR_ISO);
@@ -164,7 +165,7 @@ void OBDProfile::onRequest(const string& cmdString)
*/
int OBDProfile::onRequestImpl(const string& cmdString)
{
- const char* OBD_TEST_SEQ = "0100";
+ const char* OBD_TEST_SEQ = "0100";
uint8_t data[OBD_IN_MSG_LEN];
// Buffer overrun check,
diff --git a/src/adapter/obd/padapter.h b/src/adapter/obd/padapter.h
old mode 100644
new mode 100755
index 4f68b1e..0d62313
--- a/src/adapter/obd/padapter.h
+++ b/src/adapter/obd/padapter.h
@@ -39,7 +39,8 @@ enum ProtocolTypes {
PROT_ISO15765_1150,
PROT_ISO15765_2950,
PROT_ISO15765_1125,
- PROT_ISO15765_2925
+ PROT_ISO15765_2925,
+ PROT_J1850_VPW4X
};
// Adapters
@@ -67,6 +68,7 @@ public:
virtual void close() {}
virtual void wiringCheck() = 0;
virtual void sendHeartBeat() {}
+ virtual void setSpeed() {} // vpw adapter overrides this and sets 1x or 4x
virtual int getProtocol() const = 0;
virtual void kwDisplay() {}
bool isConnected() const { return connected_; }
diff --git a/src/adapter/obd/vpw.cpp b/src/adapter/obd/vpw.cpp
old mode 100644
new mode 100755
index ada0b87..38b88e5
--- a/src/adapter/obd/vpw.cpp
+++ b/src/adapter/obd/vpw.cpp
@@ -7,6 +7,7 @@
#include <memory>
#include <adaptertypes.h>
+#include <cstdio> // for sprintf debugging
#include <GpioDrv.h>
#include <Timer.h>
#include <PwmDriver.h>
@@ -44,18 +45,18 @@ void VpwAdapter::close()
*/
int VpwAdapter::sendToEcu(const Ecumsg* msg)
{
- insertToHistory(msg); // Buffer dump
+ insertToHistory(msg); // Buffer dump
// Wait for bus to be inactive
//
- if (!driver_->wait4Ready(TV6_TX_NOM, TV4_TX_MIN, timer_)) {
+ if (!driver_->wait4Ready(tv6_tx_nom, tv4_tx_min, timer_)) {
return 0;
}
TX_LED(true); // Turn the transmit LED on
// SOF pulse
- driver_->sendSofVpw(TV3_TX_NOM); // 200us
+ driver_->sendSofVpw(tv3_tx_nom); // 200us
for (int i = 0; i < msg->length(); i++) {
uint8_t ch = msg->data()[i]; // sent next byte in buffer
@@ -64,12 +65,12 @@ int VpwAdapter::sendToEcu(const Ecumsg* msg)
while (bits--) { // send each bit in the byte
if (bits & 0x01) { // Passive, set bus to 0
if (ch & 0x80) {
- driver_->sendPulseVpw(TV2_TX_NOM); // 128us
- Delay1us(TV2_TX_NOM / 2);
+ driver_->sendPulseVpw(tv2_tx_nom); // 128us
+ Delay1us(tv2_tx_nom / 2); // huh?
}
else {
- driver_->sendPulseVpw(TV1_TX_NOM); // 64us
- Delay1us(TV1_TX_NOM / 2);
+ driver_->sendPulseVpw(tv1_tx_nom); // 64us
+ Delay1us(tv1_tx_nom / 2); // huh?
}
if (driver_->getBit()) {
driver_->stop();
@@ -79,10 +80,10 @@ int VpwAdapter::sendToEcu(const Ecumsg* msg)
}
else { // Active, set bus to 1
if (ch & 0x80) {
- driver_->sendPulseVpw(TV1_TX_NOM); // 64us
+ driver_->sendPulseVpw(tv1_tx_nom ); // 64us
}
else {
- driver_->sendPulseVpw(TV2_TX_NOM); // 128us
+ driver_->sendPulseVpw(tv2_tx_nom ); // 128us
}
}
ch <<= 1;
@@ -101,11 +102,11 @@ int VpwAdapter::sendToEcu(const Ecumsg* msg)
*/
bool VpwAdapter::waitForSof()
{
- for (;;) {
- uint32_t val = driver_->wait4Sof(TV3_RX_MAX, timer_);
+ for (;;) {
+ uint32_t val = driver_->wait4Sof(tv3_rx_max, timer_);
if (val == 0xFFFFFFFF) // P2 timer expired
return false;
- if (val >= TV3_RX_MIN)
+ if (val >= tv3_rx_min)
break;
}
return true;
@@ -117,7 +118,7 @@ bool VpwAdapter::waitForSof()
*/
int VpwAdapter::receiveFromEcu(Ecumsg* msg, int maxLen)
{
- uint8_t* ptr = msg->data();
+ uint8_t* ptr = msg->data();
msg->length(0); // Reset the buffer byte length
// Wait SOF
@@ -141,13 +142,13 @@ int VpwAdapter::receiveFromEcu(Ecumsg* msg, int maxLen)
goto extr; // EOD Max expired, terminate receive on timeout
}
state = !state;
- if (pulse < TV1_RX_MIN) {
+ if (pulse < tv1_rx_min) {
goto exte; // pulse is too short
}
- if (pulse > TV2_RX_MAX) {
+ if (pulse > tv2_rx_max) {
goto exte; // pulse is too long
}
- ch |= (pulse > VPW_RX_MID) ? 1 : 0;
+ ch |= (pulse > vpw_rx_mid) ? 1 : 0;
}
*(ptr++) = ch ^ 0x55;
}
@@ -180,19 +181,20 @@ int VpwAdapter::onRequest(const uint8_t* data, int len)
* Will try to send PID0 to query the VPW protocol
* @param[in] sendReply Send reply flag
* @return PROT_J1850_VPW if ECU is supporting PWM protocol, 0 otherwise
+ * Modified to not auto test. Just trust that this is the protocol we want. Mods break ATSP
*/
int VpwAdapter::onConnectEcu(bool sendReply)
{
- uint8_t testSeq[] = { 0x01, 0x00 };
-
+ //uint8_t testSeq[] = { 0x01, 0x00 };
open();
- int reply = requestImpl(testSeq, sizeof(testSeq), sendReply);
-
- connected_ = (reply == REPLY_NONE);
- if (!connected_) {
- close(); // Close only if not succeeded
- }
- return connected_ ? PROT_J1850_VPW : 0;
+ //int reply = requestImpl(testSeq, sizeof(testSeq), sendReply);
+ //
+ //connected_ = (reply == REPLY_NONE);
+ //if (!connected_) {
+ // close(); // Close only if not succeeded
+ //}
+ //return connected_ ? PROT_J1850_VPW : 0;
+ return PROT_J1850_VPW;
}
int VpwAdapter::requestImpl(const uint8_t* data, int len, bool sendReply)
@@ -274,7 +276,13 @@ int VpwAdapter::getP2MaxTimeout() const
void VpwAdapter::getDescription()
{
bool useAutoSP = config_->getBoolProperty(PAR_USE_AUTO_SP);
- AdptSendReply(useAutoSP ? "AUTO, SAE J1850 VPW" : "SAE J1850 VPW");
+ bool vpw4x = config_->getBoolProperty(PAR_VPW_4X);
+ if (vpw4x) {
+ AdptSendReply(useAutoSP ? "AUTO, SAE J1850 VPW 4X" : "SAE J1850 VPW 4X");
+ }
+ else {
+ AdptSendReply(useAutoSP ? "AUTO, SAE J1850 VPW" : "SAE J1850 VPW");
+ }
}
/**
@@ -313,6 +321,50 @@ ext:
close();
}
+void VpwAdapter::setSpeed()
+{
+ if (!config_->getBoolProperty(PAR_VPW_4X)) {
+ tv1_tx_nom = TV1_TX_NOM;
+ tv2_tx_nom = TV2_TX_NOM;
+ tv3_tx_nom = TV3_TX_NOM;
+ tv4_tx_min = TV4_TX_MIN;
+ tv6_tx_min = TV6_TX_MIN;
+ tv5_tx_nom = TV5_TX_NOM;
+ tv5_tx_max = TV5_TX_MAX;
+ tv6_tx_nom = TV6_TX_NOM;
+ tv1_tx_adj = TV1_TX_ADJ;
+ tv2_tx_adj = TV2_TX_ADJ;
+ tv1_rx_min = TV1_RX_MIN;
+ tv2_rx_max = TV2_RX_MAX;
+ tv3_rx_min = TV3_RX_MIN;
+ tv3_rx_max = TV3_RX_MAX;
+ tv5_rx_min = TV5_RX_MIN;
+ tv6_rx_min = TV6_RX_MIN;
+ vpw_rx_mid = VPW_RX_MID;
+ }
+ else {
+ tv1_tx_nom = TV1_4X_TX_NOM;
+ tv2_tx_nom = TV2_4X_TX_NOM;
+ tv3_tx_nom = TV3_4X_TX_NOM;
+ tv4_tx_min = TV4_4X_TX_MIN;
+ tv6_tx_min = TV6_4X_TX_MIN;
+ tv5_tx_nom = TV5_4X_TX_NOM;
+ tv5_tx_max = TV5_4X_TX_MAX;
+ tv6_tx_nom = TV6_4X_TX_NOM;
+ tv1_tx_adj = TV1_4X_TX_ADJ;
+ tv2_tx_adj = TV2_4X_TX_ADJ;
+ tv1_rx_min = TV1_4X_RX_MIN;
+ tv2_rx_max = TV2_4X_RX_MAX;
+ tv3_rx_min = TV3_4X_RX_MIN;
+ tv3_rx_max = TV3_4X_RX_MAX;
+ tv5_rx_min = TV5_4X_RX_MIN;
+ tv6_rx_min = TV6_4X_RX_MIN;
+ vpw_rx_mid = VPW_4X_RX_MID;
+ }
+}
+
+
+
//-------------------------------------------------------------------------
//
// +---------+ +----+ +--+ +-----+ +----+ +--+-----+
diff --git a/src/adapter/obd/vpw.h b/src/adapter/obd/vpw.h
old mode 100644
new mode 100755
index 5c0fc09..df1b582
--- a/src/adapter/obd/vpw.h
+++ b/src/adapter/obd/vpw.h
@@ -33,6 +33,27 @@ private:
int requestImpl(const uint8_t* data, int len, bool sendReply);
Timer* timer_;
PwmDriver* driver_;
+
+ void setSpeed();
+
+ uint32_t tv1_tx_nom;
+ uint32_t tv2_tx_nom;
+ uint32_t tv3_tx_nom;
+ uint32_t tv4_tx_min;
+ uint32_t tv6_tx_min;
+ uint32_t tv5_tx_nom;
+ uint32_t tv5_tx_max;
+ uint32_t tv6_tx_nom;
+ uint32_t tv1_tx_adj;
+ uint32_t tv2_tx_adj;
+ uint32_t tv1_rx_min;
+ uint32_t tv2_rx_max;
+ uint32_t tv3_rx_min;
+ uint32_t tv3_rx_max;
+ uint32_t tv5_rx_min;
+ uint32_t tv6_rx_min;
+ uint32_t vpw_rx_mid;
+
};
#endif //__VPW_H__