VX220 Stack Gauge Cluster

Introduction and miscellaneous that we haven't created categories for, yet
Post Reply
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

VX220 Stack Gauge Cluster

Post by catphish »

As part of my VX220 build, I am currently in the process of reverse engineering and reprogramming the Stack gauge cluster.

The goal is to allow the gauge cluster to display relevant data such as state of charge and motor temperature, replacing fuel level level and engine temperature, and also to use the techo needle to display current or power.

This is probably a little off-topic on this forum, but I thought I'd document my findings here. The gauge cluster is built with the following hardware:
  • MCU/CPU: MC68HC11A1CFN3
  • SRAM: GM76C256CLLFW70
  • ROM: M27C1001
  • Display: S6A0069X10-Q0
  • Address decoding: GAL16V8D
  • Output buffer driving 2 x stepper motors: AC374
  • Stepper motors: X15.116
This microcontroller is super interesting because it has internal peripherals, but also an external 16 bit address bus, allowing external peripherals to be mapped directly into memory. After a few days of reverse engineering, I have mapped out the memory and GPIO:

Code: Select all

0x1000 - PORT A
    0(IN)  - Tied to GND
    1(IN)  - Speed input
    2(IN)  - Tacho input
    3(OUT) - Illumination
    4(OUT) - Force on (maintains power when ignition off)
    5(OUT) - ROM A15
    6(OUT) - Turns on indicator + handbrake + brakes + full beam LEDs
    7(I/O) - (IN) Ignition ON (A3)

0x1008 PORT D
    0(I/O) - Serial RX
    1(I/O) - Serial TX
    2(I/O) - Unknown - to unpopulated resistor component
    3(I/O) - Unknown - to unpopulated resistor component
    4(I/O) - Unknown - to HC373A, pin D5, purpose unknown
    5(I/O) - Unknown - to unpopulated resistor component

0x100A - PORT E
    0(IN) - Coolant temp (A6)
    1(IN) - Fuel level (A7)
    2(IN) - Driver's door switch (B11)
    3(IN) - Coolant level (B10)
    4(IN) - Headlights on (B6)
    5(IN) - Trip reset button (B9)
    6(IN) - Tied to GND
    7(IN) - Unknown

0x0700 - Stepper control
    0,1,2,3 - Stepper 1
    4,5,6,7 - Stepper 2

0x600 - LCD Command
0x601 - LCD Data

0x0000-0x00FF - MCU RAM
0x0800-0x0FFF - External RAM (full range unconfirmed)
0x1040-0x7FFF - External RAM (full range unconfirmed)
0x8000-0xFFFF - External ROM (full range unconfirmed)
The board exposes the following lines on a debug port:
  • UART RX
  • UART TX
  • MODEA
  • MODEB
  • RESET
Using this debug port, I am able to reset the microcontroller into bootstrap mode and load a new program via the UART. This must be sent at 7200 baud which is a little inconvenient, but using a genuine FT232 USB cable, this works perfectly. I have been able to successfully load and execute code, write characters to the LCD, and control the stepper motors.

Unfortunately, the on-board ROM is one-time-programmable, so in order to permanently reprogram the board, I would need to replace the ROM chip with a pin-compatible flash. This is certainly possible, but my preference for now is to run the device in the manner I am running it now. I will connect an STM32 or RP2040 board with CAN to the debug port. This can reprogram the cluster at startup then stream data from CAN to it.

See attachments with detailed photos. I will now work on a simple firmware that accepts data from serial and displays it. The biggest challenge will be reliable stepper motor control.
Attachments
PXL_20230318_181603708(1).jpg
PXL_20230318_195117798(1).jpg
PXL_20230318_195128122(1).jpg
PXL_20230318_223330720(1).jpg
PXL_20230318_181025101(1).jpg
PXL_20230318_180958361(1).jpg
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: VX220 Stack Gauge Cluster

Post by johu »

That is one complex gauge cluster!
Not off topic at all, vehicle integration is very welcome. Would it fit in any of the OEM categories? Maybe should add a "Miscellaneous" one :)
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: VX220 Stack Gauge Cluster

Post by Pete9008 »

Nice work with the reverse engineering :)

Stack do make some very good quality instruments.

Brings back memories with the external memory/paged memory system!

Have you had to do a dual stage bootloader or can the 68HC11 one program the external RAM directly?

Re the steppers I've done a couple of rev counter movements using them. There's not much to driving them, I found the best implementation was to have an ISR running at the max desired step rate (guarantees a nice smooth update rate and makes it difficult to drive too fast and lose steps) with the target position being supplied from an IIR/FIR in the main loop. How do you zero them on that cluster, is there a positive end stop or a sensor? I can probably dig out some source code code if that helps (I should have code for both 8051 and STM32 but can't guarantee I can find the former).

Look forward to following progress.
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

Re: VX220 Stack Gauge Cluster

Post by catphish »

johu wrote: Sat Mar 25, 2023 8:28 am That is one complex gauge cluster!
Not off topic at all, vehicle integration is very welcome. Would it fit in any of the OEM categories? Maybe should add a "Miscellaneous" one :)
Yes, it would make more sense in the OEM forums. I think it would be a good idea to make a "Misc OEM" category. Feel free to move this post to either, I'm not sure which is more appropriate as this is really a Lotus part, not a GM part :)
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

Re: VX220 Stack Gauge Cluster

Post by catphish »

Pete9008 wrote: Sat Mar 25, 2023 10:52 am Have you had to do a dual stage bootloader or can the 68HC11 one program the external RAM directly?
The built-in loader can only load 256 bytes of code to the integrated RAM, so I will need to build a two-stage loader to enable the external RAM then load more code there. So far, I haven't had to do this as all my test code (which I'm writing in ASM) has been less than 256 bytes. I suspect the final program will be much larger though.
Pete9008 wrote: Sat Mar 25, 2023 10:52 am Re the steppers I've done a couple of rev counter movements using them. There's not much to driving them, I found the best implementation was to have an ISR running at the max desired step rate (guarantees a nice smooth update rate and makes it difficult to drive too fast and lose steps) with the target position being supplied from an IIR/FIR in the main loop.
Thanks, this sounds like a very good idea. I will almost definitely do it this way, as it means I can run other code freely and not have to worry about timing. The main loop can just set a target position, and the ISR can move individual steps.

The needles have mechanical endstops inside the motors, so zeroing them should just be a matter of doing a full sweep. Unfortunately, i destroyed one of the steppers in my test unit trying to take it apart. Should be able to replace it though.
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: VX220 Stack Gauge Cluster

Post by Pete9008 »

Impressed your coding it in assembler!

I think GCC still supports the 68HC11? Although you may be best sticking with assembler for the 1st stage bootloader if you only have 256 bytes available.

On the steppers the proper way to do it is to also implement acceleration/deceleration ramps (2ways to lose steps, running too fast and accelerating too fast). I found I could get away without the ramps but then it was using small NEMA steppers which probably had more torque and lower speed. If needed ramps are still best done in the ISR though.

A sweep on start up should work, looks good too!
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

Re: VX220 Stack Gauge Cluster

Post by catphish »

Short demo of my initial testing. I'm actually using the wrong stepper pattern here (4 step instead of 6). Will implement the correct step pattern soon and test different speeds for missed steps.
https://www.youtube.com/embed/CdFOtvMrDKE
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

Re: VX220 Stack Gauge Cluster

Post by catphish »

Here's a short sample of assembly code that runs on the device. This code just prints the values from PORT E (0x100A) to the display.

Code: Select all

start:
	# Stack pointer
	lds #0xff

	# Enable extended mode
	ldaa #0xe3
	staa 0x103c

	# Enable backlight LED
	ldaa #0x10
	staa 0x1000

	bsr display_init
loop:
	# Go to start of first line
	bsr delay
	ldaa #0x80
	staa 0x600

	ldaa 0x100a
	ldx #0x08
	loop_x:
		BITA #0x80
		bne notzero
			bsr print_0
			jmp zero
		notzero:
			bsr print_1
		zero:
		lsla
		DEX
		bne loop_x
	jmp loop
delay:
	PSHX
	ldx #0x1000
	delay_loop:
		DEX
		bne delay_loop
	PULX
	rts
display_init:
	# Configure display by loading constants into 0x0600
	PSHA
	# Basic configuration, 8 bit, 2 lines, 5x8 font
	bsr delay
	ldaa #0x38
	staa 0x600
	# Display on, cursor off, blink off
	bsr delay
	ldaa #0x0c
	staa 0x600
	# Clear display
	bsr delay
	ldaa #0x01
	staa 0x600
	PULA
	rts
print_0:
	# Load character into 0x0601
	PSHA
	bsr delay
	ldaa #0x30
	staa 0x601
	PULA
	rts
print_1:
	# Load character into 0x0601
	PSHA
	bsr delay
	ldaa #0x31
	staa 0x601
	PULA
	rts
I thought it would be fun to ask ChatGPT to explain how this code works:
This is an assembly code for the M68HC11 microcontroller, which is setting up and controlling a display to output some binary data.

The program starts at the label "start" and first sets the stack pointer to 0xFF using the "lds" instruction. Then it enables extended mode by loading the value 0xE3 into the accumulator (using "ldaa") and storing it at memory address 0x103C (using "staa"). Next, it enables a backlight LED by loading the value 0x10 into the accumulator and storing it at memory address 0x1000.

After this initialization, the program jumps to the "display_init" subroutine to configure the display. This is done by loading various constants into memory starting at address 0x0600 using "staa" instructions. The subroutine then returns to the main program.

The main loop starts with a delay subroutine ("bsr delay") and then sets the display cursor to the start of the first line by loading the value 0x80 into memory address 0x600. It then loads a byte of data from memory address 0x100A into the accumulator (using "ldaa") and sets the index register X to 0x08.

It then enters a loop where it checks each bit of the byte of data by using the "BITA" instruction with a mask of 0x80. If the bit is not zero (i.e., it is a one), it calls the "print_1" subroutine. If the bit is zero, it calls the "print_0" subroutine and then jumps to a label "zero".

After printing the bit, it shifts the accumulator left by one bit (using "lsla"), decrements the index register X (using "DEX"), and checks whether it has reached the end of the byte of data by using the "bne" instruction. If it has not reached the end, it jumps back to the "loop_x" label to process the next bit.

If it has reached the end of the byte of data, it jumps back to the "loop" label and repeats the process.

The "delay" subroutine is a simple delay loop that counts down from 0x1000 to 0 using the index register X.

The "print_0" and "print_1" subroutines simply load the appropriate ASCII character (either '0' or '1') into memory address 0x601 and then return.

The program continues to loop indefinitely, printing out the binary data on the display.
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

Re: VX220 Stack Gauge Cluster

Post by catphish »

I've put together a small toolkit including a chain loader, example program, and PC serial loader: https://github.com/catphish/gaugemod
This allows me to compile and run larger C programs, so I should now be able to write the remainder of the code now.

I am able to make interrupts work as long as I keep the processor in "special mode" which points all interrupts to internal RAM rather than external ROM.
User avatar
catphish
Posts: 954
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 93 times
Been thanked: 179 times

Re: VX220 Stack Gauge Cluster

Post by catphish »

I now have the gauges and LCD working nicely with data fed in by the serial port.

There are three major things left to do:
1) Look at handling the pulse inputs for the speedo. This isn't essential but I'd prefer to get the speed from the original ABS feed rather than CAN from the drive unit.
2) Look at counting distance and storing odometer / trip readings.
3) Putting it all together, with nice things like paging through screens of data. This includes writing code for an external MCU to stream in the data, as I'm using a PC right now to test it.

Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: VX220 Stack Gauge Cluster

Post by Pete9008 »

Looking good!
Post Reply