Once again, with the sources this time :-)
//Marc
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <termios.h>
int p_word( unsigned char *buf, unsigned len )
{
unsigned short *wp = (unsigned short *)buf;
while ( len >= sizeof(unsigned short) )
{
printf( "%04x %5d ", *wp, *wp );
++wp;
len -= sizeof( short );
}
return len;
}
int p_byte( unsigned char *buf, unsigned len )
{
while ( len >= sizeof( unsigned char ) )
{
printf( " %02x %5d ", *buf, *buf );
++buf;
len -= sizeof( unsigned char );
}
return len;
}
int p_ascii( unsigned char *buf, unsigned len )
{
printf( "%.*s", len, buf );
return 0;
}
static struct
{
char offset;
char len;
char *descr;
int (*func)( unsigned char *, unsigned );
} ram_values[] =
{
{0x00,2,"Current timing period", p_word },
{0x02,2,"Injector pulse width", p_word },
{0x04,1,"L0111", p_byte},
{0x05,1,"L0013 b_map_L0013", p_byte },
{0x06,1,"b_air_adc", p_byte },
{0x07,1,"b_h2o_adc", p_byte },
{0x08,1,"b_curr_tps_adc", p_byte },
{0x09,1,"b_batt_adc", p_byte },
{0x0a,1,"L00F0", p_byte },
{0x0b,1,"L0106", p_byte },
{0x0c,1,"L0066", p_byte },
{0x0d,1,"L0066", p_byte },
{0x0e,1,"L0080", p_byte },
{0x0f,1,"L0081", p_byte },
{0x10,1,"L0082", p_byte },
{0x11,2,"w_mix_modifier", p_word },
{0x13,1,"L0054 Fuel Flags", p_byte },
{0x14,1,"L0083", p_byte },
{0x15,1,"L0087", p_byte },
{0x16,1,"L0088", p_byte },
{0x17,1,"L0089", p_byte },
{0x18,1,"L008A", p_byte },
{0x19,1,"L008A", p_byte },
{0x1a,1,"L8EFB", p_byte },
{0x1b,1,"B60E - EEPROM[0E]", p_byte },
{0x1c,1,"B620 - EEPROM[20]", p_byte },
{0x1d,1,"B621 - EEPROM[21]", p_byte },
{0x1e,1,"B622 - EEPROM[22]", p_byte },
{0x1f,1,"B624 - EEPROM[24]", p_byte },
{0x20,1,"B625 - EEPROM[25]", p_byte },
{0x21,1,"B626 - EEPROM[26]", p_byte },
{0x22,1,"B627 - EEPROM[27]", p_byte },
{0x23,1,"B628 - EEPROM[28]", p_byte },
{0x24,1,"B629 - EEPROM[29]", p_byte },
{0x25,1,"B62a - EEPROM[2a]", p_byte },
{0x26,1,"B62b - EEPROM[2b]", p_byte },
{0x27,1,"B62c - EEPROM[2c]", p_byte },
{0x28,1,"B62d - EEPROM[2d]", p_byte },
{0x29,1,"B62e - EEPROM[2e]", p_byte },
{0x2a,1,"B62f - EEPROM[2f]", p_byte },
{0x2b,1,"B630 - EEPROM[30]", p_byte },
{0x2c,1,"B631 - EEPROM[31]", p_byte },
{0x2d,1,"B632 - EEPROM[32]", p_byte },
{0x2e,1,"B633 - EEPROM[33]", p_byte },
{0x2f,1,"L87f2", p_byte },
{0x30,1,"L87f3", p_byte },
{0x31,1,"L87f4", p_byte },
{0x32,1,"L87f5", p_byte },
{0x33,1,"L87f6", p_byte },
{0x34,1,"L87f7", p_byte },
{0x35,11,"Serial Number", p_ascii },
{0x40,0x1d,"$0000", p_byte },
{0x6e,1,"L00da", p_byte },
{0x6f,1,"$007a", p_byte },
{0x70,1,"L007b security flags", p_byte },
{0x71,1,"B661 - EEPROM[61]", p_byte },
{0x72,1,"B662 - EEPROM[62]", p_byte },
{0,0,0}
};
#define LAST_DUMP_ENTRY 0x72
int showall( unsigned char *buf, unsigned len )
{
unsigned idx = 0;
while ( len && ram_values[idx].descr )
{
printf( "%02x %20s ",
ram_values[idx].offset,
ram_values[idx].descr );
if ( ram_values[idx].func
&& ram_values[idx].func( &buf[ram_values[idx].offset],
ram_values[idx].len ) )
{
return -1;
}
printf( "\n" );
len -= ram_values[idx].len;
++idx;
}
return 0;
}
int dumpall( int ecu )
{
unsigned char buf[ LAST_DUMP_ENTRY + 1 ];
unsigned char c;
unsigned char response;
for ( c = 0; c <= LAST_DUMP_ENTRY; ++c )
{
if ( ( c % 16 ) == 0 ) printf( "\n%02x: ", c );
if ( write( ecu, &c, 1 ) != 1 )
{
perror( "write" );
return -1;
}
if ( read( ecu, &response, 1 ) != 1 )
{
perror( "read" );
break;
}
buf[c] = response & 0xff;
printf( "%02x ", buf[c] );
fflush( stdout );
}
printf( "\n" );
showall( buf, c );
}
int main( int argc, char **argv )
{
char *port;
int ecu;
fd_set rdfds,efds;
struct timeval poll;
port = getenv( "ECU_PORT" );
if ( !port )
{
port = "/dev/ecu_port";
}
ecu = open( port, O_NOCTTY|O_RDWR );
if ( ecu < 0 )
{
perror( "open" );
printf( "Please point ECU_PORT or /dev/ecu_port to the serial port"
" where the ECU is\nconnected,"
" and ensure you have read/write access to the port.\n" );
return -1;
}
struct termios old_settings;
struct termios new_settings;
if ( tcgetattr( ecu, &old_settings ) < 0 )
{
perror( "tcgetattr" );
exit(1);
}
new_settings = old_settings;
cfmakeraw( &new_settings );
tcsetattr( ecu, TCSANOW, &new_settings );
//printf( "ECU opened at %d baud\n", cfgetispeed( &old_settings ));
poll.tv_sec = 0;
poll.tv_usec = 20;
int nfd;
while (1)
{
FD_ZERO( &rdfds );
FD_ZERO( &efds );
FD_SET( 0, &rdfds );
FD_SET( 0, &efds );
FD_SET( ecu, &rdfds );
FD_SET( ecu, &efds );
nfd = select( ecu+1, &rdfds, NULL, &efds, &poll );
if ( (nfd < 0 ) || FD_ISSET( 0, &efds ) || FD_ISSET( ecu, &efds ) )
{
perror( "select" );
tcsetattr( ecu, TCSAFLUSH, &old_settings );
close(ecu);
exit(1);
}
if ( nfd == 0 )
{
printf( "ecu> " ); fflush( stdout );
FD_ZERO( &rdfds );
FD_SET( 0, &rdfds );
FD_SET( ecu, &rdfds );
nfd = select( ecu+1, &rdfds, NULL, NULL, NULL );
}
if ( nfd < 0 )
{
perror( "select" );
tcsetattr( ecu, TCSAFLUSH, &old_settings );
close( ecu );
exit(1);
}
if ( FD_ISSET( ecu, &rdfds ))
{
unsigned char ecubuf[ 128 ];
int nb,i;
nb = read( ecu, ecubuf, sizeof( ecubuf ) );
if ( ( nb < 0 ) && ( errno != EAGAIN ) )
{
perror( "read<ecu>" );
}
if ( nb > 0 )
{
printf( "[ " );
for ( i = 0; i < nb; ++i )
{
printf( "%02x ", ecubuf[i] );
}
printf( "]\n" );
}
}
if ( FD_ISSET( 0, &rdfds ))
{
char rdbuf[ 128 ];
int nb;
nb = read( 0, rdbuf, sizeof( rdbuf ));
if ( nb < 0 )
{
perror( "read<stdin>" );
exit(1);
}
if ( nb == 0 )
{
tcsetattr( ecu, TCSAFLUSH, &old_settings );
close( ecu );
exit(0);
}
rdbuf[ nb-1 ] = '\0';
if ( !strcmp( rdbuf, "dump" ) )
{
dumpall( ecu );
}
else if ( !strcmp( rdbuf, "help" )
|| !strcmp( rdbuf, "?" ) )
{
printf( "dump - dump all from 00 to 7f\n"
"quit - exit cleanly\n"
"xx xx (hex nibbles) - send these\n" );
}
else if ( !strcmp( rdbuf, "quit" ) )
{
tcsetattr( ecu, TCSAFLUSH, &old_settings );
close( ecu );
exit(0);
}
else
{
char *s;
unsigned long l;
char *cp;
s = strtok( rdbuf, " " );
while ( s )
{
l = strtoul( s, &cp, 16 );
if ( *s && !*cp && (l < 0x100) )
{
unsigned char ch = ( l & 0xff );
printf( "<%02x>", ch );
if ( write( ecu, &ch, 1 ) != 1 )
{
perror( "write<ecu>" );
}
}
else
{
printf( "Don't understand '%s', try 'help'.\n", s );
}
s = strtok( NULL, " " );
}
}
} // read on stdin
} // while (1)
tcsetattr( ecu, TCSAFLUSH, &old_settings );
close( ecu );
return 0;
}
Marc Bongartz wrote:
> Hi MC,
>
> I may be able to help with this one, having spent quite some time with my
> Marelli IAW 4WF ECU (from a 1996 Fiat Coupe 16VT). I'm attaching a
> piece of source code (for Linux, but should give you an idea). To
> summarize,
>
> you basically send an address byte (between 0x00 and 0x72) and the ECU
> returns a byte representing the data or a part of it. For example, if
> you send
> 0x08, the ECU will return the current ADC reading of the TPS sensor.
>
> Note I haven't actually communicated with the ECU (moved on to other
> things
> and
> never finished sorting out the interface). I know it's 4800 bauds though.
> If you have any docs on the Marelli's, I'll gladly accept it ;-)
>
> Regards,
> //Marc
>
>
> mente_catto wrote:
>
> > Mine is Magneti-Marelli.
> > Anyone have idea about how to read some values like RPM?
> > >From docs I found here it seems that "RAM CELLS" of the ECU must be
> > read, but how to understand where interested values reside into RAM?
> >
> > CU,
> > MC
> >
>
>
Received on Wed Nov 12 02:22:27 2003
This archive was generated by hypermail 2.1.8 : Wed Jan 02 2008 - 00:56:01 CET