?? main.c
字號(hào):
/*************************************************************************
** AVR ISO 9141/14230-2 Interface
** by Michael Wolf
**
** Released under GNU GENERAL PUBLIC LICENSE
**
** contact: webmaster@mictronics.de
** homepage: www.mictronics.de
**
** Revision History
**
** when what who why
**
** Used develompent tools (download @ www.avrfreaks.net):
** Programmers Notepad v2.0.5.32
** WinAVR (GCC) 3.4.1
** AvrStudio4 for simulating and debugging
**
** [ Legend: ]
** [ + Added feature ]
** [ * Improved/changed feature ]
** [ - Bug fixed (I hope) ]
**
** ToDo:
**
**************************************************************************/
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <avr/wdt.h>
#include "main.h"
#include "iso.h"
/*
**---------------------------------------------------------------------------
**
** Abstract: Main routine
**
**
** Parameters: none
**
**
** Returns: NULL
**
**
**---------------------------------------------------------------------------
*/
int main(void)
{
wdt_disable(); // make sure the watchdog is not running
UBRRH = UART_BAUDRATE>>8; // set baud rate
UBRRL = UART_BAUDRATE;
UCSRB =((1<<RXCIE)|(1<<RXEN)|(1<<TXEN)); // enable Rx & Tx, enable Rx interrupt
UCSRC =((1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)); // config USART; 8N1
serial_msg_pntr = &serial_msg_buf[0]; // init serial msg pointer
iso_glob.uart_n_baud = N_10400; // set baud rate to 10,4kBaud
iso_hardware_init(); // init ISO hardware
iso_uart_init(); // init ISO software UART
ident(); // send identification to terminal
serial_putc('>'); // send initial command prompt
sei(); // enable interrupts
for(;;)
{
while( CHECKBIT(parameter_bits, MON_RX) || CHECKBIT(parameter_bits, MON_TX) )
{
unsigned char iso_msg_buf[260]; // ISO message buffer
unsigned char *iso_msg_pntr = &iso_msg_buf[0]; // msg pointer
unsigned int recv_nbytes; // byte counter
recv_nbytes = iso_recv_msg(iso_msg_buf); // get ISO message
if( !(recv_nbytes & 0x8000) ) // proceed only with no errors
{
iso_msg_pntr = &iso_msg_buf[0];
// check for respond from correct addr or monitor all mode
if( (CHECKBIT(parameter_bits, MON_RX) && CHECKBIT(parameter_bits, MON_TX))
||
((mon_receiver == *(iso_msg_pntr+1)) && CHECKBIT(parameter_bits, MON_RX) )
||
((mon_transmitter == *(iso_msg_pntr+2)) && CHECKBIT(parameter_bits, MON_TX) )
)
{
/*
if( !CHECKBIT(parameter_bits, HEADER) )
{ // surpess CRC and header bytes output
recv_nbytes -= 4;
iso_msg_pntr += 3;
}
if(CHECKBIT(parameter_bits, PACKED))
{ // check respond CRC
if( *(iso_msg_pntr+(recv_nbytes-1)) == iso_checksum(iso_msg_buf, recv_nbytes-1) )
serial_putc(recv_nbytes); // length byte
else
serial_putc(recv_nbytes&0x8000); // length byte with error indicator set
}
*/
// output response data
for(;recv_nbytes > 0; --recv_nbytes)
{
if(CHECKBIT(parameter_bits, PACKED))
serial_putc(*iso_msg_pntr++); // data byte
else
{
serial_put_byte2ascii(*iso_msg_pntr++);
serial_putc(' ');
}
}
if(!CHECKBIT(parameter_bits, PACKED))
{// formated output with CR and optional LF
serial_putc('\r');
if(CHECKBIT(parameter_bits, LINEFEED)) serial_putc('\n');
}
} // end if valid monitoring addr
} // end if message recv
} // end while monitoring active
} // endless loop
return 0;
}
/*
**---------------------------------------------------------------------------
**
** Abstract: Processing of received serial string
**
** Parameters: none
**
** Returns: 0 = unknown
** 1 = OK
** 2 = bus busy
** 3 = bus error
** 4 = data error
** 5 = no data
** 6 = data ( also to surpress any other output )
**
**---------------------------------------------------------------------------
*/
char serial_processing(void)
{
signed char *serial_msg_pntr = strlwr(serial_msg_buf); // convert string to lower
signed char serial_msg_len = strlen(serial_msg_buf); // get string length
signed char *var_pntr = 0; // point to different variables
if( (*(serial_msg_pntr)=='a') && (*(serial_msg_pntr+1)=='t')) // check for "at" or hex
{ // is AT command
// AT command found
switch( *(serial_msg_pntr+2) ) // switch on "at" command
{
case 'a': // auto receive address on
if(*(serial_msg_pntr+3) == 'r') SETBIT(parameter_bits, AUTO_RECV);
if( iso_req_header[0] & 0x80) // check for functional or physical addr
auto_recv_addr = iso_req_header[2]; // use physical recv addr
else if( iso_req_header[0] & 0xC0)
auto_recv_addr = iso_req_header[1]+1; // use funct recv addr
return 1;
case 'd': // set defaults
parameter_bits = ECHO|LINEFEED|RESPONSE|AUTO_RECV;
timeout_multiplier = 0x19; // set default timeout to 4ms * 25 = 100ms
iso_req_header[0] = 0xC1; // functional addressing
iso_req_header[1] = 0x33; // tester addr
iso_req_header[2] = 0xF1; // target addr
return 1;
case 'e': // echo on/off
if(*(serial_msg_pntr+3) == '1')
SETBIT(parameter_bits, ECHO);
else
CLEARBIT(parameter_bits, ECHO);
return 1;
case 'i': // send ident string
ident();
return 1;
case 'l': // linefeed on/off (only for data strings)
if(*(serial_msg_pntr+3) == '1')
SETBIT(parameter_bits, LINEFEED);
else
CLEARBIT(parameter_bits, LINEFEED);
return 1;
case 'h': // show headers on/off
if(*(serial_msg_pntr+3) == '1')
SETBIT(parameter_bits, HEADER);
else
CLEARBIT(parameter_bits, HEADER);
return 1;
case 'r': // show response on/off
if(*(serial_msg_pntr+3) == '1')
SETBIT(parameter_bits, RESPONSE);
else
CLEARBIT(parameter_bits, RESPONSE);
return 1;
case 'f': // send formated
if(*(serial_msg_pntr+3) == 'd')
CLEARBIT(parameter_bits, PACKED);
return 1;
case 'p': // send packed data
if(*(serial_msg_pntr+3) == 'd')
SETBIT(parameter_bits, PACKED);
return 1;
case 'm': // switch into monitoring mode
switch(*(serial_msg_pntr+3))
{
case 'a':
SETBIT(parameter_bits, MON_RX); // monitor all
SETBIT(parameter_bits, MON_TX);
return 6; // return, no following parameter
case 'r': // monitor only receiver addr
SETBIT(parameter_bits, MON_RX); // monitor receiver only
CLEARBIT(parameter_bits, MON_TX);
var_pntr = &mon_receiver;
break; // get following parameter
case 't': // monitor only transmitter addr
CLEARBIT(parameter_bits, MON_RX);
SETBIT(parameter_bits, MON_TX); // monitor transmitter only
var_pntr = &mon_transmitter;
break; // get following parameter
}
if(
isxdigit(*(serial_msg_pntr+4)) && isxdigit(*(serial_msg_pntr+5))
&& ( serial_msg_len == 6)
) // proceed when next two chars are hex
{
// make 1 byte hex from 2 chars ASCII and save
*var_pntr = ascii2byte(serial_msg_pntr+4);
return 6;
}
case 's': // commands SH,SR or ST
if( isxdigit(*(serial_msg_pntr+4)) && isxdigit(*(serial_msg_pntr+5)) )
{ // proceed when next two chars are hex
switch(*(serial_msg_pntr+3))
{
case 'h': // set header bytes
if(
isxdigit(*(serial_msg_pntr+6)) && isxdigit(*(serial_msg_pntr+7))
&& isxdigit(*(serial_msg_pntr+8)) && isxdigit(*(serial_msg_pntr+9))
&& ( serial_msg_len == 10)
) // proceed when next four chars are hex
{
// make 3 byte hex from 6 chars ASCII and save
iso_req_header[0]=ascii2byte(serial_msg_pntr+4);
iso_req_header[1]=ascii2byte(serial_msg_pntr+6);
iso_req_header[2]=ascii2byte(serial_msg_pntr+8);
if( CHECKBIT(parameter_bits, AUTO_RECV) )
{
if( iso_req_header[0] & 0x04) // check for functional or physical addr
auto_recv_addr = iso_req_header[2]; // use physical recv addr
else
auto_recv_addr = iso_req_header[1]+1; // use funct recv addr
}
return 1;
}
break;
case 't': // set response timeout multipler
var_pntr = &timeout_multiplier;
break;
case 'r': // set receive address and manual receive mode
var_pntr = &auto_recv_addr;
CLEARBIT(parameter_bits, AUTO_RECV);
break;
} // end switch char 3
if(serial_msg_len == 6)
{
*var_pntr =ascii2byte(serial_msg_pntr+4);
if (timeout_multiplier < 8) timeout_multiplier = 8; // set multiplier for minimum of 32ms timout
return 1;
}
} // end if char 4 and 5 isxdigit
return 0;
case 'z': // reset all and restart device
wdt_enable(WDTO_15MS); // enable watdog timeout 15ms
for(;;); // wait for watchdog reset
default: // return error, unknown command
return 0;
}
}
else
{ // is OBD hex command
// no AT found, must be HEX code
if( (serial_msg_len & 1) || (serial_msg_len > 16) ) // check for "even" message lenght
return 0; // and maximum of 8 data bytes
serial_msg_len /= 2; // use half the string lenght for byte count
while( *serial_msg_pntr ) // check all chars are valid hex chars
{
if(!isxdigit(*serial_msg_pntr))
return 0;
++serial_msg_pntr;
}
serial_msg_pntr = &serial_msg_buf[0]; // reset pointer
unsigned char iso_msg_buf[260]; // ISO message to be send
unsigned char *iso_msg_pntr = &iso_msg_buf[0]; // msg pointer
unsigned char cnt; // byte counter
// convert serial message from 2 byte ASCII to 1 byte binary and store
for(cnt = 0; cnt < serial_msg_len; ++cnt)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -