Apply custom images to Ford Convers+

IPC - Instrument cluster panels (like Convers+)
Post Reply
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Apply custom images to Ford Convers+

Post by Go4IT »

Hey guys, today i add this topic where i've been working for a while. The goal was to find, extract and change the images, especially the screensafer image (Ford logo) to something custom.

After putting this project down for a while, a cool guy append to my project an gives the needed hint. He did find the encoding of the images and was so kind to share his knowledge with me. We will explain the method in the following posts.
THX and welcome @Ursadon ! :D

So the very first step is done, we know the imageformat and could now create it from out custom images. It therefore needs to be remapped from truecolor RGB to indexed color palette with 256 colors.

Next would be to find the color LUTs to put the inks of the palette. Also to find out the memory layout, how the system finds the image it wants. Regarding to his disassembling the image is displayed via a shared memory imagebuffer in RAM of the MCU (MAC7117), where the LCD board accesses it. So it may worth a look into the screens datasheet, or it's processor, to find all releveant informations.
User avatar
Ursadon
Active member
Posts: 81
Joined: 10 Mar 2019, 19:23

Re: Apply custom images to Ford Convers+

Post by Ursadon »

- "Alright guys let's do this" (c) leeroy jenkins

We have:
Hardware:
NXP MAC7116VAG50 - ARMv4T (ARM7TDMI) uC (1Mbyte)
Epson S2D13A05F00A1 - LCD controller, but i can't find any datasheet. Maybe need to send email to Epson to get it.
Spansion S29GL016A90TFIR2 - Flash (2Mbyte)
more at https://mk4-wiki.denkdose.de/artikel/ip ... ardown_vfl
Software:
8M2T-14C026-CE (ROM)
8M2T-14C026-ED (flash)

All images stored in Flash in this format:
===================================
00 00 00 FF 01 00 00 00 - Header
...
... RLE-Encoded (with zero-pad)
...
XX XX - width
XX XX - Height
XX XX - width
00 00 - <probably> Height - but seems like always 00 00
30 XX XX XX - PTR to start of data frame
30 XX XX XX - PTR to start of image
00 00 56 38 - End of image (EOI)
===================================

So what is "RLE-Encoded (with zero-pad)" ?
its mean: if previous byte is zero, then current byte contains count of
repeats next byte
if previous byte is non-zero (and previous decoding done) then current
byte contains count of bytes to read.

First 2 RLE's we must treat as "count of repeats" (not yet full tested, but supposed to be true)

Notices:
1) <deprecated>

2) "End of image (EOI)" is not a marker! It is offset to the function that is used for data parsing.

3) At ROM, at 0x00005638 sits DisplayDraw function

Image

Image

4) ROM contains no functions for direct send commands to LCD
controller. PBL configures DMA and defines mem region (0x20217700) to use as framebuffer. But for 400*200*1 image we need 79KBytes of ROM - we need to investigate it.

5) All images stored as RGB8 picture, so we have only 256 colors, but
colortable is not standart. It have too many bits for blue. We can see
correct table at Display test (self-test of IPC). 0x00 offset in self-test at bottom of screen.

6) I created a table with an example of parsing an image located at 0x00000000:
https://docs.google.com/spreadsheets/d/ ... sp=sharing

7) initial function for bootlogo is at 0x000176F0, and there is no xrefs to it. I think that in the PBL there is some kind of RTOS (maybe QNX - i don't have a dump of region 0x00000000 - 0x00005000), which calls this function under certain conditions.

Image

8) TODO: colortable. It is not a standart RGB8 [2:3:2]. it have an alpha channel. if byte is = 0xFF, it's not a black color - it means transparent pixel (skip byte printing)
Last edited by Ursadon on 22 Mar 2019, 15:50, edited 1 time in total.
Not native English speaker :cry:
IPC hacker, embedded cracker, tamer of bears & beers
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

I've played around a bit and wrote a small tool in PHP (don't hit me, but i used the first language in sight, maybe i port this to Visual C# on PC some day, or any of you guys do). It extracts all images from the Flash section of the firmware and get quite a lot of images. Some of them are distort for unknown reason.

What i found out is that you mixed up width and height in the format, they need to be swapped.

Also the image end is alway a '00 00', meaning that direct data seem to follow (cmd) but it's length is zero. This definitively terminates the framdata. Now, normally the height follows as a word (2 bytes, to be precise). But some images have an extra 0x00 between those symbols. If found out that this is a padding byte if the image data does end on an word boundary. So if address after end-of-frame marker is odd, there is an pad byte inserted. This really confused my tool on the first run, because it leads to huge pixelsizes ;-)

And you're right about the alpha channel (transparency) but i think it is a 0x00 which denotes transparent, not 0xFF like you mean. 00 in RGB terms is white, not black and FF is black, not white. We have subtractive color model here.

Here my notes in your writing:

1) Aggreed, this seems to be true always!
2) is true, but then let's not call it end of image, call it draw pointer.
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

5) and 8) Here is a photo of the testimage we need to find the LUT from:
43C70B56-12D8-4AEF-8187-449BADFE601F.jpeg
Maybe we could adpot the inks to build a temporary index palette, just to get nice images, until we found the real values. They must be somewhere... maybe in the LCD controller init routine if it is global.

I don't think you are right about RGB8, we have an indexed color palette here. As i remember from the LCD datasheet it has limited color capabilities of 65.536 inks but Convers only uses 256 of them. Therefore each byte (pixel) indexes a color with it's value. The colorant itself it set in the lookuptable (LUT) where each index holds and "whatever" color component value, maybe RGB, maybe something different.

7) The firmware imge does not contain anything, so,you can't do a bootstrap programming with a fresh MAC7117 with it. There is some boot ROM code reside on the chip, which never gets changed and we don't know.

----

I've added a datasheet of the LCD controller and one for the MCU. It could be of some help.
b1549218978.31617.pdf
b1549218978.31628.pdf
You do not have the required permissions to view the files attached to this post.
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

I'd like to explain the RLE decoding on an practical example, using the "compass" image from the navigation part:
rle_example_compass-image_0x3F14.png
Here in the data section is the binary range marked, which contains this picture:
convers_image_compass_24x23_addr-0x3F14.png

Code: Select all

Here is the decoding logic of the bytes:
Image found at 0x00003F14
0x00003F20: repeat 0x00 0x0B-times
0x00003F22: repeat 0x34 0x01-times
0x00003F24: repeat 0x00 0x17-times
0x00003F26: repeat 0x33 0x01-times
0x00003F28: repeat 0x00 0x16-times
0x00003F2A: add 0x03 direct bytes
0x00003F2F: repeat 0x00 0x15-times
0x00003F31: add 0x03 direct bytes
0x00003F36: repeat 0x00 0x15-times
0x00003F38: add 0x03 direct bytes
0x00003F3D: repeat 0x00 0x14-times
0x00003F3F: add 0x05 direct bytes
0x00003F46: repeat 0x00 0x13-times
0x00003F48: add 0x05 direct bytes
0x00003F4F: repeat 0x00 0x13-times
0x00003F51: add 0x05 direct bytes
0x00003F58: repeat 0x00 0x12-times
0x00003F5A: add 0x07 direct bytes
0x00003F63: repeat 0x00 0x0E-times
0x00003F65: add 0x0D direct bytes
0x00003F74: repeat 0x00 0x08-times
0x00003F76: add 0x1A direct bytes
0x00003F92: repeat 0x00 0x06-times
0x00003F94: add 0x03 direct bytes
0x00003F99: repeat 0x00 0x06-times
0x00003F9B: add 0x1A direct bytes
0x00003FB7: repeat 0x00 0x08-times
0x00003FB9: add 0x0D direct bytes
0x00003FC8: repeat 0x00 0x0E-times
0x00003FCA: add 0x07 direct bytes
0x00003FD3: repeat 0x00 0x12-times
0x00003FD5: add 0x05 direct bytes
0x00003FDC: repeat 0x00 0x13-times
0x00003FDE: add 0x05 direct bytes
0x00003FE5: repeat 0x00 0x13-times
0x00003FE7: add 0x05 direct bytes
0x00003FEE: repeat 0x00 0x14-times
0x00003FF0: add 0x03 direct bytes
0x00003FF5: repeat 0x00 0x15-times
0x00003FF7: add 0x03 direct bytes
0x00003FFC: repeat 0x00 0x15-times
0x00003FFE: add 0x03 direct bytes
0x00004003: repeat 0x00 0x16-times
0x00004005: repeat 0x33 0x01-times
0x00004007: repeat 0x00 0x17-times
0x00004009: repeat 0x34 0x01-times
0x0000400B: repeat 0x00 0x0C-times
0x00004010: end of imagedata found
Image size: 24 x 23 pixels
Save image as: convers_image_001_24x23.png
Now for the explaination

At start of image data at 0x31FA we find the header, consisting of 3 words (note we are on an 32 bit architecture, so a word as 4 bytes long):
00 00 00 FF
01 00 00 00
00 00 00 00

Right after this, we find the first frame data RLE symbol: 0B 00
The first byte give the number of repeats (0x0B = 11 times) where the seconds byte is the value (pixel index color) to place in the resulting image.

Next comes: 01 34
means "value 0x34 is repeated 1 time"

This continues the same way until address 0x31FA. There we find: 00 03 38 33 38 15
Wait! What is this? A zero number of repeats?
Yes! But in tells us that there is a "direct data" RLE symbol. The following Byte give the number of Bytes following the length byte. So '03' denotes three bytes of direct data, namely '38 33 38 15', which are put 'as-is' into the resulting image.

There is only one additional RLE symbol, the 'end-of-data'. It also starts with an zero length, like the 'direct-data' symbol, but has the length byte set to zero. We found this at address 0x4010.

After it, there may be some extra padding bytes (00). I found none, one or two bytes here until be go over to the image metadata section. I guess this is because of the 32 bit alignment made for effective accessing memory locations. So for now i suspect, that the last RLE symbol is padded to a 4 byte length of the frame data.

Right after this, we can read 2 bytes of image width given in pixels, and 2 bytes of image height.
You do not have the required permissions to view the files attached to this post.
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

The image start at position 0x207C0 seems to have an error inside. The image cannot be renedered because it is missing the 'end-of-data' RLE symbol. The last good RLE-symbol (red marked) is 0B 00, then it heads over to image width and height without a terminal 00 00.
0x20DD0: 12 98 0B F7 03 01 12 99 0B F5 03 01 12 9B 0B 00 02 12 13 F0 03 00 02 12 12 9E 0B F0 12 08 0B 00 01 90 00 C6 01 90 00 00 30 02 07 CC 30 02 07 C0 00 00 56 38
I need to skip the image range from 0x207C0 to 0x20E03 to avoid my extraction tool from crash.
The same is true for image following at position 0x20E04. I skip this until 0x21757.
Maybe this broken picture is never shown... strange is'nt it? If the Convers would ever try to show this picture it would crash also.

With exception of those both images i could generate 509 pictures aus of the dump. Not all of them seem to be correct, they are unaligned so it seems width it false. Maybe i need some width-padding, must inspect this. Also got the images from the startup-animation.

But no Ford-Logo :?
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

I'm struggling with the image format, there are some strange exceptions. Beside of this there must be a mechanisme how the software access these pictures. There must be some kind of lookup-table (handles) where the software knows which image to place at what coordinate, or at least know where to load it's data. The processor is fast enough and also has limited RAM capabilities so i guess they are decompressed "on-the-fly". And in this LUT i expect there are pointers to the image-footer which tells the size and contains data- and drawingroutine pointer. The drawing routine pointer may to be able to use different methods for decompressing the image, even if they currently seems to use only RLE.

With such table it doe not make sense at all, and with it, there is no need for an End-Of-Image RLE-Symbol (like i though the "00 00" is), because of the width and height, the decompression routine knows when framedata is exhausted. Thus, the 00's we see are only padding-bytes, which may or may not be inserted, depending in the length of the image framedata (must fit into 4 byte boundary, this is for shure). This would also clearify why my extraction method often fails because it does not find an End-Of-Image-Symbol :-)

So, let's find this LUT !
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

I've found it! :)

It was not so hard to find. I hoped to find a pointer to the start address of one of the image footers (where the metadata is located) and so i picked one and looked for '30 00 12 AC'. I used the prefix '30' because inside the image metadata section this scheme is used and i assume that the running system addresses the data section in Flash from address 0x30000000 onwards. My search get two results and the later one seems correct. I then cross checked some more addresses i found there and all fits. So it's clear i've found the right section.

The image lookup table (LUT) in the ROM file starts at 0x6A9E4 (or maybe 0x6A9E0 when the index #0 is not used, because the address points to 00 00 00 00). There you find 4 byte pointers to the footer section of all used images. This sequence of 32 bit addresses is used like an array, where the index is stepped in 4 byte ranges, so each index# gives back a valid address.

From the given address the drawing routine determines the dimension (width and height) of the image and also where to load the pixeldata from (RLE encoded). It knows how much RLE symbols to load by the image dimension (= stream of pixels, wrapped at each 'width' count), so there is no need for a termination symbol. Therefore the last 00 bytes i've seen where only for padding the stream into a 32 bit alignment!

The image header, which consists of 3 words, each 32 bit long, also not a delimiter, because this where not needed. I guess they denote image type, compression-scheme and colortable to be used for drawing. We may find out by disassembling the drawing routine...
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

Ursadon wrote: 11 Mar 2019, 13:22 NXP MAC7116VAG50 - ARMv4T (ARM7TDMI) uC (1Mbyte)
Right, the MAC7116 is a member of the Freescale MAC7100 family. It has an ARM7 CPU, 32 Kb internal Flash memory.
ARM7TDMI-S is an ARM7-Family CPU with 32 and 16 bit (Thumb) instruction set ("ARMv4" architecture). It's running in Big Endian byteorder.
(BTW: "T" in the CPU descriptor means "Thumb", "D" means it is JTAG debuggable, "M" menas "fast multiplier" and "I" stands for ICE debugging. The ARM7 was released in 2001)

So, i've loaded the ROM into IDA and choose "ARM Big-endian" as CPU-Type. In the "process options/ARM Architecture" i choose "ARMv4" and leave all other options untouched. I assume that of the memory map of the MAC it's loaded at 0x0000 0000. Do you know the entrypoint of the software? Normally CPU's start executing at 0x0 :-)
It then shows me:

Code: Select all

ROM:00000000                 STCVCL  p5, c5, [R7], {0xAA}
ROM:00000004                 BGE     0x1571FCC
I think this is nonsense...
Go4IT
Pro
Posts: 967
Joined: 08 Feb 2019, 12:25

Re: Apply custom images to Ford Convers+

Post by Go4IT »

BINGO! My theory was right. Now i could extract ALL images without any issues (including the Ford-Logo) :D

Next is to find the colormap...
Post Reply