Je vous file mon code source C++.
Code :
/*
IcedFluid
First version : 19/07/2004
Modified : 31/09/2004
15/09/2005
ECU PM7 Only
Dev Compiler : MS Visual C++ 6.0
*/
/*
INFORMATIONS :
FUEL MAP
o Adresse
$3EF2 (PM6 / PM7)
o Equations completes
injector pulse (ms) = (fuel map value + (224 / (2^multi))) / (208 / (2^multi))
fuel map value (hex) = (pulse x (208 / (2^multi))) - (224 / (2^multi))
o Equations simplifies
a = (224 / (2^multi))
b = (208 / (2^multi))
injector pulse (ms) = (fuel map value + a) / b
fuel map value (hex) = (pulse x b) - a
IGNITION MAP
o Adresses
$3DF3 (PM6)
$3CE5 (PM7)
o Equations
retard (angle en â) = ((igni map value) - 15 ) * 0.36
igni map value (hex) = (retard / 0.36) + 15
CHECKSUM
o activÚ
$23BF = 0x60
o desactivÚ
$23BF = 0x80
REV LIMITER
o Adresses
PM7 (HOT)
hb : high byte = @$0F53
lb : low byte = @$0F55
origine = 0x00, 0xFA = 7680 RPM
o Equations
RPM = 1920000 / ( ( *($) x 256) + *($+2) )
(hb x 256) + lb = 1920000 / RPM
o Algorithme de calcul hb & lb depuis RPM
V = 1920000 / RPM
hb = valeur_entiere(V / 256)
lb = V - (256 x hb)
nb : Attention a RPM = 0 (division par 0 !)
IDLE
o Adresses
PM7 (HOT)
hb : high byte = @$3B53
lb : low byte = @$3B55
origine = 0x09, 0x09 = 830 RPM
*/
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
typedef unsigned char uchar;
typedef unsigned short ushort;
class cPM7
{
public : cPM7();
public : ~cPM7();
public : bool read ( char * qfileName );
public : bool write( char * qfileName );
public : bool dump ( char * qfileName );
//
// SECTION MAPS
//
protected : void loadMap( ushort qoffset, void * qdstmap, ushort qsize );
protected : void writeMap( ushort qoffset, void * qsrcmap, ushort qsize );
protected : void loadFuelMap() { loadMap(ofuelmap, c_fuelmap, sizeof(c_fuelmap)); }
protected : void loadFuelMult() { loadMap(ofuelmult,c_fuelmult,sizeof(c_fuelmult)); }
protected : void loadIgniMap() { loadMap(oignimap, c_ignimap, sizeof(c_ignimap)); }
protected : void loadMaps() { loadFuelMap(); loadFuelMult(); loadIgniMap(); }
protected : void writeFuelMap() { writeMap(ofuelmap, c_fuelmap, sizeof(c_fuelmap)); }
protected : void writeIgniMap() { writeMap(oignimap, c_ignimap, sizeof(c_ignimap)); }
protected : float calcPulse( uchar qpulse, uchar qmulti );
protected : uchar calcPulse( float qpulse, uchar qmulti );
protected : float calcAngle( uchar qangle );
protected : uchar calcAngle( float qangle );
public : void buildMaps( void * qdstmap, void * qsrcmap );
public : bool fuelMap( uchar qrow, uchar qcol, float qvalue ){ return sMap(qrow, qcol, qvalue, f_fuelmap); }
public : bool igniMap( uchar qrow, uchar qcol, float qvalue ){ return sMap(qrow, qcol, qvalue, f_ignimap); };
public : float fuelMap( uchar qrow, uchar qcol ){ return gMap(qrow, qcol, f_fuelmap); }
public : float igniMap( uchar qrow, uchar qcol ){ return gMap(qrow, qcol, f_ignimap); }
protected : bool sMap( uchar qrow, uchar qcol, float qvalue, float * qmap );
protected : float gMap( uchar qrow, uchar qcol, float * qmap );
protected : char * floatToChar( float qvalue, int qcount );
protected : bool rowcol(uchar qrow, uchar qcol);
protected :
uchar c_fuelmap[255];
uchar c_fuelmult[15];
uchar c_ignimap[255];
float f_fuelmap[255];
float f_ignimap[255];
ushort ofuelmap;
ushort ofuelmult;
ushort oignimap;
//
// SECTION RPM STUFF
//
protected : ushort loadRpm(ushort qoffh, ushort qoffl);
protected : void writeRpm( ushort qrpm, ushort qoffh, ushort qoffl );
protected : ushort calcRpm( uchar qhb, uchar qlb );
protected : void calcRpm( ushort qrpm, uchar * qhb, uchar * qlb );
//
// SECTION REV.LIMITER
//
public : void setRevLimiter( ushort qrpm ) { revl = qrpm; }
protected : void loadRevLimiter() { revl = loadRpm(orvhb, orvlb); }
protected : void writeRevLimiter( ushort qrpm ) { writeRpm(revl, orvhb, orvlb); }
protected :
ushort revl;
ushort orvhb; //offset rev.limiter High Byte
ushort orvlb; //offset rev.limiter Low Byte
//
// SECTION IDLE
//
public : void setIdle( ushort qrpm ) { idle = qrpm; }
protected : void loadIdle() { idle = loadRpm(oidlhb, oidllb); }
protected : void writeIdle( ushort qrpm ) { writeRpm(idle, oidlhb, oidllb); }
protected :
ushort idle;
ushort oidlhb; //offset idle High Byte
ushort oidllb; //offset idle Low Byte
//
// SECTION CHECKSUM
//
protected : void writeChecksumDisabled();
protected :
ushort ochecksum;
//
// SECTION GENERAL
//
protected :
ushort szfile;
FILE * f;
};
cPM7::cPM7()
{
szfile = 16384; //16ko
f = NULL;
// MAPS
ofuelmap = 0x3EF2;
ofuelmult = 0x3FF1;
oignimap = 0x3CE5;
memset(c_fuelmap, 0, sizeof(c_fuelmap));
memset(c_fuelmult, 0, sizeof(c_fuelmult));
memset(c_ignimap, 0, sizeof(c_ignimap));
memset(f_fuelmap, 0, sizeof(f_fuelmap));
memset(f_ignimap, 0, sizeof(f_ignimap));
// REV.LIMITER
revl = 0;
orvhb = 0x0F53;
orvlb = 0x0F55;
// IDLE
idle = 0;
oidlhb = 0x3B53;
oidllb = 0x3B55;
// CHECKSUM
ochecksum = 0x23BF;
}
cPM7::~cPM7()
{
;
}
bool cPM7::rowcol(uchar qrow, uchar qcol)
{
if( qrow >= 0 && qrow <=17 )
if( qcol >= 0 && qcol <=15 )
return true;
return false;
}
bool cPM7::sMap( uchar qrow, uchar qcol, float qvalue, float * qmap )
{
if( rowcol(qrow, qcol) )
{
qmap[ (15 * qrow) + qcol ] = qvalue;
return true;
}
return false;
}
float cPM7::gMap( uchar qrow, uchar qcol, float * qmap )
{
if( rowcol(qrow, qcol) )
{
return qmap[ (15 * qrow) + qcol ];
}
return -1;
}
void cPM7::loadMap( ushort qoffset, void * qdstmap, ushort qsize )
{
fseek(f, qoffset, 0);
fread(qdstmap, 1, qsize, f);
}
void cPM7::writeMap( ushort qoffset, void * qsrcmap, ushort qsize )
{
fseek(f, qoffset, 0);
fwrite(qsrcmap, 1, qsize, f);
}
float cPM7::calcPulse( uchar qpulse, uchar qmulti )
{
float a = powf( 2, qmulti);
return (qpulse + (224 / a)) / (208 / a);
}
uchar cPM7::calcPulse( float qpulse, uchar qmulti )
{
float a = powf( 2, qmulti);
return (uchar)((qpulse * (208 / a)) - (224 / a));
}
float cPM7::calcAngle( uchar qangle )
{
return ((qangle - 15 ) * (float)0.36);
}
uchar cPM7::calcAngle( float qangle )
{
return (uchar)((qangle / 0.36) + 15);
}
void cPM7::buildMaps( void * qdstmap, void * qsrcmap )
{
int i, m;
for(i= m= 0; i<255; i++)
{
if( qdstmap == f_fuelmap && qsrcmap == c_fuelmap )
f_fuelmap[i] = calcPulse( c_fuelmap[i], c_fuelmult[m] );
if( qdstmap == f_ignimap && qsrcmap == c_ignimap )
f_ignimap[i] = calcAngle( c_ignimap[i] );
if( qdstmap == c_fuelmap && qsrcmap == f_fuelmap )
c_fuelmap[i] = calcPulse( f_fuelmap[i], c_fuelmult[m] );
if( qdstmap == c_ignimap && qsrcmap == f_ignimap )
c_ignimap[i] = calcAngle( f_ignimap[i] );
if( m >= 14 ) m = 0;
else m++;
}
}
ushort cPM7::calcRpm( uchar qhb, uchar qlb )
{
return (1920000 / ((qhb * 256) + (qlb)));
}
void cPM7::calcRpm( ushort qrpm, uchar * qhb, uchar * qlb )
{
long v;
if( qrpm <= 0 ){ qrpm = 1; }
if( qrpm > 15000 ){ qrpm = 15000; }
v = (long)(1920000 / qrpm);
*qhb = (uchar)(v / 256);
*qlb = (uchar)(v - (256 * (*qhb)));
}
ushort cPM7::loadRpm( ushort qoffh, ushort qoffl )
{
uchar hb, lb;
fseek(f, qoffh, 0);
fread(&hb, 1, sizeof(hb), f);
fseek(f, qoffl, 0);
fread(&lb, 1, sizeof(lb), f);
return calcRpm( hb, lb );
}
void cPM7::writeRpm( ushort qrpm, ushort qoffh, ushort qoffl )
{
uchar hb, lb;
calcRpm( qrpm, &hb, &lb );
fseek(f, qoffh, 0);
fwrite(&hb, 1, sizeof(hb), f);
fseek(f, qoffl, 0);
fwrite(&lb, 1, sizeof(lb), f);
}
void cPM7::writeChecksumDisabled()
{
uchar v = 0x80; // replace a 0x60 for kill the checksum routine
fseek(f, ochecksum, 0);
fwrite(&v, 1, sizeof(v), f);
}
bool cPM7::read( char * qfileName )
{
bool r = false;
if( (f = fopen(qfileName, "rb")) != NULL )
{
if( _filelength(f->_file) >= szfile )
{
loadMaps();
buildMaps( f_fuelmap, c_fuelmap );
buildMaps( f_ignimap, c_ignimap );
loadRevLimiter();
loadIdle();
r = true;
}
fclose(f);
}
return r;
}
bool cPM7::write( char * qfileName )
{
bool r = false;
if( (f = fopen(qfileName, "wb")) != NULL )
{
if( _filelength(f->_file) >= szfile )
{
buildMaps( c_fuelmap, f_fuelmap );
buildMaps( c_ignimap, f_ignimap );
writeFuelMap();
writeIgniMap();
writeRevLimiter( this->revl );
writeIdle( this->idle );
writeChecksumDisabled();
}
fclose(f);
}
return r;
}
char * cPM7::floatToChar( float qvalue, int qcount )
{
static char v[30];
int decimal, sign;
char * buf = _fcvt( qvalue, qcount, &decimal, &sign);
memset(v, 0, sizeof(v));
if( sign )
strcat(v, "-");
strncat(v, buf, decimal);
strcat (v, ",");
strcat (v, buf+decimal);
return v;
}
bool cPM7::dump(char * qfileName)
{
int l, c, map;
float * ptab;
char buf[100];
char * RPM[17] = {"500 ","600 ","700 ","800 ","900 ","1100","1300","1600","1900","2200","2600","3100","3700","4400","5300","6300","7400"};
char * MAP[15] = {"26","24","22","21","19","18","16","14","13","11","9","8","4","1","1,3" };
bool r = false;
if( (f = fopen(qfileName, "wb")) != NULL )
{
//
// Maps dump
//
for(map=0; map<2; map++)
{
// Show Maps Titles
if( map == 0 )
{
fputs("\r\n- FUEL MAP - ( x = vaccum (ingh) ; y = RPM ; values = injector pulse (milliseconds) ) \r\n", f);
ptab = &f_fuelmap[0];
}
if( map == 1 )
{
fputs("\r\n- IGNITION MAP - ( x = vaccum (ingh) ; y = RPM ; values = ignition advance (angle degrees) ) \r\n", f);
ptab = &f_ignimap[0];
}
//Show Vaccum Row
fputs("\r\n;\t\t", f);
for(c= 0; c<15; c++)
{
fputs(MAP[c], f);
fputs(";\t\t", f);
}
//Show RPM Columns and table values
fputs("\r\n", f);
for(l= 0; l<17; l++)
{
fputs(RPM[l], f);
fputs(";\t", f);
{
for(c= 0; c<15; c++)
{
fputs( floatToChar( ptab[ (15*l)+c ], 2 ), f );
fputs(";\t", f);
}
}
fputs("\r\n", f);
}
}//end for
//
// Show Rev.Limiter
//
fputs("\r\n- REV.LIMITER - \r\n", f);
sprintf(buf, "%d", revl );
fputs(buf, f);
fputs("\r\n", f);
//
// Show Idle
//
fputs("\r\n- IDLE - \r\n", f);
sprintf(buf, "%d", idle );
fputs(buf, f);
fputs("\r\n", f);
fclose(f);
}
return r;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// MAIN
///////////////////////////////////////////////////////////////////////////////////////////////////////
char * openFile();
char * saveFile();
int main (int argc, char * argv[])
{
cPM7 pm7;
pm7.read(openFile());
pm7.dump(saveFile());
return 0;
}
char * openFile()
{
static char srcFile[255];
OPENFILENAME ofn;
// Initialisation de la DialogBox de choix de fichier
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = srcFile;
ofn.nMaxFile = sizeof(srcFile)-1;
ofn.lpstrFilter = "*.BIN;*.bin";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
int getopen = GetOpenFileName(&ofn);
if( getopen )
{
if( strlen(ofn.lpstrFile) )
{
return ofn.lpstrFile;
}
}
return "";
}
char * saveFile()
{
static char dstFile[255];
OPENFILENAME ofn;
// Initialisation de la DialogBox de choix de fichier
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = dstFile;
ofn.nMaxFile = sizeof(dstFile)-1;
ofn.lpstrFilter = "";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
int getsave = GetSaveFileName(&ofn);
if( getsave )
{
if( strlen(ofn.lpstrFile) )
{
return ofn.lpstrFile;
}
}
return "";
}