Results 1 to 15 of 89

Thread: 1997 F-Body Tools

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #16
    Fuel Injected!
    Join Date
    Jan 2019
    Location
    Canada
    Posts
    484
    HomeBrew Cable (HBC) was designed initially to get around deficiencies the ELM327 cable presented me. I wanted to explore the PCM software fully but was unable to get past the restriction of 12 byte frames. To be fair, this restriction is part of J1850 standard. GM used this violation of the standard for the purposes of transfering large amounts of data between PCM and tester. It was this one issue that caused me to abandon the ELM327 and find another interface. I went looking for a store bought cable. Availability, cost and flexibility were the factors. At the time I started this project, there were no good candidates. There was one, but they didn't ship to Canada... So how hard could it be to design my own? Turns out it wasn't easy AND I am still chasing a few gremlins (now gone with v3?) buried deep in the code but at this time it is about 99%. This write up could help get rid of any final issues because it causes me to try and remember how/why things were done in order to write it all down. Here is my best shot:

    The HBC is based on an Arduino NANO module. This module is very low cost (mine cost ~5$, prices have gone up because of world semi shortages but still low cost). The module integrates an ATmega328P processor with all the circuits needed to make it run (clock, reset, power, CH340 USB serial interface). I won't discuss the CH340 or the bootstrap loader system here. The one thing that is important is that when the PC serial port is opened, it causes a reset in the NANO. When you write software for this setup, the port should remain open for the duration of what ever you are doing. Else wise, the module is reset and needs a delay of seconds (2S if I remember correctly)before the part re-boots it's self.

    J1850 Software
    --------------
    Again before I start, This is not intended to be a certified 100% grade AAA interface. I have not paid much attention to rise a fall times of signals. This could mean that the module could produce enough EMI to buzz an AM radio. Please remember that the intent is/was to build a workable interface that permitted up/down loading, testing, logging.

    Starting with the receive side: It is necessary to detect and measure the time between transitions in order to decode J1850 symbols. The software makes use of interrupts to do this because the latency of polling will not be accurate enough. The function "ISR(PCINT0_vect)" is run each time the pin changes state. Timer 2 (of the ATmega328P) is setup to run with a prescale of 32 and thus counts 2us increments. Each time the receive pin changes state (H->L OR L->H) the PCINT0 (that is PinChangeINTerrupt0)is serviced.

    PCINT0 needs to take care of timer overflows. For example if a L->H transition takes place when the timer reads 0xFFF0 and the pin transitions H->L 40us later the timer will then read 0x0010. This overflow condition needs to be looked after in order that the correct time is computed. Once the pulse duration is found, this time represents the width of the !PREVIOUS! bit. Using the previous bit level and the width, the symbol is looked up.

    Symbol Standard spec What the code does
    ----------------------------------------------------------------
    Invalid ; Pulse width less than 34us
    Short pulse > 34 <= 96 ; Pulse width 34us <--> 96us
    Long pulse > 96 <= 163 ; Pulse width 96us <--> 164us
    SOF > 163 <= 239 ; Pulse width 164us <--> 240us
    EOD > 163 <= 239 ; Pulse width 164us <--> 240us
    EOF > 239 N/A ; Pulse width greater than 240us
    BRK > 239 <= 1.0 sec ; Pulse width greater than 240us
    IFS > 280 N/A ;

    IFS is not so important in a system with only two nodes. The nodes work in a request/response manner, I have not yet found the need to time this.


    For accuracy, transmission of bits is also interrupt driven using timer 0. The service routine is TIMER0_COMPA_vect. The output always toggles for each bit sent. The level and width depend on the previous bit and the bit to be sent.

    The NextBit class provides a lookup of the next symbol to send. See NextBit.CPP and .H.


    At this point it may be easier to handle each of the files in order to understand the software. I have done my best to add comments to the code and to explain it BUT it isn't easy to write this all up. Here is a shot at a write up...

    Note1, it might have been easier to document this code with pseudo code. Does anyone have a tool they can recommend to ease this? I have no experience with pseudo code at all.

    Note2, A ghost was found buried deep in the code that was causing the bug I have been searching for. The request to document this code caused me to clean up, remove junk and generally consider things. The problem I found might help others who write code for arduino serial functions. Originally I wrote the end of frame to the PC like this
    Serial.print("\n") // DON'T DO THIS
    The above line creates a hex string of $0A $00. It then sends the character $0A, detects the string termination and returns. If you do this from an interrupt there is a problem that I don't understand with the .print function. It works 99% of the time but sometimes overwrites characters in the fifo. I was getting ramdom missing characters. My upper level software detected the missing character. This resulted most of the time with CRC fault. Other times the frame header got hit and I detected a missing response. I started to mess around with recovery from bad frames BUT in the ends solved it like this
    Serial.write(0x0A) // Faster easier cheaper works 100%
    I am now able to down load support for mode $35 to ram then with another bit of code dump TSide, format into Mot SRecords (S2/S9). I will post this stuff later.

    Note3, Newest software for HBC is in this post PLEASE get rid of the older stuff.



    Parse.cpp
    Parse.h
    ---------
    This pair files service inputs from the PC to the HBC. Valid inputs are:

    -'I' Initialize the transmit side to receive a frame. This is optionally done to reset the transmit input.
    This command may be send after the NANO has booted. That is about 2.5S after the port is opened. In most (all?) cases it is never needed.

    -' ' Space character is used to make the line human readable. Space may optionally be sent between pairs of hex data.

    -'characters in the range of 0-9, A-F or a-f' Characters sent are the frame content. Space may optionally be used between hex pairs but not separating the pairs.

    -'\n' Hex $0A character instructs HBC to send the frame in the buffer. The TX buffer sent has CRC appended to it before the frame is sent.

    The code simply checks the input serial stream from the PC to see if characters are available. If characters are available, data input characters are placed in the tx buffer sequentially. If \n is received, the buffer is sent. I command resets/initializes the transmit buffer to it's initial point

    NextBit.cpp
    NextBit.h
    -----------
    This pair of files instansiates the next bit class. This is responsible for generation of the next symbol during transmit. NextBit is called from the timer 0 interrupt service. The return value is used to set the level and length of the next bit to be transmitted.

    HexOut.cpp
    HexOut.h
    ----------
    This pair of files takes a hex character input and transmits three ascii characters to the PC.

    CRC8_SAE.cpp
    CRC8_SAE.h
    ------------
    This pair of files takes an array of hex data representing the frame to be sent and returns the CRC. Used to append crc to the transmit stream. The HBC does not check CRC on the receive stream. This could easily be done, but is better handled by running this routine in the PC. That way the CRC covers not only the J1850 serial but also the NRZ link between the arduino micro to CMD640 and also the USB to the PC. An arguement could be made for generating the transmit CRC in the PC as well. My decision here made it much easier for me to send commands from a terminal without needing a separate calc for CRC to hand enter into the frame. In the future a command could be added to inhibit appending of CRC by the HBC.

    J1850_VPW.cpp
    J1850_VPW.h
    -------------
    This pair of files looks after initialization of HBC, interrupt services and debounce of the input. The initialization sets up Timer 0 for 4us interrupts when enabled. The bits sent have width that is multiples of the 4us time. When a frame is sent, this timer is enabled (parse.cpp) and Next bit is initialized. The timer interrupts when the count reaches 0x40. The reason for this selection is lost in time, it might have been easier to have selected 0xFF and just used a -ve number for initialization. This works well so...
    Timer 2 is concerned with measuring the time between transitions of the input. Each bit restarts the timer. When a transition happens, the count (2us increments) is measured. It is this count that determines what symbol has been received. The symbols are assembled into bytes and sent to the PC. When EOD is reached, a \n character is sent to the PC. This makes it more useful for a terminal to read because the frames are all separated on lines.
    Attached Files Attached Files

Similar Threads

  1. 1997 F-Body ECM
    By Tom H in forum GM EFI Systems
    Replies: 508
    Last Post: 01-19-2024, 11:19 PM
  2. Tools are good...
    By DavidBraley in forum GM EFI Systems
    Replies: 2
    Last Post: 12-05-2016, 05:46 AM
  3. 95 F-body Fuel Pump with 95 B-Body Engine/Tank
    By EPS3 in forum GM EFI Systems
    Replies: 7
    Last Post: 09-19-2016, 02:40 PM
  4. PRE efi tools
    By roughneck427 in forum Fuel Injection Writeups Articles and How to New and Old
    Replies: 1
    Last Post: 03-12-2015, 07:17 PM
  5. Good PCM Hacking Tools For OSX
    By Durahax in forum TunerPro Tuning Talk
    Replies: 0
    Last Post: 07-28-2013, 12:58 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •