johnbutol / ICM-Teensy

Apache License 2.0
14 stars 1 forks source link

More detail description #1

Open RiLights opened 5 years ago

RiLights commented 5 years ago

Hi,

I'm really interested in this project. That is really cool!

Can you please describe more detail about the connection to Arduino? What the responsibility of Pi Zero? Do you have a road map what you want to do?

Cheers Ostap

johnbutol commented 5 years ago

Yes, changes are coming. It was just a proof of concept with parts I had laying around. Final goal is to keep as low as parts and code possible. Any idea is appreciated. I know this screen has been used on other Volvo models apart from P1 platform and in some Aston Martins too. So it should interest more people.

RiLights commented 5 years ago

Cool! I have a Volvo C30 and I really would like to join to this developing. Just let me know, please your road map to take a look on the better world ; )

endlessmind commented 5 years ago

I'm working on a project that needs this. I see that you are looking for 0xE3, 0x40, 0x40 to find the start of a frame on 2004 models and up (to 2012?), but when I run raw pin data from a 2006 V50 it cannot find any frames.

The loop that "remove 3 bytes every 128 bytes" is overflowing. i+j+3 is the issue, when j = 2093 it overflows.

Can you explain what you are doing in the loop with the bitwise operation? bmpData[i] |= (((newDataIsr[pixelStart + pixelXOffset] & (0x80 >> pixelYOffset)) >> ((COLUMN_SIZE_8 - 1) - pixelYOffset)) << ((COLUMN_SIZE_8 - 1) - j));

Also, there is a lot of "magic" in the bmpDataBuild functions (1st pass -> 5th pass) that I have no idea what is going on here.

My goal is to run this backward, so take a 256x64 monochrome bitmap and create a buffer than I can then send to the displays data-pins. So I need to understand what you are doing to create the bmp from the data.

If you want, you can get the sample data that I used (recorded with a logic analyzer). I've written a C# application to render the data like you do (for testing) and has been able to insert own text into the buffer (without any image or bitmap frameworks). But If I can't even find frames on the older models of the car then that wont help me at all.

johnbutol commented 5 years ago

Magic values

First, raw data from an used 2012 ICM was recorded with a logic analyzer. I got this output: https://docs.google.com/spreadsheets/d/1-d3a6DjBSePXNDZvgL5lJTeI4-Da14dF7wiOh2XfGTM/edit?usp=sharing Each line is one byte on the parallel data bus, represented in binary to kind of mimic pixels on a screen.

First hundreds of lines are like static TV noise (maybe data but i doubt). image

Then around line 500, static stops, the show begins: image

You can find the magic values in yellow, simple.

Pixels alignment

Data is sent from left to right, with each byte representing a column of 8 pixels LSB to MSB for top to bottom. image

When a screen line is completed (256 pixels), it goes on the next line, and so on.

The loop

Loop convert the pixel alignment of the display explained above to the pixel alignment defined by bitmap standard (full uncompressed 1 bit BMP). BMP data is then sent by serial connection to any computer (here a PI Zero) able to write BMP data to actual BMP file and voilà.

First results

It was a long process to make it work: From image Oh! looks like there is a fan icon on the bottom then image Less TV noise then image Fixed horizontal syncing then image Aligned the clock, but lost horizontal syncing Eventually, I got this image And finally image NOooo, last effort to remove these lost pixels image DONE. Bonus: image

ICM 2004.5

At this point it looks like the code is ready to be tested on my car. ICM modules from this period are different and have two flat flex cables instead of one on newer models. The pinout is on the wiki page. First results: image Hmmm, something is wrong, after having hooked back up the logic analyzer again, the frame start values have changed between older and newer ICM. image What is going on ? Some menu elements are visible but nothing is aligned. Worse, elements which used to be on the top right are now on the bottom left, but readable nonetheless. It looks like screen is splitted in sections. And these sections seems to be all separated with a 3 byte value. I need more code. Removing 3 bytes every 128 bytes (thanks for the overflow bug!, although it has no effect !?): image I cut the screen area in 16 sections, each one with its position id to build a correct image again. image Then 1st pass image to 3-4th pass image I have no image for 5th pass but you get the idea.

Code has been written in this order so this is why reading it leads to understandable confusion.

For your project you need to reverse the loop. Have fun.

endlessmind commented 5 years ago

Thanks for the detailed response. I can't find the start of the frame as you suggest, so i'm just filling my ring-buffer (newDataIsr in your code) and runs everything through the decoding function and then renders it.

This is the best I have come up with: b202e4aabc2bce26f66d2fea13a5fe74

I've tried reversing the bitorder and anything obvious I can think of.

I "fixed" the overflow bu changing the inner loops limit to 2048 from 2096, might this be what's causing the issue?

In C# .Net I can't run the code exactly as you've written it because I get runtime exception on the overflow on the first run of the code.

johnbutol commented 5 years ago

Buffer went from 2048 to 2096 only to support older ICM, I don't know when Volvo switched to newer ones, so maybe in your case you don't need this extra code. Try to make it work without. In your output file I think I read MENU maybe with horizontal syncing issue. Try a file with bigger printed text (like the one with the car and PERFORMANCE SOUND), maybe at decoding it will help to better understand where the process failed

endlessmind commented 5 years ago

Sorry for been a pain in the butt.

After re-exporting the data from the logic analyzer i manage to get these images (using 2096 buffert, but very similar when using 2048)

56ddd3128be788ec4a91d543cae5316f 619eaba5421895b82ced108ca6654c2a

The noise in the first picture looks similar to one of the pictures you posted. Might this just be a question if finding the start of the frame at this point and it will all be fixed?

endlessmind commented 5 years ago

Here is the data I've been running, if it helps. binary.zip

Current result (have not found start bytes yet) 28f201c28e33430c02ebe432c9f2f123

endlessmind commented 5 years ago

I manage to get to this state by making an software interrupt to remove noise data :-)

icm-2019-06-03_15_50_08

johnbutol commented 5 years ago

what kind of hardware do you use ?

endlessmind commented 5 years ago

The data was captured with a Saleae Logic analyzer. Captured D0-7, clk and 2 other pin that might be cs and/or r/w. The data I sent you was an export of D0-7.

I re-exported it with clk and the 2 other pins. I did not know which where clk, but I saw that you had the interrupt set to falling. So I only added data to the buffert if a line was low. I switched between what line I was checking until the frame was rendered complete.

The data is from a polish V50 2006 that a friend captured for me as I only have access to a 8 channel logic analyzer at the moment.

I managed to also render the stand-by screen, there was 2 issues with that. The lines under the temp was one complete line, this was due to the overflow bugg i mentioned. (My renderer can scale up the image, there it scaled up 300%) icm-2019-07-03_01_53_36

So, earlier I 'fix' the overflow bugg by setting the limit of the inner loop to 2048 instead of 2096: for (j = 0; j < (PIXEL_DATA_SIZE_2048 - i); j++) This cased the above image, but at least the program didn't crash.

This time I fixed it, at least better, by just reducing the loop limit by 3 to compensate for the "+3" for (j = 0; j < (PIXEL_DATA_SIZE_2096 - i -3); j++) That resulted in this: icm-2019-06-03_17_08_03

Second issue. Section 16 in your drawing is a bit jerky when rendering all frames in the captured data (33 frames) It moves 1 or 2 pixels on some frames, but this might be due to some bad connections on the logic analyzer, this is not present on the capture that has menu-frames.

endlessmind commented 5 years ago

Sorry to bother you again, but I need some help with the last bit of this project.

I've manage to write stand-alone code that can alter the pixels at high speed (running on an ARM @ 217Mhz takes about 3-4ms to clear all and then insert own data), last step is to convert it back to data I can send out to the display.

You are more familiar with the format than me, would you be able to help me with this?

My test would be: signal data ->convert to bmp -> convert back to signal data -> convert to bmp and display.

If the image look like it did first time it was converted from signal data to bmp, then it should work sending it to the lcd. Then I just need to figure out timings and some commands to the display, but that will not be to hard.

Would you be able to help me?

JakesFate commented 5 years ago

Sorry to bother you again, but I need some help with the last bit of this project.

I've manage to write stand-alone code that can alter the pixels at high speed (running on an ARM @ 217Mhz takes about 3-4ms to clear all and then insert own data), last step is to convert it back to data I can send out to the display.

You are more familiar with the format than me, would you be able to help me with this?

My test would be: signal data ->convert to bmp -> convert back to signal data -> convert to bmp and display.

If the image look like it did first time it was converted from signal data to bmp, then it should work sending it to the lcd. Then I just need to figure out timings and some commands to the display, but that will not be to hard.

Would you be able to help me?

I'm curious You are able to display on the oem display or just clear what it is displaying?

endlessmind commented 2 years ago

Sorry, i did not get notified that you had answered. No, i just wanted to display in on my computer as a test. I never managed to find a way to control that OEM screen :(