PDA

View Full Version : 1997 F-Body Tools



Tom H
01-10-2022, 11:27 PM
New thread is intended to help support tools of use for debugging, uploading and downloading LT1 OBDII PCMs.

I have had a good look now at some software that I believe Tech II uses to download these PCMs. Somewhere back in the 1997 F-Body PCM thread there are details of this software but I have had a much deeper dive into it now and it's worth sharing. I believe that in our PCMs the TPU is the heart of the system. If you accept that I will offer that the SPI bus is the backbone. In working through the way that the Eside is programmed, I came to a better understanding of how the SPI is used in the system.

During normal operation, the SPI makes our multi-processor system function by transferring data both from Tside to Eside while simultaneously transferring from Eside to Tside. Details of this transfer are to be found in the "PCM" thread and I will not duplicate here other than a broad overview. The T to E transfer moves 25 parameters every cycle along with a checksum. The E to T moves 20 parameters each cycle plus one of eight frames and of course checksum. The eight frames each have 10 parameters and are sent sequentially every cycle. So it is the SPI that passes both control and information between the two sides.
A second function present during normal operation is the monitoring of the output driver circuits. Here, the Tside re-configures the SPI, de-asserts slave select to the Eside and transfers two bytes through the blue, red and black driver ICs. Those ICs are the 23 pin staggered SIPs that are found by each of these connectors.
The third function the SPI serves relates to upload/download. The Tside sends an SPI message that puts Eside into a special mode. In this mode the Eside interprets commands sent to it in a very similar way that DLC commands are interpreted. In fact these commands are the same except that the header used in J1850 is stripped off.

With that background, one goal I have is to upload the code from Eside. This will make use of a mode $35 command. While the Tside does not support mode $35, I wrote some software to provide it. This permits upload of Tside. To do the same with Eside the command received and validated by the Tside must then be forwarded through the SPI and acted on by the Eside.

I have improved the comments in the programming assembly file and will attach a snip of it to this post. In order to support upload, I will re-write some of this code to permit validation and forwarding of mode $35 commands to the Eside. I plan to merge the software I wrote earlier such that uploading will require a single file downloaded to the Tside. Once downloaded the module will permit uploading from both banks of Tside and from Eside.

Here is a snip of the code that does the forwarding in the download case:


*************************************************
* FORWARD REQUEST TO ESIDE
*************************************************

F_REQ_ESIDE: ; ...
pshy


ldy #$0549 ; INITIALIZE TIME OUT COUNT
clr COP_RFSH_COUNT ; INITIALIZE COP REFRESH COUNT
jsr RESET_COPS ; RESET COP TIMERS

FE_WAIT_ES: ; ...
dec COP_RFSH_COUNT ; DECREMENT COP REFRESH COUNT
bne FE_SKIP_CR ; SKIP COP RESET


jsr RESET_COPS ; RESET COP TIMERS


dey ; DECREMENT TIME OUT COUNT
beq FE_FAULT ; TIME OUT EXPIRED

FE_SKIP_CR: ; ...
ldaa PORTA ; PORT A BIT 1
anda #$02
bne FE_WAIT_ES ; LOOP UNTIL ESIDE SIGNAL


ldaa $00,x ; READ SPI TX DATA
staa SPDR ; INITIATE FRAME TRANSFER

FE_XFER_LP: ; ...
ldaa SPSR ; READ THE SPI STATUS
bpl FE_XFER_LP ; WAIT FOR TRANSFER TO COMPLETE


ldaa SPDR ; READ SPI RX DATA
cba ; COMPARE RECEIVED WITH BYTE COUNT
bne FE_FAULT ; SPI FRAME ERROR


incb ; INCREMENT TRANSFER COUNT
inx ; INCREMENT SPI TX BUFFER POINTER
puly ; RESTORE REGISTER


rts ; DONE
; ---------------------------------------------------------------------------

FE_FAULT: ; ...
ldx #$1008 ; SLAVE SELECT INACTIVE
bset $00,x $20 ; ABORT REQUEST TRANSFER


jmp START
; End of function F_REQ_ESIDE



-Tom

Tom H
01-15-2022, 12:10 AM
Home brew cable update

There were a number of bugs in the first version of the home brew cable. A time parameter was mistakenly entered in hex instead of decimal. The cable had only been hand tested and had never been checked for ensuring the tx didn't over write incoming frames. Other small fixes.

Thought I would take just a moment to update the software in case someone is trying this... There is no change to the interface, so I just copied the info from the other thread here.


-Tom

=============================================
Download for OBDII

The first bit of software to discuss is the bit that runs the home brew cable (HBC). The heart of the HBC is an Atmel ATMEGA328P processor. Subjectively, this part has a lot of advantages over the 68HC11 that I first tested with. The timer has very powerful modes, the free IDE programs the part in C and has all you need to write/debug code. Cost of the board was under $5 although the worldwide shortage of semiconductor parts has brought the price up a bit.

My code which Atmel refers to as a "sketch" is written in 5 modules. Here is the basics of operation:

The HBC software separates receive and transmit completely. This lets me monitor what I send along with what is returned by other nodes. The software (at least this version) has limitations in speed (no 4X yet) and in ability to perform outside of the early GM network (no arbitration --> two nodes only, break is detected but not acted on)

The receive symbols are decoded using the pin change interrupt. The interrupt determines the level of the previous bit and it's length. It then looks up the meaning of the symbol and pack it into bytes sent to the PC.

The transmit is timer driven. When a line is received, it waits until any current frame in progress is complete, then output the frame including SOF and EOF.

A normal sequence to read the security seed sends
4C 10 F0 27 01 71
and receives
4C F0 10 67 01 58 3D 27

Since the Arduino Nano board uses serial over USB, I set the interface at 115200 8N1
Characters are sent to the board using standard ASCII, each pair represents a hex digit

Probably forgot to detail something, so please just ask if there is confusion.

I am enclosing an archive of the Atmel archive. I am told that it is just a zip file that contains the project. All is in public domain/free for you to use. I expect to be improving on features and quality as time passes, will post later versions here.


That is the cable software, but I have written command line code for your PC that takes SRecords and downloads them to ram. All sorts of things can be downloaded: Flash programming, Flash dumping, debug routines... whatever you can think of.

-Tom

spfautsch
01-18-2022, 07:26 PM
Interesting stuff Tom. I recently bought a 2001 Y body and was thinking to myself how cool it would be to have an open source tool to talk to it with. But for now I'll be dusting off my Jet cable / software (based on tunercat).

Just to clarify a few bits - the arduino IDE is not sanctioned by Atmel. They also have a free but non-open IDE suite for their AVR products but it's not quite as friendly to beginners.

kur4o
01-18-2022, 10:10 PM
Interesting stuff Tom. I recently bought a 2001 Y body and was thinking to myself how cool it would be to have an open source tool to talk to it with. But for now I'll be dusting off my Jet cable / software (based on tunercat).

Just to clarify a few bits - the arduino IDE is not sanctioned by Atmel. They also have a free but non-open IDE suite for their AVR products but it's not quite as friendly to beginners.

A little off topic but 2001 ybody pcm is currently very well hacked, with freeware support. Still a homebrew cheap cable is missing, but you can easily fill the gap.
Maybe a new thread will be more appropriate to get you started.

On topic, the progress is awesome. Great work and complete write up. Can`t wait to see that project finished.

Tom H
01-20-2022, 01:12 AM
I received mail with a few questions regarding the home brew J1850 cable. For this project I have built a single prototype and the software is still somewhat in flux. Having said that, it works reliably and I have been looking at extending the upload capability to the Eside. I am answering questions on this thread because whatever someone finds unclear, others will surely question as well. OK so....

17430

1) The 820 Ohm Resistor; is that a commonly available discrete or should I combine a few resistors to get that value?
This resistor was selected based on several assumptions. The zener diode is 8.2V and for my test setup the input voltage is 12V (give or take). These two components are just there to provide an 8.2V source for the line driver. There should be round about 4v across the resistor. This gives us about 5ma of bias current for the zener. Since IZT of the zener is 30ma you could go with a much smaller resistance but not too much larger. Probably 1K would be fine. Just depends on what you have floating around your tool box. I suggest you use no larger than 1K or smaller than 500 ohms. With these values resistor of 1/10 watt will be fine. This part is not sensitive... use what you got.

2) Best to get the 47K resistor in the bulk pack kit?
The 47K resistor forms a voltage divisor with the 10K. The ratio of these two parts is important but values could be changes. These two resistors along with the transistor and another 10K form an inverter and a level shifter/buffer. Test your circuit by sending frames. You should see the output of this inverter toggle and the circuit will send your sent frame such that you can monitor it for correctness on your terminal. These resistor are all available on digi-key/Amazon/Ebay and hundreds of places.

3) The Arduino_Nano... there's a lot of choices on SparkFun.com. Any recommendations in particular? I see this one: Arduino Nano Every - DEV-15590 - SparkFun Electronics
I bought several Arduino boards. I like the ones that come with a short cable and have all the header pins installed. I can't recommend a vendor except to say that some things are in short supply just now. I got mine through Amazon and found a vendor that had a good delivery and good recommendations from other buyers.

4) Any particular size breadboard you recommend?
I guess it depends on your skill soldering and so on. If you want small, surface mount resistors are good. you can use wirewrap wire to hook things up. With leaded components you will be a bit larger due to the resistor wires and bending them to fit the holes. I would thing 2" by 4" would be more than enough. So far I have not built a breadboard. I built mine in a prototyping strip... this is just another project I need to complete.


Hope this helps.

-Tom

sherlock9c1
01-23-2022, 04:24 AM
I have an arduino uno R3 on hand; any issues with using that instead of an arduino nano? The processors are the same, I believe the code is the same, and we only need two output pins so we should be good? I'm just brand new to arduinos.

kur4o
01-23-2022, 12:51 PM
Great write up on the hardware side.

Can you give some insight how the software side of actual communication will work. Does it use comm port, is it transparent or some translation between cable and pcm is done, checksum and so on. The usual stuff we need to get a good start with it.

sherlock9c1
01-24-2022, 07:18 AM
Zener diode question - based on mouser (https://www.mouser.com/datasheet/2/345/1n5333b_1n5388b-2301475.pdf), it looks like the P/N you used was 1N5344B?

Tom H
01-24-2022, 12:54 PM
Zener diode question - based on mouser (https://www.mouser.com/datasheet/2/345/1n5333b_1n5388b-2301475.pdf), it looks like the P/N you used was 1N5344B?

The schematic should have shown the part number, but didn't... I used a 1N4738 in the prototype. You can pick up a datasheet here:
https://www.onsemi.com/products/discrete-power-modules/zener-diodes/1n47

sherlock9c1
01-24-2022, 04:38 PM
Tom, I ordered a few of those 1N5344B's before you responded; it looks like the Izt is 5x what the 1N4738's is, (150ma vs. 30ma). The Zzt is 1.5 vs. 4.5 ohms. It's been a long time since I've done circuit design; is that much more bias current a deal breaker? 150ma seems like a lot for this application.

Tom H
01-24-2022, 05:53 PM
Tom, I ordered a few of those 1N5344B's before you responded; it looks like the Izt is 5x what the 1N4738's is, (150ma vs. 30ma). The Zzt is 1.5 vs. 4.5 ohms. It's been a long time since I've done circuit design; is that much more bias current a deal breaker? 150ma seems like a lot for this application.

Yes but cheap and dirty. You don't need much current for this... easy to calc from J1850 spec. Remembering if I can, I bias the zener with ~5ma or so suggests a 30ma is still overkill

I am sure this will work but if any troubles... Just reduce the value of the resistor (increase bias current) bias some. 400ohm would double the bias to about 10ma. From the curve you should be well in range.

Tom H
01-27-2022, 03:38 PM
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.

Tom H
01-28-2022, 04:07 PM
I am at the stage where I have most of the functions needed for altering code working. I have questions for you all regarding format(s) that are useful in other tools.

My work has so far been mostly in isolation from commercial tools. I find Motorola S records to be a very convenient format. This format permits me to load a module without remembering where in memory it is to be loaded. There are dozens of standard formats out there but it also makes some sense to stay with the format that matches the processor used. IDA is also set up to read S records, so at least there is a flow there.

If I look through gearhead archives of binaries, most are just straight binary... start at $0000 work through $FFFF. This just isn't good enough for the orphan '96/7 PCMs. These PCMs are based around 68HC11 unlike the later OBDII PCMs. Also an issue is the bank setup on the Tside. To use a binary format, three areas need to be loaded: TSide bank 0 range $2000-$FFFF, Tside bank 1 $8000-$FFFF and Eside $2000- $FFFF. Minor ranges for both sides in the $0E00-$0FFF might also need to be considered. If a 128K binary for the TSide was generated, the programmer still needs to remember that the first $2000 are not programmed and that the first $8000 on bank 1 are also skipped.

Since I see the Srecord as the format of choice, this is what I plan to use for storing and loading of binary data in/out of the PCM. Often times where another tool is involved in the modification for tuning there will be a specified format they want to use.

Here are my questions. If binary format is wanted for your tool (tool name?):
- Does the TSide bank 0 binary start from $0 or $2000?
- Is there a separate file for TSide bank 1?
- If yes, how is the bank 1 gap between $0 and $8000 handled?
- If no, does bank 1 address $8000 follow bank 0 $FFFF or is there padding there?
- Does the ESide binary start from $0 or $2000?

If someone could offer me some guidance here (The exact expected format), I will make up a console app to do the conversion back and forth. If I can't pin down the output format, command line switches could be set up BUT that is always confusing to the end user.

Other stuff --
Tside upload is complete now. I have tested uploading both banks and the EEPROM areas into SRecords.
Download console app is now completely solid after yesterdays fix to HBC.
Still thinking about the ESide, some work needed.
4X for HBC is a little way off.
For interest below are some of the calculations for upload time.

=================
Distribution of short and long bits, assumed to be even

Short bit time 64 us
Long bit time 128 us
Ave bit time 192 us

Ave byte time 1536 us

Frame Overhead 500 us


Request UL $35 11 Characters + overhead
Response UL $75 12 Characters + overhead
Request UL $36 29 Characters + overhead
Response UL $76 12 Characters + overhead

Sequences 3584 Sequences loading 16bytes at a time to match SRecord format

Characters/sequence 52 Assumes no PC response to Mode $36 (no mode $76)


Sequence time 80372 us
80.372 ms

Total time 288053.248 ms
288.053248 s
4.800887467 m

Characters/sequence 64 Assumes PC response to Mode $36 (mode $76)
5.901892267 m

I tested and found the time matches (all 1X for now). The total time to upload will be about 11min for the whole PCM. When/if I can get 4X working, 3min PCM upload should be possible.

-Tom

spfautsch
01-29-2022, 07:04 PM
I have an arduino uno R3 on hand; any issues with using that instead of an arduino nano? The processors are the same,

I've yet to delve into this for lack of time, but I believe any 328P based arduino / clone will work. It looks like I'll need some zeners to test but I intend to try with a bare breadboard clone and a FTDI cable.

Edit: one advantage to using a clone that lacks an integral usb>rs232 adapter is that the RTS line can be disconnected, eliminating the microcontroller reset caused when the serial port is opened by the client application.

Tom H
01-29-2022, 07:21 PM
I've yet to delve into this for lack of time, but I believe any 328P based arduino / clone will work. It looks like I'll need some zeners to test but I intend to try with a bare breadboard clone and a FTDI cable.

Edit: one advantage to using a clone that lacks an integral usb>rs232 adapter is that the RTS line can be disconnected, eliminating the microcontroller reset caused when the serial port is opened by the client application.

No zener? I just used a 9V battery in place of the zener supply for a while. The circuit is quite forgiving...

-Tom

spfautsch
01-29-2022, 08:33 PM
I hadn't even looked at the schematic other than to identify you were using a transistor pair to drive the output, etc. It's hard to read, is that rail voltage 6.2 or 8.2 volts? I should have a 7806 and maybe even a 7808 3 pin regulator in my parts bin.

Regardless, if this bus is electrically similar to the older 8192 baud ALDL, I have to wonder (and will experiment with) a simple resistor and diode arrangement as I used on my data logger.

Tom H
01-29-2022, 08:36 PM
I am posting a few things that are duplicated from the PCM thread because they belong together.

In order to read out the FLASH content of the '97 Camaro PCM, you need to be able to access both banks of the TSide and also the Eside. I have put together a couple of command line apps that permit both TSide banks to be uploaded. I have found that GM did not implement mode $35. This mode would regularly be used as suggested by SAE J2190. The first task I undertook was to find a way to support mode $35. I did this by downloading a very small program into low memory. Using the Home Brew Cable (HBC) I first download the image to ram and execute it. This is done as follows:

Download Mode35_T.s19 /P9194 /C3 /V00

In this command line: Download.exe is the command, Mode35_T.s19 is the module I wish to install, /Pxxxx is the PCMs password, /C3 indicates HBC is installed on COM3 and /V00 just suppresses many of the comments placed in the code (if you want to see, try /VFF )

Once this command is accepted by the PCM, it is ready to upload from any address in the PCM.

I have a command line app that uses the PCM conditioned with the Mode35_T.s19 module to upload. The application is run using command line switches and generates an SRecord output file. This format is an often used way to store binary information along with addressing. It can easily be converted to a binary ( .bin file). This is done as follows:

Upload Output.S29 /C3 /B0 /S0E00 /L0200 /V00

In this command line: Upload .exe is the command, /C3 selects the serial port to use, /Bx selects which bank to upload (0 or 1 only), /Sxxxx sets the starting address of the upload in hex, /Lxxxx sets the length in hex, and /V00 just suppresses many of the comments placed in the code (if you want to see, try /VFF )

I am enclosing a sample output file named TSideEEPROM.s29 along with the various executables mentioned above.

-Tom

Tom H
01-29-2022, 11:07 PM
I hadn't even looked at the schematic other than to identify you were using a transistor pair to drive the output, etc. It's hard to read, is that rail voltage 6.2 or 8.2 volts? I should have a 7806 and maybe even a 7808 3 pin regulator in my parts bin.

Regardless, if this bus is electrically similar to the older 8192 baud ALDL, I have to wonder (and will experiment with) a simple resistor and diode arrangement as I used on my data logger.

The objective is to send 6.25 - 8V when the output is active and high impedance when it is passive. The rest of the symbol info is in the timing of transitions. Any 8V regulator will allow for the drop in your output stage and should work a treat and you won't need a zener diode to regulate. You could avoid transistors and so on by using a 1488 rs2323 driver and a resistor. While you might not be in spec with the J1850 (rise time/fall time issues) it will work fine. When I did the circuit, I just went to my parts drawer and used what I have. Looking at it with the scope I see no problems.


-Tom

spfautsch
01-29-2022, 11:24 PM
The objective is to send 6.25 - 8V when the output is active and high impedance...

Thanks for the clarification.

Out of curiosity, did you test with TTL levels? I know it wouldn't be within spec but the 328P will happily sink 20ma per pin at 5V with no issues driving the outputs active high. When not driving the pin it could be toggled to an input / high impedance state.

Tom H
01-30-2022, 12:08 AM
I did try 5V, didn't work for me. Interested if you test.

Didn't understand the 2nd bit... No need to sink any current. Passive state is high Z. Active state sources current. Issue I had is that 5V doesn't seem to be enough to toggle the input stage. If you can get it to work, all the resistors & transistors involved with the TX can be removed with just a small bit of software change. I power the NANO through USB. There are some voltage losses through the chip and also a diode to permit other power schemes. Powering with the NANO regulator might be enough to make it work. So there might be a way, but I didn't look too hard. I also needed to buy the zener. Can't just buy one on the 'zon so i have a bag full.

-T

spfautsch
01-30-2022, 12:53 AM
No need to sink any current.

Just so we're speaking to the same semantics, when I say sinking current that to me implies an output pin on the AVR pulled positive sinking current supplied by an external ground. Sourcing current would be the same output switched to ground / negative. This was the terminology I was schooled with, with the underlying theory that current flows towards a positive charge. Not that important, just semantics.

I'm still playing catch-up so haven't looked at any of the source code. But if you're using any of the Arduino PWM libraries, changing a pin's state during operation may not be feasible.

Tom H
01-30-2022, 03:51 PM
Just so we're speaking to the same semantics, when I say sinking current that to me implies an output pin on the AVR pulled positive sinking current supplied by an external ground. Sourcing current would be the same output switched to ground / negative. This was the terminology I was schooled with, with the underlying theory that current flows towards a positive charge. Not that important, just semantics.


While you are absolutely correct in what you write, however conventional current flow is the standard in use almost everywhere today. When looking at data sheets for ICs and so on, the reference is to ground. Specifications for sourcing of current are above that potential. This is somewhat of an abstraction from what we want to get to here. I will try not to use source/sink to describe current flow. I believe you should have no trouble adapting the circuit given to the parts you have on hand.

To get rid of the need for an 8V supply, I thought for a moment about using an output of the micro to toggle and building a switch capacitor boost circuit. This took too many parts, i discarded the notion.

I will be interested to see what you come up with. There is no use of PWM libraries in my design. You can do practically whatever you need WRT control of the outputs.

-Tom

Tom H
01-31-2022, 04:27 PM
I have questions for you all regarding format(s) that are useful in other tools.

...

Here are my questions. If binary format is wanted for your tool (tool name?):
- Does the TSide bank 0 binary start from $0 or $2000?
- Is there a separate file for TSide bank 1?
- If yes, how is the bank 1 gap between $0 and $8000 handled?
- If no, does bank 1 address $8000 follow bank 0 $FFFF or is there padding there?
- Does the ESide binary start from $0 or $2000?



There being no opinions on this, here is the conversion tool that meets my needs. I just zipped the whole visual studio project file but it is too big or ?? so here is the exe.

Usage: Srec2Bin <Input_File_Name> <Output_File_Name> /L<Hex_Fill_Length> /F<Hex_Fill_Character>

<Input_File_Name> File extension .S29 (S2 addressing)
<Output_File_Name> File extension .bin (unformatted binary)
/L???? Fill length at file start. Four hex digits
/F?? Fill character used. Two hex digits

For those working with other cables or ?, source is available, just ask.

-Tom

JimCT_9C1
02-14-2022, 12:16 AM
Hello Tom - Just catching up after some time away and though late still wanted to chime in on bin format.

One fairly common format I have seen is 144kb. This format has been simply and clearly described by kur4o in the xdf thread:


96-97 files are 0-56 kb tside bank0. 56-88kb bank1 tside. 88-144kb eside.

So to answer your questions for this bin format:

Q- If binary format is wanted for your tool (tool name?):
A- Tunerpro, perhaps others

Q- Does the TSide bank 0 binary start from $0 or $2000?
A- Starts from $2000 (makes up 1st 56k)

Q- Is there a separate file for TSide bank 1?
A- No, immediately follows Bank 0 in same file

Q- If yes, how is the bank 1 gap between $0 and $8000 handled?
A- No gap in bin; presumably this is handled by binconverter utility or pcmprogramming software

Q- If no, does bank 1 address $8000 follow bank 0 $FFFF or is there padding there?
A- Bank 1 immediately follows Bank 0 in same file with no padding (makes up next 32k)

Q- Does the ESide binary start from $0 or $2000?
A- Starts from $2000 and immediately follows TSide Bank 1 (makes up last 56k)

Hope this helps, and thanks for all you're doing with these tools!

Jim

Tom H
02-14-2022, 03:55 PM
Hi Jim,

Going by your answers, I think you have all the needed tools already.

The first Tside bank is dumped separately, let's say we place it in <file1>, length is $E000 starting at $2000. Second bank is placed in <file2> and has a length of $8000 starting at $8000. In a batch file or cmd window, use the following:

"TYPE FILE1 FILE2 > FILE3"

Now file 3 is a concatenation of both files, no gaps. Then use Srec2Bin as follows:

"SREC2BIN FILE3 144KB.BIN

Take the output file and you should be good to go. If someone has the tool that uses this format, give it a go and let me know how it works.

I am now working through the spi and will post some info soon. Turns out to be interesting/tricky how it was done. Each transfer switches mastership of the spi after the first transfer. Still a bit of head scratching to go but once done, dumping the Eside should be easy. BTW looking through earlier posts in the ECM thread, dzidaV8 in post #77 indicates he has all this working! You might want to speak with him to see if what he has done is better for your needs...


-Tom

Tom H
06-20-2022, 11:30 PM
Hi,

I have come to the end of another of my sub-projects. I spent the last few months learning some of the details of windows programming. I have built software that works in conjunction with the Home Brew Cable (HBC) that was written earlier. This tool gives the user the ability to exercise the J1850 port. All commands can be supported with the exception of the 4X mode... still working on that.

This system breaks down into three main sections.
The first section is the cable hardware. This was detailed earlier, but two small changes have been made to enhance the operation. There is a new JPEG of the interface. The Arduino Nano is used for it's low cost. This whole interface fits on a small perforated board. The costs of parts is way up, but it is still under $20 to build.

The second section is the cable software. This software runs on the Nano and essentially translates between the J1850 and standard NRZ serial over USB. Small changes to this code have been made to prevent overrun of the TX. To prevent this overrun, XON/XOFF protocol has been added to the PC --> PCM link. This change permits the cable to throttle data coming to it from the PC.

Last section is the PC software. I wrote an app that the user can issue the J1850 commands. Once the app is booted, the user selects the Com port that the cable is on and connects. There are 20 configurable keys that allow the user to issue commands. There is also a command line entry for the commands that are entered once. This is an interface that I find flexible. Another feature is the repeat "tester present" timer. This ensures that once the security password is issued, it does not time out.

I wrote this for the 1997 Z28 Camaro PCM that I am working on but is should work fine on GM cars 1996 through about 2003.


17970

The interface has a dozen parts or so and should be easy to build.

17971

The software that resides on the Nano is provided in the archived sketch. By running the Arduino software tool, the sketch can be uploaded in less than a minute.

17972

Here is a shot of the user interface. The buttons down the left screen are programmable to any J1850 command you need. Details of this software will be in another post following soon.

-Tom

Tom H
06-21-2022, 12:13 AM
The app that works with HBC is written in C++. People with other cables that would like to port the software, feel free to ask and I will get you my source code. Please if you do use the source, understand that I am self taught and some conventions that you might be used to I might not follow. I tried to write the code in classes that make it easy for me to port them to other apps.

The C++ IDE I use is Microsoft visual studio 2015. It is free, fairly complete and easy to use. One small disadvantage is that a microsoft runtime DLL must be installed. You can get the module needed at this URL:

https://www.microsoft.com/en-us/download/details.aspx?id=48145

Just follow MS's install instructions and you are done.

OK, so now to the app...

17974
The app has a simple menu structure at the top. There is help available if you forget some detail, but fairly terse. The repeat menu permits you to turn on/off the tester present messages. Once connected, if you enable this timer, the app will send a "tester present" message periodically to prevent the tester from exiting the security disabled state.

The taskbar just under the menus contains a few controls. In the combo box, select the port your Nano is connected to. Not sure which port? --> run device manager and look at the available serial ports, pick out the one associated with your Nano. Once the app port select combo is set, hit the connect button. This lets system start and you should see an OK come up in the transcript.

At this point the app is ready to send commands. The user can enter them into the "line entry" edit control as follows. Permitted characters are hex (that is 0-9, a-f or A-F). User may enter spaces to make it more readable. Once the command is entered, hit the enter key and the command will be sent. The transcript will show both the command and the response. The transcript is always looking at the bus. This gets away from the ELM327 type command response. This permits commands that have multiple responses to be correctly monitored. Yes GM does use this sort of one request multiple response format.

The command buttons down the left side are configurable. To do this click the button with shift key down. You can then change the key name and the content to be sent.

Here is the app with the name changed with an appended .TXT.
17973

I hope this is of use to someone.

kur4o
06-21-2022, 12:22 AM
That looks amazing. Great work so far.

Can I ask what is the communication between cable and pc. Does it use some header or is pure passive passthrough mode that the cable just relays the command to bus, without any processing.

On the x4 mode. If the hardware is capable you can implement the switching to a hardware level, listening for some mode a1 and mode a0 being issued on bus or from pc for x4 mode trigger. Switch back to x1 mode should also be on hardware level, when sensing some weird signalling.

Tom H
06-21-2022, 02:12 PM
Can I ask what is the communication between cable and pc. Does it use some header or is pure passive passthrough mode that the cable just relays the command to bus, without any processing.


Hi kur4o,

The format of data over the NRZ link is:

Standard serial at 115200 baud 8N1. The Nano board detects when communication is valid and resets the microcontroller. There is a delay here, so when booted the Nano returns "OK\r\n". Till the OK comes, don't send a pile of stuff. In cases where stuff is sent before OK, it will be lost or some weird thing will happen. This case has not been tested although I believe software will recover it.

Talking about receive or transmit is confusing. Receive for the HBC is transmit for the PC and again transmit for the J1850. I will use "Outbound" for the data path PC -> HBC -> PCM.

The outbound is transmitted to the HBC from the PC and the following characters are recognized:

Character Hex value
'0'-'9' 0x30 through 0x39
'A'-'F' 0x41 through 0x46
'a'-'f' 0x61 through 0x66
' ' (space) 0x20
'I' 0x49
'i' 0x69
NL (linefeed) 0x0A

Other characters are discarded.

Hex values are sent in pairs. They can be sent with a space ' ' character between pairs. Given that:
"4C10F050\n" is exactly the same as "4C 10 F0 50 \n" but "4 C 1 0 F 0 5 0 \n" won't work... no pairs.


The inbound is received by the PC from the HBC and the following characters are used:
Character Hex value
'0'-'9' 0x30 through 0x39
'A'-'F' 0x41 through 0x46
'O' 0x4F
'K' 0x4B
' ' (space) 0x20
CR (return) 0x0D
NL (linefeed) 0x0A
DC1 (XON) 0x11
DC3 (XOFF) 0x13

You should not see other characters
!!Edit!! I added a detection for BREAK. This adds the characters 'B' and 'R' to the list!!

Inbound frame data is sent in pairs of hex characters with space between them. Lines are terminated with NL. The HBC sends XOFF to suspend the outbound side and XON to resume it.

-----------------------------------------------------------------------
The explanation is quite wordie so to make it easy, here is an example

Outbound: 4C 10 F0 28 00 \n sends 34 43 20 31 30 20 46 30 20 32 38 20 30 30 20 0A
Inbound: 4C F0 10 68 00 5E receives 34 43 20 46 30 20 31 30 20 36 38 20 30 30 20 35 45 20 0A

I have removed the XON/OFF characters from above. If you don't need them, just filter them out.
Note that the HBC generates the CRC on the outbound. On the Inbound I check CRC in the PC app.

Above is confusing & hard to read through. If you have question, don't hesitate to ask.

- Tom

Tom H
06-21-2022, 02:30 PM
On the x4 mode. If the hardware is capable you can implement the switching to a hardware level, listening for some mode a1 and mode a0 being issued on bus or from pc for x4 mode trigger. Switch back to x1 mode should also be on hardware level, when sensing some weird signalling.

The 4x has been back burner for a while. Switching can be accomplished as you suggest, but with some care. The data transfer (think it's mode$36) automatically enters 4X. When it sees a 1x character it falls back. Main thing not tested is the capability of the HBC hardware. Initial tests suggest yes but still a bunch to do. Should be as simple as switching the table of constants, but things are usually not that simple.

With the interface I have, the calcs look like the speeds work out OK...

Some back of the napkin calculations:

J1850 shortest pulse 49us

Ignoring frame overhead, shortest word is 392us

NRZ at 115200 8N1 results in a word time of 87us
3 words are generated from each receive: 261us

Now let's ask if the PC can keep up or if I need to improve on the efficiency of my code
or worse redo the interface to get rid of space between hex pairs <sigh>

-Tom

In-Tech
06-21-2022, 03:58 PM
Hiya Tom H and kur40,
You actually want to measure clock and use that as a "standard" in your comm protocol, this way the ticks can be accurate in digital micro land ;). I'll try to dig up an example from yeeeeeeearssss ago, am just throwing out ideas for y'all for now :) latency and each particular circuits latency will always exist. Here we have a known proven structure so it should get narrowed down fairly quick. You can always use flip/flop(7407 style) to help "clean" the signal in your interface comm device. The old 160/8192 non standard crapola seemed like a biatch at the beginning too. Throw in some clock jitter with an unknown protocol and you can imagine the kinda crap i had to sift and figure out back in the day. You guys are well on your way :) It still and always will boil down to 8 bit ;)

Tom H
06-21-2022, 04:22 PM
Hiya Tom H and kur40,
You actually want to measure clock and use that as a "standard" in your comm protocol, this way the ticks can be accurate in digital micro land ;). I'll try to dig up an example from yeeeeeeearssss ago, am just throwing out ideas for y'all for now :) latency and each particular circuits latency will always exist. Here we have a known proven structure so it should get narrowed down fairly quick. You can always use flip/flop(7407 style) to help "clean" the signal in your interface comm device. The old 160/8192 non standard crapola seemed like a biatch at the beginning too. Throw in some clock jitter with an unknown protocol and you can imagine the kinda crap i had to sift and figure out back in the day. You guys are well on your way :) It still and always will boil down to 8 bit ;)

Hi Carl,
Not sure I understand all you wrote. All this stuff is async. PCM has it's own ceramic resonator for the 4MHZ the DLC wants. HBC micro has it's own 16MHZ clock and of course there is the PCM's 12.whatever crystal. In places where it was easy, I put buffers to handle instant overspeed. Other places I depend on the rate being in excess of the bandwidth and buffer excess. Clock jitter is every where along with line jitter and all the errors my cheap and dirty interface introduces.

So far, my testing of the 10K4 seems OK. I have used the same code to download into ram & read back w no faults.

re calcs for clock, these are based on min/max specs. Going 4x will probably require me to change the interface, which is a PIA.

Cheers,
-Tom

In-Tech
06-21-2022, 06:46 PM
Hiya Tom,
GM is wonderful on async, especially the old stuff. Always logical. Intentional clock jitter was what I was eluding to, as you know it is kinda like encryption without a routine. Back in the early 2000's 64 bit was the edge, The TMS370(6805 variant) had some cool perif variables at the time. I introduced 5024 to a homeland bud. Anyway, off track.
Bottom line is it all boils down to one register once you are inside.

I love your work, Tom. I enjoy, so if I can help, I will :)
I'm still an old gearhead at heart, finishing a 430" LS and dyno soon so we can make the offroad vegas to reno race in August.

Tom H
10-07-2022, 05:10 PM
Hi,

I am posting some software today that was written to give upload access to the FLASH in early OBDII LT1 PCMs. The software is setup to drive the Home Brew Cable (HBC). Details of this cable and how to build it are given earlier in this thread. Uploading code was something that GM had intention of supporting only in the factory. I suggest this because the TSide has no mode $35. The ESide has mode $35 but is accessible only through the SPI bus. There is no standard way to access the SPI through class II commands.... So a ram based module was needed to support upload access. The code is not fast, uses only X1 mode. Upload of the complete PCM takes about ten minutes for the complete TSide flash (both banks) and the Eside flash. I think this is fast enough given that it will be done only a few times.

I wrote the module based roughly on the SAE standards for mode $35 (See J2190 for details). One difference with the regular GM scheme that I introduced into the code is the use of the upper address bits to indicate bank. Banking on the TSide was used by GM to increase code size from 57,344 ($E000) to 90,112 ($E000 + $8000).

To use this App...

The windows app posted here first initializes the PCM. Car needs to be "key on" not running and of course not moving. Be sure the battery is charged and so on. With the HBC connected to the computer's USB and to the car's OBDII connector, start the software. Here is a screen shot:

18434

Using windows device manager, determine which COM port you are using and set it. Click Initialize Upload and the program will install the mode $35 module in TSide ram. A little out of order on my screen, the next step is to enter the PCM's password/security key. There are a good number of posts on this list to help find your key if you don't already have it. Click the initialization key. Once the software has initialized (progress is reported in the
output window on right screen) you will be ready to start your upload. Once loaded, the PCM is placed in a mode where it only supports mode $35. If for any reason you need to start the car, I recommend disconnecting the battery BEFORE trying to restart the car. It might work with just "key off" "key on" but the ram will be scrambled and could cause issues. I did not ensure to overwrite the tags that cause cold restart so best is battery disconnect/reconnect. See second screen shot:

18435

Select one of the three target spaces (TSide bank 0, TSide bank 1, ESide). This select which of the code spaces you will upload. Select the address to start upload from and the length of the upload. Please note that the ESide uses the GM coded mode $35. This code restricts access to ram below $2000 and flash above $2000. Other techniques must be used to upload things like the EEPROM from the ESide. Once the necessary selections are made, click Begin Upload. See screen shot 3

18436

At this point the selected storage has been uploaded to the PC in an array. All that remains is to output into a file in a format that is of use. The provided selections allow storage in three formats. SRecords is the default. This is of use with IDA or other tools. The most common format is binary. Binary file can be saved using a fill option. This will offset the download by the amount of the starting address. With this most common format, (example)the $2000th byte in the file represents the upload from address $2000. The offset option will be little ?never? used. It enters binary from the start address into the file starting at the first byte.

If anyone needs the source to port to a different cable, please just ask.

If you use this, please reply to this thread and let me know how it works for you.


-Tom

Tom H
06-22-2023, 04:10 PM
Once again I have been distracted from a current goal of analyzing the knock sensor system. I will
get back to that, but first here are the details of the VSS system. A good deal of this may be common
knowledge but I thought to write up what I have done. This exposes more of the internal workings of TPU
(Circa 1997) which is key to understanding this PCM.
-----------

Starting at the beginning, here are a few details I used to work out the VSS function. These are specific
to my calibration/configuration.

17 PULSES/DRIVESHAFT REVOLUTION (NUMBER OF TEETH ON THE VSS RELUCTOR)
3.42 REAR GEAR RATO (GU6)
58.14 PULSES/TIRE ROTATIONS
504 TIRE ROTATIONS/KM (P245/50ZR16)
811 TIRE ROTATIONS/MILE (P245/50ZR16)
28372.32 PULSES/KM
45660.82 PULSES/MILE

Note that wheel rotations per mile/KM differ depending on tire manufacturer. The numbers I have here are
based on the constants in my calibration and are confirmed to be in the ballpark from available tire data.

I needed a way to generate VSS pulses on the bench to allow me to look into VSS processing. In my case it
was an easy call to use an Arduino Nano to generate VSS. They are inexpensive at about $5 and I have a
bunch of them around. I wrote some crude code to drive different frequencies and or exact
number of pulses. This helped greatly with the investigation. It permitted me to generate pulses of a
fixed count, pulses of a fixed rate/frequency or stop the pulses.

There are a couple of schematics attached to this post. The PCM VSS input is set up such that it requires
a negative going pulse (below ground) to trigger it. It doesn't need much... half a volt or so will be fine.
For more detail look at the VSS_Interface.jpg schematic. Since the switch point for the circuit is just
below ground some conversion of 5V logic signals is necessary. Digital signals from 5V logic can be set to
trigger the VSS with just a couple of common components. I used a small capacitor (0.1 - 0.5uf) to block
dc and a small signal diode (perhaps 1N914 or any small signal diode) to create the level shift. This
interface has been well tested and is reliable. In cases where someone wants to tune transmission
calibrations, more sophisticated software will be needed to drive VSS, RPM, MAP, TPS and perhaps a bunch
of other things. Perhaps some time I will investigate the automatic transmission, but later.

In case someone want's to duplicate this setup, I have included a schematic for the basic interface. Code
is available on request (I will comment it a bit and give it a clean before passing it on). The code is
however quite crude and you might be better off generating your own. The second schematic is of the VSS
interface to the TPU. This is the standard LT1 interface that was used in the $EE style PCMs.

Initial setup generated the following fixed rates. The second column is the PCM's reported speed. Second
setup changed the interface to let the user enter a numeric speed to be output.

VSS input PCM
Frequency Speed
Hz KPH
1953 242
977 121
651 81
488 61
391 49
326 41
279 35
244 31
217 27
195 25
178 23
163 21
150 19
140 18
130 17

To query the PCM I used a bunch of things that have been described elsewhere: Homebrew cable and
CarCom software. The sequence used to read speed in KPH from the PCM is: 4C 10 F0 22 00 0D 01 <CRC>

OK, so far the physical connection between the road and the PCM is described. From here things get
a bit more complicated, I will do my best to describe what is going on in the TPU. Before doing this
everything I write here is from observations of the operation. I have not yet found how to dump the
internal programming of the TPU so what follows is only 99.9% solid.

VSS is connected to the TPU on pin 6.

The PCM transfers data bidirectionally between ESide and TSide on the SPI bus. This bus runs across
the ribbon cable that connects the boards. The PCI bus transfers are formatted such that 32 bytes
are sent (I generally condider this to be a frame). The transfers from ESide to TSide also have a
subframe that is of no consequence to this topic, just mention it to avoid confusion. In each frame
bytes 5 through 8 contain vehicle speed data.

Bytes 5:6 represent elapse time of the VSS pulses
Bytes 7:8 represent the number of VSS pulses since the last read

During this transfer ESide reads an elapse time and pulse count, then sends it across to TSide. The
sequence used ensures that the count and elapse time are always paired. To ensure this paring the
following was done:

- Each time the VSS pulse count is read, the elapse time count is latched inside the TPU. Software
then reads the time count within a few cycles.
(Guess is 48 EClock cycles. This makes sure the elapse time is for the count given)
- The elapse time count is updated each time a VSS pulse is seen.
- The register for elapse time is updated on pulses from the second VSS pulse on.

This ensures that if the car stops part way through, the time is not skewed with the count. Basically
the counter and timer designs ensure synchronization between the two. The pulse count representing
distance and the elapse time is just that...time. That gives us what we need to calculate speed.

The ESide code for this sequence looks like this:

8A04 ldaa word_14E0 ; TIO SHARED RAM
8A07 ldd word_14E0
8A0A std <byte_009A ; BYTE 5/6 TX SPI

8A0C ldaa word_14E2 ; TIO SHARED RAM
8A0F ldd word_14E2
8A12 std <byte_009C ; BYTE 7/8 TX SPI




-------------

7CCC ldd VEHICLE_SPEED_M ; SPEED IN MPH
7CCF ldx #$9FA7 ; MPH X 2^16 / 40871
7CD2 fdiv ; OR 1.6035
7CD3 xgdx
7CD4 addd #$0080 ; ROUND UP INTO ACCA
7CD7 sbca #$00
7CD9 staa VEHICLE_SPEED_K ; SPEED IN KPH: 0 TO 255 KPH


... ( 242kph * 40871 ) / 2^16 = 151



19157

19158


If you would like the software for the "speed generator" , please just request and I will post it.

-Tom

kur4o
06-22-2023, 07:07 PM
Vss always have been a dark matter, due to only some constants visible to cpu code. That brings it much in detailed explanation how it works.

I think some constants are passed to tpu in initial reset of pcm. So tpu must be in some way configurable, how it reads speed.

Anyway, Tom great write up. Thanks

Tom H
06-30-2023, 02:58 PM
Hi,

From what I see in my code, the TPU parameters do not seem to be adjusted between auto/manual or any other issues. I believe the differences are all in the TSide calibration parameters. I don't have a complete understanding of TPU however and I do see parameters marked (not sure who/why??) as relating to speed transfered from the [ESide config to the TPU] configuration section. Looking at the code however, I can see all the calculations to find Trans Output Shaft (TOS) RPM, filter it, find vehicle speed from gear ratio/tire size and convert the speed to KPH as required by OBDII.

As I understand it, one basic difference between manual and auto trans is that the number of pulses generated per rev of the driveshaft. I believe that the automatic generates 40 pulses where the manual generates 17 (manual is confirmed). I don't have automatic code and am not sure where on this site I could find it. I had a quick look and didn't see much support for the OBDII generation of PCMs. Perhaps someone could send me a pointer...

In a disassembly I was given, the calibration has a named parameter "TOS_Driveshaft_PPR" which I decode to mean "TRANSMISSION OUTPUT SHAFT PULSES PER REVOLUTION". This name seems almost correct but: The config constant becomes the denominator in a FDIV instruction with a value of $4888. Pushing through all the math I believe this constant is as follows:

("TRANS OUTPUT SHAFT PULSES PER REVOLUTION" / "NUMBER OF SECONDS IN A MINUTE) X 2^16

IN NUMBERS

(17 / 60) * 65536 = 18,568 OR $4888 (This is the constant in my code)


Missing from my earlier post is that the VSS_CLOCK used to quantify the input VSS frequency is EClock/48. The sequence on the ESide is to latch the count on the edge of VSS. The count continues, incrementing each 48 EClocks. Notice that EClock/48 is 2^16 or 65,536. Given this, driveshaft RPM can easily be calculated for a given VSS input frequency.

Why was it done this way? My guess is that they re-used automatic transmission code from earlier PCM/TCM and didn't want to mess with what was already working and tested. The way the parameters for TOS are packaged in a structure is quite different to the manner most of the code is written. This makes me think it might be earlier code...

The result of the TSide routine is 8 X Trans Output Shaft RPM. It can be found with PID 1942 using the standard mode $22 request. In my case: 4C 10 F0 22 19 42 01 <CRC>

I will include a couple of assembly code files, commented with what I think I know. If anyone would like the spreadsheet to calculate TOS from VSS input (manual trans only for now), just ask.

-Tom

Tom H
07-14-2023, 03:41 PM
Hi,

As I understand it, one basic difference between manual and auto trans is that the number of pulses generated per rev of the driveshaft. I believe that the automatic generates 40 pulses where the manual generates 17 (manual is confirmed). I don't have automatic code and am not sure where on this site I could find it. I had a quick look and didn't see much support for the OBDII generation of PCMs. Perhaps someone could send me a pointer...

In a disassembly I was given, the calibration has a named parameter "TOS_Driveshaft_PPR" which I decode to mean "TRANSMISSION OUTPUT SHAFT PULSES PER REVOLUTION". This name seems almost correct but: The config constant becomes the denominator in a FDIV instruction with a value of $4888. Pushing through all the math I believe this constant is as follows:

("TRANS OUTPUT SHAFT PULSES PER REVOLUTION" / "NUMBER OF SECONDS IN A MINUTE) X 2^16

IN NUMBERS

(17 / 60) * 65536 = 18,568 OR $4888 (This is the constant in my code)

-Tom


I had a better look at this site for automatic code. In the OBDII tune section I found TunerCat ".CAL" files for the automatic. Not knowing anything about this tool or the cal file it works with, I got out my binary edit tool to take a look. Knowing that the FLASH on the TSide bank 0 has a range from $2000 through $FFFF and that bank 1 has a range of $8000 through $FFFF tells me that the TSide needs $16000bytes to represent the flash. Similarly, the ESide has a range of $2000 through $FFFF for a size of $E000. Total .CAL file needs for all the flash is $24000 bytes or 147,456 in decimal. Problem for me was the file had a size of 148,480 bytes. The difference in expected vs. real file size is 1,024 bytes. First guess was that there was some sort of header...
Viewing the file showed a bunch of hex values followed by a VIN for someone's car. Light went on as I realized that the first 1k bytes were the content of EEPROM for the car used to extract the .CAL file from.
My best guess at the format is:

$200 bytes TSide EEPROM
$200 bytes ESide EEPROM
$E000 bytes TSide FLASH bank 0
$8000 bytes TSide FLASH bank 1
$E000 bytes ESide FLASH (no banking on ESide)

Total $24400 bytes or 148,480 decimal

Using my hex editor I found an exact match in the code section with my PCM. Of course the calibration will be different because this is an automatic. I then wrote code to extract the sections into their component parts. I wanted to confirm the conversion of the TPM output for output shaft/driveshaft RPM that I posted earlier.

Looking at the conversion value in the TSide bank 0 at $2B83 for both the manual and automatic code I found:

Manual: $4888
Automatic: $AAAB

The PCM code uses the FDIV instruction so the result is:

(17 / 60) * 65536 = 18,568 OR $4888 (This is the constant in the manual code)
(40 / 60) * 65536 = 43,691 OR $AAAB (This is the constant in the automatic code)

So the calc for driveshaft RPM is confirmed for both transmissions. This was a way too long route to find the answer, but at least I got there.

As a foot note, I know nothing about the TunerCat tool. The code I wrote is good only for LT1 for sure because of the strange multi-processor arrangement. The code could be re-used if someone wants to parse different .CAL files, but would need modifications to the C code. If anyone wants this code, just PM me and I will post it.

-Tom

Tom H
12-06-2023, 11:10 PM
Hi,

I am working on a more modern tool to upload and flash the 1997 PCM. Does this interface look like what you would expect for an upload/program tool? I have little experience with Win32 and all it's controls, messages and voodoo but waded through it to make what I think would be an OK interface. This is just a shell at the moment, so far it does nothing except process inputs. Here is a screen shot of the main window and all it's controls. For ease of understanding I have removed all the options for Srecords and just plan to produce a binary ".bin" file.
I am interested in opinions if there is anything missed or improvements you think of.

-Tom

kur4o
12-06-2023, 11:32 PM
Looks great, maybe add read button, and some progress dialog or simple log window.

I think we need to specify bin format, used for reading tuning and flashing.
This seems the easiest from tune point. All offsets will be correct and easier to create definition file
eside 0-ffff, ,tside 0-ffff, tside 32kb bank2.

Tom H
12-07-2023, 03:06 PM
Looks great, maybe add read button, and some progress dialog or simple log window.

Are you suggesting that the button captioned "Upload" be changed to "Read" ? I will change that.
Progress dialog is a great idea. I will add that. Earlier tool had a monitor of the traffic on the bus. That had no meaning I guess.



I think we need to specify bin format, used for reading tuning and flashing.
This seems the easiest from tune point. All offsets will be correct and easier to create definition file
eside 0-ffff, ,tside 0-ffff, tside 32kb bank2.


There are several formats in use for binary. For myself, I like to use the SRecord but that's not supported by any of the tools. Most binaries I have seen are formatted this way:



TSide
$0000 - $1FFF Padded with $FF. This is the area of ram, peripherals, registers and so on
$2000 - $FFFF Calibration, code, vectors: Bank 0
$10000 - $17FFF Padded with $FF. This area holds same as Bank 0
$18000 - $1FFFF Code, vectors: Bank 1

ESide
$0000 - $1FFF Padded with $FF. This is the area of ram, peripherals, registers and so on
$2000 - $FFFF Calibration, code, vectors. Note: No banking here


There are some (like the .cal files) that eliminate the padding. Probably others I don't know about also. I need to be sure that when programming is requested, the entire binary is programmed. Fail on this and the result is a brick. To that end, I set the default when TSide or ESide is selected to be the whole FLASH. When you do "Upload" (now "Read") the interface permits you to download as little as you like. For example you might be interested in the EEPROM and want to Read that. This front end permits that.
I think that some folks would like to use all the good tools available for OBDI in later cars. I know of no reason that say 1995 software couldn't be loaded on to the 1997 computer. If someone wanted to try this, setting bank 1 lengths to zero and programming just the lower 64K will permit this.

If I understand your suggestion, you would like to see the padding for Tside Bank 1 eliminated. This is easily done with the interface I have by setting Bank 1 padding to zero. As this all gets debugged, I could change the default when TSide is selected to this.

If you like, I can send you a working version of the controls part of the project. I would be interested in further comments and/or suggestions on coding. So far all I have integrated is the serial port.

-Tom

PS: Wonder if anyone has a bricked PCM they could send me. Looking for a 16242921 or perhaps a 16214399 (not as good) to bring this project to life. Needs to be suffering a software issue which I can fix. Trouble finding them locally.

kur4o
12-07-2023, 06:33 PM
0000-1fff can be read too, it is actual ram so is accessed, no need to pad it.

If we move tside part at the end of actual file, there is no need for bank1 padding since it don`t contain any tuning parameters, but we may also leave it, so it is easier for patching. that way all offsets will be correct with the addition of only +10000 +20000 +30000 offset. So we can keep the padding. The file will increase in size but it doesn`t matter since only partial data will be read and written.

With current layout
tside bank0 0-ffff
tside bank1 10000-1FFFF
and eside 20000-2FFFF

The writing will be pretty straightforward
2000-FFFF
18000-1FFFF
22000-2FFFF.

You can also develop some mini bins that contains only vectors and communication loop, that will be written first, so in case the communication is dropped it can be recovered.
The pcm running from mini bin only. Something like a boot mode cutout bin.

On earlier pcm we managed to cut the bin to that parts only, not sure how well will work on later style.

Some bin verification will be needed too. We don`t want someone flash the wrong bin. Some basic checksum and identifiers for bin integrity.

Tom H
12-07-2023, 10:58 PM
While there is no need to pad it, the ram is overwritten by my code to support programming and ESide access. I will maintain padding such that if the file were used to program a part, the first $2000 locations will contain the erased state of the FLASH ($FF). Both TSide bank 0 and ESide need this padding. If you were programming on a standard programmer a blank part, the first $8000 of TSide bank 1 should be handled the same way.

I plan for a TSide file and an ESide file, each starting at $0. If the plan were to have a single file (like the .CAL files) Tside bank 0 would take up 56K, bank 1 32k and Eside 56K:

File
$0000 - $DFFF TSide bank 0
$E000 - $15FFF TSide bank 1
$16000 - $23FFF ESide

So that's a total of 144K which is all the FLASH space that is used. I will mull this over but I lean to having the two files, formatted such that if they were burned on a DataIO machine the bytes would land in the correct place.

Regarding flashing the wrong bin, I don't know how to stop that other than looking at the gm number for the code and forcing a match. Even if this were done there would need to be a bypass to allow someone to program code for a '95 into a '96/7. Can't think why that should be prevented.

kur4o
12-07-2023, 11:22 PM
You need to consider how that files will be tuned. The best format for tuning and creating definitions, regarding offsets will be to stack 3 complete 0-ffff bins, and upon flashing to extract what you need.
1 file fits all will be much preferred than split type of pattern.

That is why we need to carefully consider the final format of file, since the process of flashing will include and editing. Making definition files with messed offset will be real nightmare, while keeping the 3 bin stacked will line perfectly with disassembly and all relative addressing will be just +10000 and +20000.

Tom H
12-08-2023, 01:18 PM
In thinking about how the file will be edited, your suggestion now makes sense. Three blocks of 64K, initialized to $FF and overwritten with the FLASH content. Perhaps a checksum or CRC at the file end.

Implications to the front end read/program are that there is no need to identify padding or code spaces. Probably just needs serial setup, password, and two buttons one for read other for program. Makes the controls 100% easier.

I will put together the revised controls and post.

-Tom

Tom H
12-18-2023, 12:44 PM
Quick update... Face of this tool now looks this way. I have improved several things..
- Serial connection checks that the selected port is available and that the HomeBrew cable is connected.
- New version of the HomeBrew cable eliminates generation and checking of CRC. I now do this in software
such that CRC covers end to end. Not just the J1850 link is covered but also the serial nrz link and the usb link.
- Simplified interface to the cable should help if someone wants to port it to another cable

Future plan includes 4X

19609

Kur4o: Is this more what you had in mind?

-Tom

kur4o
12-18-2023, 02:11 PM
That looks much better, Real efficient and simplified design without crap load of confusion.

A note on improvement will be to add some debug logging in a separate tab or window, in case something bad happens mid flash, user can troubleshoot the problem.
On reading it will be good if the eeprom area of both banks is read too[if not already done], for easier files identification.

You can also add some dummy program mode, that will just dump bin to pcm, without actual writing to happen, to check for stable communication.
Something like simulated flash.

JimCT_9C1
12-24-2023, 09:23 AM
Thank you Tom and kur4o for keeping on with the goal of creating a read/write flash tool for these pcms!

Been away for a while. I'll the give read/upload from post#34 a go, although not sure how far I'll get using my adapter cables vs HBC. The new interface looks clean. I second kur4o's suggestion to keep a debug or log somewhere in case it's needed.

The file format of 192k stacked bin (3x64k: Tside Bank0, Tside Bank1, Eside) is a nice direct way to lay out the bin. As pointed out in post#42,44 this format will make things easier going forward with definition files, etc.

Eventually, it would be handy to be able to read/load bins into the tool from disk that may be in other formats such as non-padded 144k (post#24,43), 145k cal (post#38) or other(?) format. Once in the tool,they could be saved to disk in 192k format for editing or written to pcm. Similar to Bin Converter utility in FlashHack.

Thanks again to you and all contributors for great work and progress!

Jim

Tom H
12-24-2023, 02:46 PM
The file format of 192k stacked bin (3x64k: Tside Bank0, Tside Bank1, Eside) is a nice direct way to lay out the bin. As pointed out in post#42,44 this format will make things easier going forward with definition files, etc.
Jim

Seems I can't leave well enough alone... I made a slight change to the format: I added a 4K comment field to the front of the file. This means if you had a bunch of modified files, you could access the comment with just the notepad editor and read your comments. By default I fill this field with date and time, but you could add any comments you like. Things like made this change to this table and so on. I will try to post an example later today.

My code is tied to the HBC. Won't accept any serial port that doesn't boot with a matching string. Also, no longer is CRC done in the cable. This means that crc covers the transfer end to end. Much more secure of error. Last up the HBC checks the downstream and upstream flow for errors. Since my receiver is independent of the transmitter, the sent command is also received and fed back to software. This ensures that what you send on the bus actually got there. Finally support for xon/xoff.
There is new software for HBC that must be used. When all is done I will post it with everything else.

In an hour or so I can probably post a sample file from my bench PCM.


Still looking for a test PCM. If you have a brick or an unused PCM from OBDII years it's golden

-Tom

Tom H
12-24-2023, 03:11 PM
Actually didn't take much time to make a binary. I dumped the content of both FLASH (both pages for TSide) in about 4 minutes. This is still with X1 speed.

Here is the output file. I added a few comments to show why I added the bit at the front. You can open it with just your notepad (open with ...) to see the comments stored with the code.This should help keep track of what mods are in the file and so on. One more thing though don't change the comments with notepad. This would probably offset the entire content of the file and make it a producer of bricks.

Here is the output file of my first run. You can change the extension to .bin and you will have what I started with.

-Tom

JimCT_9C1
12-28-2023, 04:16 AM
Thanks for sharing, Tom.

Took a quick look and played with it a little bit.

One thing I would suggest is to place the comment/scratch area at the end of the file rather than the beginning; starting after the 192k bin data. This will avoid having to deal with offset memory addresses in definition files etc, and also avoids the potential problem you pointed out of inserted or deleted comment bytes offsetting the following bin data in the file.

I verified that TunerPro would correctly read, interpret, edit, and write files with additional information appended after the bin data. I tested using LT1 OBD1 xdf and bin files. I added and edited comments via Notepad, as well as cut and pasted the comment block from your file and edited that, before and after editing the bin data. Random length comments, separators, etc all worked with no need or effort to try to maintain a fixed block size or structure. The only downside was the need to drag to the bottom of the file after opening with Notepad to view or add comments. I think the robustness to accept unstructured input and not affect the bin data outweighs this minor inconvenience.

Interested to hear what other potential users may think.

Thanks again for all you've done!

Jim

Tom H
12-28-2023, 03:26 PM
Jim,

I changed the format as you suggest. The only difference is that to view the comment (identify what the file contains) you need to scroll to the end. No big deal.

The Upload/Read part of the program is just about done now. I had trouble with the reading taking more time than windows permitted before marking the window as unresponsive. To fix this all the program is now multi-threaded so that controls such as progress bars and whatnot can all be updated with ease.

Here is the latest image of the main screen:

19627

Once you build the HBC, let me know and I will send over test software.

Now starting on the programming. Kur4o provided all the programming code we need to download into PCM RAM. I can re-use the same code was written for the upload section in most cases.

I need to get out to the local U-PULL-A_PART people and see if I can score another PCM. No luck till now, I think most of these were melted down up here in the salt belt.

-Tom

Tom H
12-31-2023, 12:44 AM
Reading/upload is now complete except for the request from Kur4o for debug logging. I will get a look at that while the search for an LT1 OBDII PCM goes on...

There may be some interest in duplicating this capability for use with another cable. I have enclosed a transcript of the Class II bus for anyone interested.

In the file attached the first line is just to ensure the correct port is selected and opened
Lines 2 through 15 set up the download of code into internal ram
Lines 16 through 105 are downloading of the code to support modes $35 and $37 (not supported by the PCM native code)
Line 106 causes the downloaded code to execute, line 107 is the acknowledgement
Lines 108 through 9323 are the upload of flash from TSide bank 0, TSide bank 1 and ESide
Line 9324 causes the downloaded code to exit and reset the PCM, Line 9325 is the acknowledgement
Last two lines.. not necessary but are a request to normal activity on the ALDL

I hope to get to the programming side soon.

-Tom

JimCT_9C1
01-11-2024, 11:55 PM
Thanks for the updates, Tom!

I'll catch up and take a look, been away from this for a couple weeks.
Great progress, thanks for the continued hard work!

Jim

Tom H
01-12-2024, 01:27 PM
Hi,
Project is going ok, but with a few wrinkles. I have the module used to program the TSide loading into the PCM now. I can do all the easy work prior to programming like turn on/off vpp, read the mfg codes, checksum the part. I have looked through the zero the flash and erase the flash routines, they look OK. In addition most of the "feed the ESide fro programming" looks ok. There is trouble with the programming software however. There is no way to set the bank. Half the software looks like it wants to do a complete programming (that would be OK if we had the space to buffer the complete load somewhere), while the other half looks like it will only program the upper bank.
So that needs a bit of attention. I have already corrected two faults in the code and wonder if this module was ever used before. Alternative is that points of entry other than the start of the routine were used. I will spend a bit of time looking through this and changing it.

Main problem going forward is that I need to revive all that I did looking at bootstrapping. This is necessary because making bricks will be part of the debug. Probably can't avoid unless I am way too careful. Careful = slow.

I have not been able to find any OBDII PCMs locally. The Ontario/Canadian way seems to promote recycling as soon as possible. There are few of these cars around now. I am still on the hunt for any OBDII PCMs brick or working.

Looks like we will get a foot of snow today, so I will have time to go through the TSide programming module again and start to make the modifications needed.

-Tom

Tom H
01-16-2024, 01:54 PM
On reading it will be good if the eeprom area of both banks is read too[if not already done], for easier files identification.

You can also add some dummy program mode, that will just dump bin to pcm, without actual writing to happen, to check for stable communication.
Something like simulated flash.


Hi,

I have not been reading EEPROM, but plan to. Thinking to add it into the TSide bank 0 buffer and into the ESide buffer.

Do other programming software use the EEPROM as safety in case of programming interruption? If yes, where can I find the details? If no, I will look into using this.

Kur4o, I am using your suggestion of the "dummy program mode" to test my programming. Works a treat, plan to include that. For now all I do is turn off VPPH and skip the erase.

At the moment, reading and dummy programming for TSide are working and stable. The 68HC11 software that does the actual programming needed work. I have added the needed handling of banks to it and all looks good.

Plan to start on ESide software tomorrow.

-Tom


EDIT: Looks like the EEPROM can be re-positioned such that it replaces FLASH for the vectors. There is a small but usable code space where backup brick prevention can be programmed. I will play with this a bit more. -T

kur4o
01-16-2024, 03:20 PM
If you want to play it really safe on bricking, I can share how it was done on 94-95 lt1. EEprom can be used for easier bin identification since it have vin and Os id.

A mini bin was created that contains vectors reset code and communication code. Than we tested if this mini bin actually communicates and can be recovered.
On flashing, first was flashed that mini bin and later rest of the bin. Chances you had a hard brick was minimal even you completely loss power.
We also skip FFs to speed code flashing, not sure how viable is this with big $400 long messages. You can eventually decrease the message length to accommodate something like that. This can be implemented when you have solid flash code as a phase2.

steveo
01-17-2024, 06:18 AM
in flashhack i make reading the 68hc11's onboard eeprom optional, but i would highly reccommend it.

it's also traditional to read the ram region as it is mapped, but i skip that by default and just leave 0 there. most users appreciate that.

i think flashhack's anti bricking logic is probably worth copying when you have the rest figured. me and kur4o did a lot of testing and research there and it is excellent, it leaves a very short window or just a few seconds during which the ecm is left unbootable, and even within that window, if you don't cut power the kernel stays loaded in ram and you can retry, so the only way you could fail is to cut power during that few second window. very unlikely.

using the eeprom is another option if you could write a compact enough kernel to fit in there, however that eeprom (at least in EE) was locked via the config register by GM, so during the first flash it is impossible to write. you would need to patch the bin's init code to alter the config register, write the bin fully, then reboot the ecm to have write access to that area (which i have done successfully, but it means your first write would always be at risk, right?) my flash tool writes that entire area as well, i figured one day someone might want to relocate a table there and allow really quick and safe updates to it

Tom H
01-17-2024, 07:07 PM
using the eeprom is another option if you could write a compact enough kernel to fit in there, however that eeprom (at least in EE) was locked via the config register by GM, so during the first flash it is impossible to write. you would need to patch the bin's init code to alter the config register, write the bin fully, then reboot the ecm to have write access to that area (which i have done successfully, but it means your first write would always be at risk, right?) my flash tool writes that entire area as well, i figured one day someone might want to relocate a table there and allow really quick and safe updates to it


Interesting that locking of the register... I think we can get around that.

Writing the config register is locked into it's state once 64 eclocks have been run. Looking at the software (at least for '97) the code does this:


; VECTOR TO $4C46

ORG $4C46

LOC_4C46: JMP $6621

ORG $6621

LOC_6621: LDS #$1FFF ; SET STACK AT TOP OF EXTERNAL RAM

LDAA #$01 ; INTERNAL RAM AT $0000, REGISTERS AT $1000
STAA $103D ; CPU INIT

LDAA #$99 ; CONFIGURATION OPTIONS
STAA $1039 ; CPU OPTION

LDAA #$03 ; TIMER CONFIGURATION OPTIONS
STAA $1024 ; CPU TMSK2

CLR $1035 ; BPROT: PERMISSIONS TO WRITE EEPROM/CONFIG REG

LDD $201F ; $0A02

LDAB $0200 ; EEPROM PROGRAMMING TIMER
CMPB #$55 ; LOOK FOR TAG: $55
BEQ $664B ; FOUND, NO BLOCK PROTECTION

LDAA #$10
CMPB #$AA ; LOOK FOR TAG: $AA
BEQ $6648 ; OVERWRITE PROTECTING BPROT

LDAA #$11 ; OVERWRITE PROTECTING PTCON, BLOCK 0

LOC_6648 STAA $1035 ; WRITE BPROT

LOC_664B LDAA #$15 ; CONTINUE WITH BOOT




Downloading to ram a small routine that sets location $0200 to $55 will make the next run un-protected. The normal case is protected as you suggest. The download software need be only a few instructions. First set the tag location to $55, then a tight loop with no COP resetting. Once the COP expires (some nominal delay) a second routine can be run to program the EEPROM and OPTION registers. From then on all resets should go to the vector stored in EEPROM.

I think the programming can be done with no exposure to brickage. Still the problem of writing a kernel, but it need only be a boot loader for the programming software.

What have I missed? I hope to test this out v soon.

-Tom

Tom H
01-18-2024, 05:06 PM
Hi,

This morning I tested the idea of reprogramming the EEPROM to hold some sort of non-volatile loader while programming. This *should* prevent making bricks even if the power is removed half way or some other interruption occurs.

This can be done in this way, there are just a few steps:


Record the content of EEPROM. This has been done in the software I am currently writing.
Run the code below to keep BPROT bits clear. This will no permit you to reload the CONFIG register and place the EEPROM at the top of page overlapping the flash.
Run code to program (not written yet) the EEPROM with a boot loader in case of programming interruption.
Turn off the EEPROM while programming to permit access to the top of FLASH.
When programming is complete, restore the EEPROM, reset the CONFIG register as normal


Once this is done, the code will always run the code in EEPROM, not the regular stuff in flash. At that point you can load into ram the programming and comms routines.



ORG $0000

ENTRY: LDAA #$55 ; TAG VALUE
STAA $0200 ; SAVE
SLOOP: BRA SLOOP ; SUICIDE BY COP


Thoughts?

-Tom

kur4o
01-18-2024, 06:16 PM
This sounds like the eeprom will contain all the flash logic and will switch to eeprom loop in case there is no data on main flash. Like mini boot loader.
ON flashing you can even use code from there and only upload flash content.

On sure how it will work on eside. Might need some reconfiguration and possibly one time patch. But it will be totally bulletproof, once you figure how to switch between main flash and eeporm boot logic.

Tom H
01-18-2024, 07:11 PM
This sounds like the eeprom will contain all the flash logic and will switch to eeprom loop in case there is no data on main flash. Like mini boot loader.
ON flashing you can even use code from there and only upload flash content.

On sure how it will work on eside. Might need some reconfiguration and possibly one time patch. But it will be totally bulletproof, once you figure how to switch between main flash and eeporm boot logic.

I was thinking more like:

Install the loader in EEPROM and program the CONFIG to place it top of memory. This means the vectors are all replaced with those in EEPROM. Now on boot, the CPU takes vectors from EEPROM which restart at the bottom of EEPROM. address would be 0xFE00.
From there the loader will fill the ram, both internal (0x0000 -0x03FF) and external (0x1810 - 0x1FFF) with the flash routines. Once the ram is initialized control will transfer to the ram routines.
The ram routines then disable the EEPROM and execute the programming routines.
Once a successful programming is done, re-program the CONFIG and EEPROM back to their normal function.

As usual the ESide is a little more complicated but the same principal should work. Once the loader is installed the TSide would need to be alive to pass data through the SPI.

I didn't say it would be all easy, but I think it is do-able. I will play with the concept a bit more.

-Tom

steveo
01-19-2024, 07:22 AM
the actual logic will be difficult and i believe will make your plan unworkable, as the original bin that is booted from when starting the flash process has already altered and locked the config register. the config register can only be set once, you can't just alter it at runtime. this means your plan requires altering the original bin so you can mess with the config register on ecm boot at least once, which would require at least one 'unprotected' flash

Tom H
01-19-2024, 12:49 PM
the actual logic will be difficult and i believe will make your plan unworkable, as the original bin that is booted from when starting the flash process has already altered and locked the config register. the config register can only be set once, you can't just alter it at runtime. this means your plan requires altering the original bin so you can mess with the config register on ecm boot at least once, which would require at least one 'unprotected' flash


Hi Steveo,

Original bin locks the EEPROM unless it finds a tag. On finding the tag the BPROT register remains $00 which permits writing of the config *for that boot only*. This is done less than 64 EClocks into the boot (EClock 36 if I remember right) I have already tested this with the stock bin. Kur4o brings up the ESide... I didn't look at that yet but full of hope.
The three instruction code in the earlier post makes this happen for the '97 code. There might be differences year to year. Again all this needs to be looked at before it can be termed a solution.
It is my hope that the original bin needs no mods.

If you have the time, wade through the code snips I posted. First snip shows the instructions run from EClock 0 through EClock 36. Second is code that is loaded into ram at $0 and run. Not written yet is the code loaded into ram that writes the EEPROM with a loader and modifies the CONFIG. If you find a hole in this please post for me.


-Tom

kur4o
01-19-2024, 01:06 PM
I think the best method will be. Boot from vectors set in eeprom[exchange reset vector to some check code in eeprom], upon booting check if main vectors are present at end of file.if not branch to eeprom recovery code, if yes branch to main reset code.

Tom H
01-19-2024, 01:34 PM
I think the best method will be. Boot from vectors set in eeprom[exchange reset vector to some check code in eeprom], upon booting check if main vectors are present at end of file.if not branch to eeprom recovery code, if yes branch to main reset code.

It might be cleaner to have three routines within the app.
- Install boot loader
- Program flash
- Remove boot loader

Once boot loader is installed, the PCM would be non functional until you remove it. With the loader installed it would always look to fill the ram. Your point of the EEPROM size is the most difficult but the factory loader is done (using spi) in $36 bytes. DLC is more complex as is the SPI for the ESide.

I just checked up on the ESide and find that the boot code is the same. We could use the tag to open up the protection (BPROT) and program the config.

->Can't wait to try this<-

Sad I didn't think about this earlier. Good thing Joel brought this up when he did. Probably needs to wait for second revision of the code cause I am too far along now, almost ready for testing.

-Tom

In-Tech
01-21-2024, 09:14 AM
Hi,

This morning I tested the idea of reprogramming the EEPROM to hold some sort of non-volatile loader while programming. This *should* prevent making bricks even if the power is removed half way or some other interruption occurs.

This can be done in this way, there are just a few steps:


Record the content of EEPROM. This has been done in the software I am currently writing.
Run the code below to keep BPROT bits clear. This will no permit you to reload the CONFIG register and place the EEPROM at the top of page overlapping the flash.
Run code to program (not written yet) the EEPROM with a boot loader in case of programming interruption.
Turn off the EEPROM while programming to permit access to the top of FLASH.
When programming is complete, restore the EEPROM, reset the CONFIG register as normal


Once this is done, the code will always run the code in EEPROM, not the regular stuff in flash. At that point you can load into ram the programming and comms routines.



ORG $0000

ENTRY: LDAA #$55 ; TAG VALUE
STAA $0200 ; SAVE
SLOOP: BRA SLOOP ; SUICIDE BY COP


Thoughts?

-Tom

Hiya Tom,
At a glance, the SLOOP is an incredibly tight loop especially in eeprom and not flash.
In my mind, if you have room, I am thinking a JSR to use some ticks as well as more ticks using the stack, then a simple LDY(or anything not being used or needed later before loop quits)

SLOOP JSR(somewhere)
LDY #$FF
DECY
BNE(somewhere)
RET


It's been a bit since I did assy, forgive. I think this will use up some ticks and of course can be enhanced or tuned from there. NOP's. I'm sure you get the "jist" :happy:

Tom H
01-21-2024, 11:49 AM
Hiya Tom,
At a glance, the SLOOP is an incredibly tight loop especially in eeprom and not flash.
In my mind, if you have room, I am thinking a JSR to use some ticks as well as more ticks using the stack, then a simple LDY(or anything not being used or needed later before loop quits)

SLOOP JSR(somewhere)
LDY #$FF
DECY
BNE(somewhere)
RET


It's been a bit since I did assy, forgive. I think this will use up some ticks and of course can be enhanced or tuned from there. NOP's. I'm sure you get the "jist" :happy:


Hi!
Tight loop is actually intended. For the remaining duration of the COP (CPU or PRU) the CPU keeps accessing three locations in repetition. Presents no troubles, I have tested it well. The loop could be larger but the intent would remain: to reset the CPU without affecting location $0200. Once reset it gives the code the ability to change the CONFIG register stored in EEPROM.
Probably the smallest program I have ever written...

-Tom

In-Tech
01-21-2024, 06:51 PM
I'll say a small prayer for the substrate. :laugh: :happy:

Tom H
01-21-2024, 07:34 PM
I'll say a small prayer for the substrate. :laugh: :happy:

Prayer? We need more of a chant.
Both Motorola and GM tested the heck out of these things, extreme cold & extreme hot. Elevated voltage and under voltage. Substrate will be fine.
Here is an example where GM used the same principal




*************************************************
* SOFTWARE INTERRUPT: VECTOR AT $FFF6
*************************************************
4C28 14 00 08 BSET @$00,$08 ; SPERIOUS SOFTWARE INTERRUPT
4C2B 20 FE BRA $4C2B ; LOOP TILL COP RESET HITS



Cheers,
Tom


NO wait their code is actually tighter than mine. They used relative addressing/branch. Their code beats on two locations where as mine beats on three!

In-Tech
01-21-2024, 11:10 PM
Hahaha, chanting :laugh:
Back in the 90's I ran some tests on some TMS370 stuff, brutally burning the bit flips from 00h-FFh and it took ~30,000,000 cycles before partial failure. Adding that short delay got it up to ~90,000,000. Fun stuff. Thanks Tom for the memory visit. Great work, btw :)

Tom H
01-21-2024, 11:31 PM
0 stuff, brutally burning the bit flips from 00h-FFh a


Hey Carl,
Am I confused? The tight loop is just execution waiting for the watchdog/cop to hit. At this point it is just setting a ram location and resetting. When it reboots the GM software leaves the BPROT open for access when it sees my tag. At that point, I can mess with the EEPROM and CONFIG register to get the desired results. Since it is just execution not programming tight loop is OK.

I was sure you were pulling my leg

-T

In-Tech
01-22-2024, 05:09 AM
Hi Tom,
Yeah, I was having a little fun about the substrate :) This situation has no worries, it just reminded me when I wrote a "burner" to test. The spec sheet said it was only good for ~100,000 writes. I thought BS and did some testing for myself :rockon:

Tom H
01-25-2024, 10:56 PM
Hi In-Tech,

I wrote the loader and now have it working, but have run into a problem with my assembler. I have variables that I map into the internal ram starting at 0. My program is resident in EEPROM at $FE00 and above all the way up to the vectors.

The assembler output that I use is SRecords. It refuses all my attempts to get it to create the final execute record at the right place. It always wants to run from zero. NOT from the $FE00. Would you happen to know what magic incantations are required in the code to get it to make the correct S9 record? I have tried all the commands that have any promise in the manual. The assembler I am using is ASM11.

As it is each time I assemble, I need to go into the file change the execution address manually and re-calc the checksum. ??tools??

-Tom

In-Tech
01-26-2024, 12:51 AM
Hiya Tom, I will have to dig to find this older stuff. I'm surprised you are using MotS, Intel hex has always seemed good but I have never worked with your box. If you would like, PM me the code to assemble and I will attempt in MotS.

Btw, it's Carl, as noted in my sig line :)

Tom H
01-26-2024, 04:26 AM
Hi Carl,

Here if the loader file we have been talking about. See attached

-Tom

In-Tech
01-26-2024, 05:23 AM
Thanks Tom,
I mentioned PM in case you didn't want if public. Man, shit ton of equates in there :happy: I'll have a gander tomorrow :)

Tom H
01-26-2024, 02:09 PM
Thanks Tom,
I mentioned PM in case you didn't want if public. Man, shit ton of equates in there :happy: I'll have a gander tomorrow :)

Thanks Carl.
I am writing this tool for everyone, it's all public.

I added a line using #S19WRITE to the end of my file. This generates a text version of the S9 record. At least I only need to delete one line. It's a bandaid solution. I hope you can find better.

-Tom

kur4o
01-26-2024, 02:42 PM
If you fill with zeroes the extra blank space, it will not interact with checksum and maybe it will get aligned properly. Not the best solution but it will save some effort.

Tom H
01-27-2024, 01:23 PM
If you fill with zeroes the extra blank space, it will not interact with checksum and maybe it will get aligned properly. Not the best solution but it will save some effort.

Code is OK... loading ok, working ok. Rub I have is that the S9 record which is the "go execute here" address points to $0000, not where the code is. Bandaid is that I manually calculate the S9 record and put the text in the SRecord file. Then all I need to do is delete the S9 produced by the assembler. I am sure there is something I am doing that is preventing the assembler from working. This is just a tool though and I don't want to spend any more time than necessary fighting with it. Some day I may trip over the answer...

The idea of reducing the probability of bricking a module is the motivation for all this. I spent some time on it and so far I can:

Unlock the EEPROM
Re-program the EEPROM content with the loader


All that remains is the bit where I re-program the config to have the EEPROM replace the startup vectors. Plan to try that over the next hour or so. Fingers crossed

-Tom

Tom H
02-03-2024, 07:00 PM
Hi,

Going back a week or so, we were discussing ways to prevent creating bricks when programming is interrupted for some reason. I had the idea to use the on chip EEPROM that is part of the MC68HC11F1 used on the OBDII LT1s for this. Learning about how GM uses the part and all caused me a bit of pain. Several times I bricked my module until I came to understand more about how the EEPROM is used.

Speaking of just the TSide for today...
Turns out that address $0E35 in the EEPROM is used by the code in flash to determine if the module has been set up or not at the factory. First thing I did was to erase the EEPROM which made this location $FF. Once erased the OBDII will not respond to commands except one mode. After thinking I had junked the PCM, I started looking at the code to see what had happened. Turns out that the location at $0E35 is programmed using mode $3B. I must have spent hours tracking this all down. One command: 4C 10 F0 3B A0 00
and I was back in business. Not the end of troubles though.

I wrote a loader with almost zero features to place in the 512 byte EEPROM. I mapped a hole in my code at $0E35 so that my password would still work. The code does however fill the EEPROM to the brim and thus overwrites the password. No troubles there though because I knew where the pass (and seed) were stored and just changed the password I was sending.

I first tested the loader at the standard location in low memory. Then re-assembled for use at address $FE00. Once placed at that location it replaces the vectors that are normally provided by FLASH. I wrote the loader such that there is space at the top for these vectors. On startup the vectors point to the EEPROM and execution starts in the loader.

OK, so what does all this do for us? The loader is installed by re-programming the EEPROM. Once this is done the PCM is brain dead on restart except for one function: filling it's RAM memory with code that you send it. In our case if we wish to re-program the flash, we would send down a programming/erase/verify routine to the ram. By running this code out of ram, the entire flash can be re-programmed. In the case of an interruption to the programming, the loader is still in EEPROM and ready for you to try again. Used properly, it should prevent any bricks.

Next post is on the use of bootstrap/test mode. Want to separate the topics just a bit....
Tom

Tom H
02-03-2024, 07:51 PM
Hi,
Going way back there were some details given regarding repair of bricked PCMs. I have had reason with the re-programming project to make use of this. I wanted to document some bits here as this efforts may make it necessary for others to have this ability...

First up, here is the schematic of the hardware:
19719

I want to focus on the USB <--> Serial cable for a moment. Cables using the Prolific chip and it's clones are a problem. Microsoft goes out of it's way to mark your driver obsolete every time you change anything or they do an update. You can continue with it if you don't mind fighting with Microsoft all the time. Even then, depending on if your cable is a clone of the prolific part (most are) the baud rate is WAY off in most cases. Remember that a 5% error in baud rate builds over the 10 bit word and by the last bit is 50%. Probably doesn't work or at best is unreliable.
I have found that cables based around the CMD340 chip set work a treat. No driver issues. Baud rate with less than 1% error. I did a hack test on the ones I got for some rates of interest:
1,890, 8,192 and 12,288. These are the rates useful for work on the LT1 PCMs. Using a frequency counter I sent 'U's to the port and found better than 1%. I believe most of the error is from my terminal software. These cables cost $5 and I am going to purge all the half working stuff I own.

Ok, so that is the cable side of things. The rest of the schematic is just pulling pins low to change the processor startup mode to bootstrap, pull up the data lines because wire or is default and so on. The connector to the board I use can still fit in the case. They are just wire wrap header pins (.025 square, 2wide by four long). Here is a picture:
19720
The connectors are not numbered on the PCB, nor is there a square pad to indicate pin 1. I selected the following for pin out.
19721
Last up is a picture of my setup for bootstrap
19722

With this setup and some software you can overwrite both flash and EEPROM. It's just opinion but I don't think FLASH parts should ever be socketed or replaced. Once the conformal coating of the board is broken or a socket added I think the reliability will be poor.

When writing code for the loader I needed this setup to recover the PCM... twice I am sad to say.

-Tom

Tom H
02-04-2024, 04:50 PM
Hi,
Question for you all... In my disassembly it is marked where the checksum is located for the TSide ($2015). What does this checksum cover? Is it the calibration, calibration + code, sum of E +TSides, both banks ????

If someone knows, I won't need to go back through the code to find out.

Cheers,
Tom

kur4o
02-04-2024, 06:53 PM
It should cover both banks, from checksum address to end of bin. 16 bit byte sum.

Tom H
02-04-2024, 10:30 PM
It should cover both banks, from checksum address to end of bin. 16 bit byte sum.


Thanks! I found my problem in an unexpected place. The loader I planned to use to prevent bricking puts the EEPROM in the upper memory at $FE00. Since it overlays the flash, my checksum is wrong. Worse, it will prevent the programming of the upper flash.

Now I just need to see if I can find a solution. I can't move it because it supplies the vectors. Can't turn it off because that's in the config which is protected. HMMMmmm, Kind of makes me think of the first rule of holes...

-Tom

Tom H
02-04-2024, 11:12 PM
I can't move it because it supplies the vectors. Can't turn it off because that's in the config which is protected. HMMMmmm, Kind of makes me think of the first rule of holes...
-Tom

Use of the EEPROM as a loader is not workable. In expanded mode there is no way to move or remove the EEPROM from the memory map. It hides the last 512 bytes of flash. I have looked hard, there is no workaround that I can find. In fact the EEPROM used as a loader works a treat for everything but those last few bytes on both pages.

I need to look further into the solutions already in place for the earlier PCMs OR ??
-Tom

kur4o
02-04-2024, 11:22 PM
If it doesn`t work as expected you can always put it on hold for now, and focus on actual writing, reading operation. Than when that is nailed, we can look for brick safe solution.

steveo
02-05-2024, 05:06 AM
yeah you really need to stop the scope creep and just get a working full reprogram even an unreliable one. eehack never had any of the extra safety measures and it was everyones favorite flash tool for like half a decade. it barely bricked anything. we can definitely help you with the logic that we've put into flashhack. it's insanely reliable, like there is a less than 10 second window where if you disconnect power from the ECM it would be unbootable, outside of that it's recoverable.

Tom H
02-05-2024, 10:59 PM
Not sure if it is scope creep... Loader used all the same OBDII structure for commands. Most of the time spent is still of value. Target changes from my loader to GM's code and the module Kur4o provided. For sure I learned good lessons about my assembler and the way it mishandles the S9 record. In this case mishandles=not what I expected, function of S9 isn't well documented. Assembler isn't well supported as the author passed away.

Currently, I have the module loading and doing some prelim stuff, turn on/off vpp, measure voltages. Task at hand is creating the code that can be loaded via bootstrap, morph into special test mode and run that programming module. That way when the FLASH goes away... zeroed, erased and so on I can still step through the programming and/or recover the PCM if I need to.

I am close... probably even try programming TSide later this week.

-Tom