Skip to content

Instantly share code, notes, and snippets.

@fluke9

fluke9/mcmess.cpp Secret

Created Nov 5, 2019
Embed
What would you like to do?
#include <Windows.h>
#include <stdint.h>
#include <string>
#include "MCmess.h"
#include "serial.h"
#include "log.h"
/* McMess routines
*
* some functions in here expect to be already in a specific mode for the
* 9th bit, so please bear that in mind...
*/
static int interbyte_delay = 0;
#define BIT9_ON {Serial_ChangeParityAndStopBits(MARKPARITY, TWOSTOPBITS);}
#define BIT9_OFF {Serial_ChangeParityAndStopBits(SPACEPARITY, TWOSTOPBITS);}
void McMessStandAloneInit(HANDLE serialHandle, bool highspeed)
{
LOG("doing fast mcmess init...");
EscapeCommFunction(serialHandle, CLRBREAK);
Sleep(300);
EscapeCommFunction(serialHandle, SETBREAK);
Sleep(25);
EscapeCommFunction(serialHandle, CLRBREAK);
Sleep(25);
// todo: flush serial receive buffer
Serial_ConsumeByte("DUMMYREAD");
uint8_t sendbuffer[255];
uint8_t initanswer[5];
uint8_t idx = 0;
uint8_t len = 2;
sendbuffer[idx++] = 0x80 | (len & 0b01111111);
sendbuffer[idx++] = 0x10;
sendbuffer[idx++] = 0xF1;
sendbuffer[idx++] = 0xA0;
sendbuffer[idx++] = highspeed ? 0xA6 : 0xA5;
sendbuffer[idx++] = 0x00;
// calculate checksum
for (int i = 0; i < idx - 1; i++)
sendbuffer[idx - 1] += sendbuffer[i];
Serial_SendAndConsumeBytes(sendbuffer, idx);
Serial_ConsumeBytes("INIT ANSWER", initanswer, 5);
Serial_LogBytes("received response from ECU: ", initanswer, 5);
if (initanswer[2] == 0xA6) LOG("mcmess connection established with highspeed");
else if (initanswer[2] == 0xA5) LOG("mcmess connection established with lowspeed");
else LOG("unknown answer from ECU...");
}
// Setup writing to a specified address, only 16bits available
// Memory is mapped as following:
// 0x0000-0x3FFF -> 0x38XXXX (external ram)
// 0xC000-0xFFFF -> internal ram
void McMessSetupWrite(unsigned short address)
{
uint8_t buf[255];
unsigned char highaddr = (address & 0xFF00) >> 8;
unsigned char lowaddr = (address & 0xFF);
//LOG("McMess: setting up write to 0x%x", address);
BIT9_OFF;
Serial_SendAndConsumeByte(0x00); Sleep(interbyte_delay);
Serial_SendAndConsumeByte(lowaddr); Sleep(interbyte_delay);
Serial_ConsumeBytes("DATA", buf, 2);
BIT9_ON;
Serial_SendAndConsumeByte(0x25); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
BIT9_OFF;
Serial_SendAndConsumeByte(0x00); Sleep(interbyte_delay);
Serial_SendAndConsumeByte(highaddr); Sleep(interbyte_delay);
Serial_ConsumeBytes("DATA", buf, 2);
BIT9_ON;
Serial_SendAndConsumeByte(0x26); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
}
void McMessSetupSetLowAddress(unsigned char lowaddr)
{
uint8_t buf[255];
//LOG("McMessSetupLowAddress %x", lowaddr);
BIT9_OFF;
Serial_SendByte(0x00); Sleep(interbyte_delay);
Serial_SendByte(lowaddr); Sleep(interbyte_delay);
Serial_ConsumeBytes("DATA", buf, 2);
BIT9_ON;
Serial_SendByte(0x25); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
}
void McMessWriteByte(uint8_t data, bool silent)
{
uint8_t buf[255];
if (!silent)
LOG("McMessWriteByte %2x", data);
BIT9_OFF;
Serial_SendAndConsumeByte(0x00); Sleep(interbyte_delay);
Serial_SendAndConsumeByte(data); Sleep(interbyte_delay);
Serial_ConsumeBytes("DATA", buf, 2);
BIT9_ON;
Serial_SendAndConsumeByte(0x34); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
Serial_SendAndConsumeByte(0x2F); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
}
void McMessWriteShortCPU(uint16_t data)
{
//LOG("McMessWriteShortCPU %4x", data);
McMessWriteByte(uint8_t(data & 0xFF), true);
McMessWriteByte(uint8_t((data & 0xFF00) >> 8), true);
}
void McMessWriteByteAddressToTable(uint32_t data)
{
//LOG("McMessWriteByteAddressToTable %4x", data);
McMessWriteByte(uint8_t((data & 0xFF)), true);
McMessWriteByte(uint8_t((data & 0xFF00) >> 8), true);
McMessWriteByte(uint8_t((data & 0xFF0000) >> 16), true);
McMessWriteByte(uint8_t((data & 0xFF000000) >> 24), true);
}
void McMessWriteWordAddressToTable(uint32_t data)
{
//LOG("McMessWriteWordAddressToTable %4x", data);
McMessWriteByte(uint8_t((data & 0xFF)), true);
McMessWriteByte(uint8_t((data & 0xFF00) >> 8), true);
McMessWriteByte(uint8_t((data & 0xFF0000) >> 16), true);
McMessWriteByte(uint8_t((data & 0xFF000000) >> 24), true);
McMessWriteByte(uint8_t(((data + 1) & 0xFF)), true);
McMessWriteByte(uint8_t(((data + 1) & 0xFF00) >> 8), true);
McMessWriteByte(uint8_t(((data + 1) & 0xFF0000) >> 16), true);
McMessWriteByte(uint8_t(((data + 1) & 0xFF000000) >> 24), true);
}
void McMessWriteBytes(uint8_t* data, uint8_t len)
{
for (uint8_t i = 0; i < len; i++)
McMessWriteByte(data[i]);
}
void McMessWriteSyncTable(unsigned char data)
{
uint8_t buf[255];
//LOG("McMess: writing to synctable %x", data);
BIT9_OFF;
Serial_SendAndConsumeByte(0x00); Sleep(interbyte_delay);
Serial_SendAndConsumeByte(data); Sleep(interbyte_delay);
Serial_ConsumeBytes("DATA", buf, 2);
BIT9_ON;
Serial_SendAndConsumeByte(0x34); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
Serial_SendAndConsumeByte(0x31); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
}
void McMessReadSyncTable()
{
// can by any byte except 0x1AA, must not be 112
Serial_SendAndConsumeByte(0x12); Sleep(interbyte_delay);
}
void McMessExitReadSyncTable()
{
Serial_SendByte(0xAA);
Serial_SendByte(0xAA);
Serial_SendByte(0xAA);
Serial_SendByte(0xAA);
//Serial_SendAndConsumeByte(0xAA); Sleep(interbyte_delay);
//return Serial_ConsumeByte("RETCODE") == 0x55;
}
void McMessSwitchToSyncReading()
{
Serial_SendAndConsumeByte(0x3d); Sleep(interbyte_delay);
Serial_ConsumeByte("RETCODE");
}
uint8_t* McMessReadBytes(unsigned short address)
{
static uint8_t returndata[2];
unsigned char bytes[2];
bytes[0] = (address & 0xFF00) >> 8;
bytes[1] = address & 0xFF;
BIT9_OFF; //temp
printf("requesting: %04x\n", address);
Serial_SendAndConsumeBytes(bytes, 2); Sleep(interbyte_delay);
Serial_ConsumeBytes("READADDR", returndata, 2);
return returndata;
}
// crude function trying to get ecu out of stuck mcmess ...
void McMessTryRevive()
{
//g_showdata = 2;
EscapeCommFunction(Serial_GetHandle(), CLRBREAK);
Sleep(200); //
EscapeCommFunction(Serial_GetHandle(), SETBREAK);
Sleep(80);
EscapeCommFunction(Serial_GetHandle(), CLRBREAK);
//EscapeCommFunction(Serial_GetHandle(), SETBREAK);
Serial_ConsumeByte("NULL");
Serial_SendByte(0xA6);
Serial_ConsumeByte("NULL");
Serial_ChangeBaudRate(125000, MARKPARITY, TWOSTOPBITS);
Serial_SendByte(0x12);
Serial_ConsumeByte("NULL");
Serial_SendByte(0xAA);
Serial_ConsumeByte("NULL");
//Serial_ConsumeByte("ANSWER");
//Serial_ConsumeByte("KB0");
Serial_ChangeBaudRate(10400, NOPARITY, ONESTOPBIT);
Sleep(2000);
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment