AVR to Arduino - VPW

Ecu Hardware Modifications
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

ejukated wrote:Great project! I actually etched a PCB from that design and built the interface years ago to reset an code in a LS1 I still have it here somewhere but I think I blew the PIC mucking around with something
That would be absolutely mint if you could find that sketch. :thumbup: Thats another thing on the "to-do" list if I cant convert this to the Arduino.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

This bits going to be quick large! This part is the receiving,sending and CRC functions are performed. Note that this would be a great point to be able to edit that 12byte maximum send/receive! :thumbup:



/*
**---------------------------------------------------------------------------
**
** Abstract: Receive J1850 frame (max 12 bytes)
**
** Parameters: Pointer to frame buffer
**
** Returns: Number of received bytes OR in case of error, error code with
** bit 7 set as error indication
**
**---------------------------------------------------------------------------
*/
uint8_t j1850_recv_msg(uint8_t *msg_buf ) //as seen in j1850.h file.. declared function : Arduino form = byte j1850_recv_msg(byte *msgbuf)
{
uint8_t nbits; // bit position counter within a byte - byte nbits
uint8_t nbytes; // number of received bytes -byte nbytes
uint8_t bit_state; // used to compare bit state, active or passive -byte bit_state
/*
wait for responds
*/

timer1_start(); //Start the timer
while(!is_j1850_active()) // run as long bus is passive (IDLE) //Run While bus is idle - Idle = No Information passing through!!!!!
{
if(TCNT1 >= WAIT_100us) // check for 100us // check if timer has reached 100us
{
timer1_stop(); //Once reached 100us, stop timer
return J1850_RETURN_CODE_NO_DATA | 0x80; // error, no responds within 100us - No response after 100us.. NO DATA!
}
}

// wait for SOF -Start of frame
timer1_start(); // restart timer1 - Restart timer, TCNT1 will reset to 0
while(is_j1850_active()) // run as long bus is active (SOF is an active symbol) - Keep running while there is data available
{
if(TCNT1 >= RX_SOF_MAX) return J1850_RETURN_CODE_BUS_ERROR | 0x80; // error on SOF timeout - If TCNT1 is greater that the SOF RX max time.. Error
}

timer1_stop(); // Stop timer
if(TCNT1 < RX_SOF_MIN) return J1850_RETURN_CODE_BUS_ERROR | 0x80; // error, symbole was not SOF - If TCNT1 is less than min SOF.. Error

bit_state = is_j1850_active(); // store actual bus state - store bus state into variable
timer1_start(); - Start Timer again
for(nbytes = 0; nbytes < 12; ++nbytes) // Do this process for for 12 consecutive bytes. (get total frame)
{
nbits = 8; //set nbits = 8
do //While loop start here.. do below while(--nbits);// end 8 bit while loop
{
*msg_buf <<= 1; //msg buffer next byte
while(is_j1850_active() == bit_state) // compare last with actual bus state, wait for change - Check if bitstate has changed for next section
{
if(TCNT1 >= RX_EOD_MIN ) // check for EOD symbol - If same state and TCNT1 is greater then EOD minimum.. return nbytes
{
timer1_stop(); //stop timer
return nbytes; // return number of received bytes -return found nbytes
}
}
bit_state = is_j1850_active(); // store actual bus state - store new bus state
uint16_t tcnt1_buf = TCNT1; //int tcnt1_buf = TCNT1 - this stores the timer process value into 16bit integer
timer1_start(); //Restart timer again
if( tcnt1_buf < RX_SHORT_MIN) return J1850_RETURN_CODE_BUS_ERROR | 0x80; // error, pulse was to short - If the RX pulse was shorted than minimum.. error.

// check for short active pulse = "1" bit
if( (tcnt1_buf < RX_SHORT_MAX) && !is_j1850_active() ) //if tcnt1_buf value is less than the RX short max, and J1850 is not active
*msg_buf |= 1; //Store this bit

// check for long passive pulse = "1" bit
if( (tcnt1_buf > RX_LONG_MIN) && (tcnt1_buf < RX_LONG_MAX) && is_j1850_active() ) //if tcnt1_buf is greater than RXlongmin, less than RX Long Max and is active
*msg_buf |= 1; //store this bit

} while(--nbits);// end 8 bit while loop //loop through all 8 bits.

++msg_buf; // store next byte in message buffer

} // end 12 byte for loop - Loop through for 12bytes.

// return after a maximum of 12 bytes
timer1_stop(); //stop timer
return nbytes; //return nbytes
}
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

Now the Sending J1850 part..So far so good I think :thumbup:


/*
**---------------------------------------------------------------------------
**
** Abstract: Send J1850 frame (maximum 12 bytes)
**
** Parameters: Pointer to frame buffer, frame length
**
** Returns: 0 = error
** 1 = OK
**
**---------------------------------------------------------------------------
*/
uint8_t j1850_send_msg(uint8_t *msg_buf, int8_t nbytes) //Declared in header, Arduino form: byte j1850_send_msg(byte *msg_buf, int nbytes)
{
if(nbytes > 12) return J1850_RETURN_CODE_DATA_ERROR; // error, message to long, see SAE J1850 - If bytes to send is >12.. Error too long!.

j1850_wait_idle(); // wait for idle bus - Wait until idle before continuing

timer1_start(); //Start timer
j1850_active(); // set bus active - Set bus to active

while(TCNT1 < TX_SOF); // transmit SOF symbol - While timer process value < Transmit start of frame.. so this.

uint8_t temp_byte; // temporary byte store - byte temp_byte Stores a temporary byte
nbits; // bit position counter within a byte - is there a error here?? No declaration

uint16_t delay; // bit delay time - declares 16bit int delay

do //do this process
{
temp_byte = *msg_buf; // store byte temporary - temporary byte = *msg_buf
nbits = 8; //nbits is set to 8
while (nbits--) // send 8 bits - Do this for all 8 bits
{
if(nbits & 1) // start allways with passive symbol -start here
{
j1850_passive(); // set bus passive -Set bus to passive
timer1_start(); //Timer1 restart!
delay = (temp_byte & 0x80) ? TX_LONG : TX_SHORT; // send correct pulse lenght - Delay is set to required pulse length
while (TCNT1 <= delay) // wait - wait until reached required delay!
{
if(!J1850_PORT_IN & _BV(J1850_PIN_IN)) // check for bus error - if port low and pin in high.. send error
{
timer1_stop(); //stop timer
return J1850_RETURN_CODE_BUS_ERROR; // error, bus collision!
}
}
}
else // send active symbol
{
j1850_active(); // set bus active
timer1_start(); //restart timer
delay = (temp_byte & 0x80) ? TX_SHORT : TX_LONG; // send correct pulse lenght
while (TCNT1 <= delay); // wait - wait until timer process has reached delay
// no error check needed, ACTIVE dominates
}
temp_byte <<= 1; // next bit -move to next bit!
}// end nbits while loop - end the while loop after 8bytes
++msg_buf; // next byte from buffer -move to next byte in msg_buf
} while(--nbytes);// end nbytes do loop - continue for 12 bytes then stop

j1850_passive(); // send EOF symbol - finally set to passive
timer1_start(); //Restart timer
while (TCNT1 <= TX_EOF); // wait for EOF complete - While process value is less than TX end of frame
timer1_stop(); //stop timer once completed
return J1850_RETURN_CODE_OK; // no error - No error so return all good!!
}
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

And finally our CRC calculation. This is a little bit more confusing for me.. Im assuming this can be almost dropped straight into arduino after changing declarations.


/*
**---------------------------------------------------------------------------
**
** Abstract: Calculate J1850 CRC
**
** Parameters: Pointer to frame buffer, frame length
**
** Returns: CRC of frame
**
**---------------------------------------------------------------------------
*/
// calculate J1850 message CRC
uint8_t j1850_crc(uint8_t *msg_buf, int8_t nbytes) //declared in header, arduino form: byte j1850_crc(byte *msgbuf, int nbytes)
{
uint8_t crc_reg=0xff,poly,byte_count,bit_count; //Declares variables as bytes
uint8_t *byte_point; //byte_point pointer as byte
uint8_t bit_point; //declares bit point as byte

for (byte_count=0, byte_point=msg_buf; byte_count<nbytes; ++byte_count, ++byte_point) //So.. do until byte_count < nbytes , increase byte_count and byte_point
{
for (bit_count=0, bit_point=0x80 ; bit_count<8; ++bit_count, bit_point>>=1) //do while bitcount <8, increase bit_count and next bit of bit_point
{
if (bit_point & *byte_point) // case for new bit = 1
{
if (crc_reg & 0x80)
poly=1; // define the polynomial
else
poly=0x1c;
crc_reg= ( (crc_reg << 1) | 1) ^ poly;
}
else // case for new bit = 0
{
poly=0;
if (crc_reg & 0x80)
poly=0x1d;
crc_reg= (crc_reg << 1) ^ poly;
}
}
}
return ~crc_reg; // Return CRC
}
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
VL400
Posts: 4991
Joined: Sun Mar 01, 2009 2:54 pm
cars: VL Calais and Toyota Landcruiser. Plus some toys :)
Location: Perth, WA
Contact:

Re: AVR to Arduino - VPW

Post by VL400 »

Nice work tazzi :thumbup: You could also use AVR studio and GCC, might be easier than porting it to an arduino?

Can still use the arduino hardware and just use avrdude to flash in your hex file using the arduino bootloader.
User avatar
antus
Site Admin
Posts: 8251
Joined: Sat Feb 28, 2009 8:34 pm
cars: TX Gemini 2L Twincam
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B
Contact:

Re: AVR to Arduino - VPW

Post by antus »

Yep that crc routine will function the same as is.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

VL400 wrote:Nice work tazzi :thumbup: You could also use AVR studio and GCC, might be easier than porting it to an arduino?

Can still use the arduino hardware and just use avrdude to flash in your hex file using the arduino bootloader.
Ahh..... I didnt actually know that one! Ill look at that now infact.. If I can get something remotely working.. I can continue tweaking it later

*Edit* Have AVR studio dowloaded, WinAVR and AVR dude... From what I get, I want to compile the into a hexfile and then write that file to the arduino with the arduino bootloader(not sure how to do that)

*Edit2* Just so I dont lose any links, this confirms what VL said: https://forum.sparkfun.com/viewtopic.php?f=7&t=36985
Simply compile.. grab the hex file and write to arduino.. and should be fine..I think. :thumbup:
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

While Atmel studio contunues to do its 100th update. Might as well finish off the last main.c file.
This file is quite large... so ill break it up into pieces like always.


**************************************************************************/
#include <stdint.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <ctype.h>
#include "main.h"
#include "j1850.h"

/*
**---------------------------------------------------------------------------
**
** Abstract: Main routine
**
**
** Parameters: none
**
**
** Returns: NULL
**
**
**---------------------------------------------------------------------------
*/
// main routine
int16_t main( void ) //main routine.. Int16 main(void)
{
wdt_disable(); // make sure the watchdog is not running - Is timer related
UBRRH = DEFAULT_BAUD>>8; // set baud rate - Set the default baud (9600 I think from memory)
UBRRL = DEFAULT_BAUD;
UCSRB =((1<<RXCIE)|(1<<RXEN)|(1<<TXEN)); // enable Rx & Tx, enable Rx interrupt - Enable the RX and TX for comms
UCSRC =((1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)); // config USART; 8N1 - - USART config
serial_msg_pntr = &serial_msg_buf[0]; // init serial msg pointer - our pc comms msg container

j1850_init(); // init J1850 bus -begin j1850 initialization function

ident(); // send identification to terminal - send vblf to serial port

serial_putc('>'); // send initial command prompt - send '>' to serial port

sei(); // enable global interrupts - Turn on global interrupts

for(;;)
{
while( CHECKBIT(parameter_bits, MON_RX) ||
CHECKBIT(parameter_bits, MON_TX) ||
CHECKBIT(parameter_bits, MON_OBH)
)
{
uint8_t j1850_msg_buf[12]; // J1850 message buffer -Initialize 12byte buffer ...Here is our limitation.
uint8_t *j1850_msg_pntr = &j1850_msg_buf[0]; // msg pointer -byte array pointer
int8_t recv_nbytes; // byte counter -counts bytes received

recv_nbytes = j1850_recv_msg(j1850_msg_buf); // get J1850 frame - returns amount of bytes received as well.

if( !(recv_nbytes & 0x80) ) // proceed only with no errors - if no errors.. continue!
{
j1850_msg_pntr = &j1850_msg_buf[0]; -move to array

// check for respond from correct addr or monitor all mode
if( (CHECKBIT(parameter_bits, MON_RX) && CHECKBIT(parameter_bits, MON_TX))
||
((mon_receiver == *(j1850_msg_pntr+1)) && CHECKBIT(parameter_bits, MON_RX) )
||
((mon_transmitter == *(j1850_msg_pntr+2)) && CHECKBIT(parameter_bits, MON_TX) )
||
((mon_transmitter == *(j1850_msg_pntr)) && CHECKBIT(parameter_bits, MON_OBH) )
)
{
// surpess CRC and header bytes output
if( !CHECKBIT(parameter_bits, HEADER) )
{
if( CHECKBIT(parameter_bits, MON_OBH) || // check if one byte header frames are used
CHECKBIT(parameter_bits, USE_OBH)
)
{
recv_nbytes -= 2; // discard 1st header byte and CRC
j1850_msg_pntr += 1; // skip header byte
}
else
{
recv_nbytes -= 4; // discard 3 header bytes and CRC
j1850_msg_pntr += 3; // skip 3 header bytes
}
}

if(CHECKBIT(parameter_bits, PACKED))
{ // check respond CRC
if( *(j1850_msg_pntr+(recv_nbytes-1)) == j1850_crc(j1850_msg_buf, recv_nbytes-1) )
serial_putc(recv_nbytes); // length byte
else
serial_putc(recv_nbytes&0x80); // length byte with error indicator set
}

// output response data
for(;recv_nbytes > 0; recv_nbytes--)
{
if(CHECKBIT(parameter_bits, PACKED))
serial_putc(*j1850_msg_pntr++); // data byte
else
{
serial_put_byte2ascii(*j1850_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;
} // end of main()
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
ejukated
Posts: 443
Joined: Wed Mar 04, 2009 8:52 pm

Re: AVR to Arduino - VPW

Post by ejukated »

Tazzi wrote:
ejukated wrote:Great project! I actually etched a PCB from that design and built the interface years ago to reset an code in a LS1 I still have it here somewhere but I think I blew the PIC mucking around with something
That would be absolutely mint if you could find that sketch. :thumbup: Thats another thing on the "to-do" list if I cant convert this to the Arduino.
I had a look through my files, unfortunately I don't have the PCB layout anymore. I do still have the interface if you want a hand with any testing. I have a bench and techii all setup.
User avatar
Tazzi
Posts: 3431
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: AVR to Arduino - VPW

Post by Tazzi »

ejukated wrote:
Tazzi wrote:
ejukated wrote:Great project! I actually etched a PCB from that design and built the interface years ago to reset an code in a LS1 I still have it here somewhere but I think I blew the PIC mucking around with something
That would be absolutely mint if you could find that sketch. :thumbup: Thats another thing on the "to-do" list if I cant convert this to the Arduino.
I had a look through my files, unfortunately I don't have the PCB layout anymore. I do still have the interface if you want a hand with any testing. I have a bench and techii all setup.
Thats alright. May take you up on it, see how we progress!
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
Post Reply