Wednesday, November 19, 2014

Reverse Engineer HP 3550 LCD protocol

Well I hate to see things go to land fill so i pull usable bits from all sorts of electronic devices as well as dabble in a bit of scrap metal.
Anyway , i pulled a HP 3550 colour printer apart thinking it would contain yet another HD447800 text based LCD in it.  Hmmm.. Na.. its a 28 pin graphic lcd ( GLCD) .



There are 3 LEDs and 7 push button switches. There is one chip, a BU6740AK . A web search shows no one has much if any data on it.
But there is a WordPress blogger called Kbiva that has done a few HP printer displays before that use this chip.  Power , Ground, and 3 SPI pins sounds easy.. lets see what my new Bus Pirate tells me.
Hmm.. not much... I think i worked out what pins are what but the BP can only work up to about 1 meg. The 3550 LCD SPI looks to be faster than 1 meg. I was getting malformed SPI data.
So i ordered an 8 Chanel 24 meg Ebay Logic analyzer for under $10.
[ Insert a 10 day wait and stalking the mailbox HERE]
After 2 days of getting the new LA and playing with the Saleae software, i was ready to sus out what pins do what on the 3550 LCD.
I'll add the pinout here in a day ot two.
The SPI is running at just over 1 Mbps.

Below are the settings i found that worked for me. They are not the same as Kbiva used.



I did not get a screen shot of live data in the LA software but i'm sure you can search for examples if needed.

I captured several power up initializations as well as one with each of the buttons pushed down , and three that cover enough combinations of LEDs to know which is which.
I decided to export the LA data to CSV files that allows me to sort and colour the data to work out what bits do what. The below Dump1 may look messy, but it contains a lot of info...
The yellow bars across these extracts shown where i have cut out repetitive data.
I can see no LCD initialization section. For now i will assume there is a basic one to clear the screen and setup biases and basic register settings between the chip and the LCD.


Dunp 1 - Init Codes

0xA000 may be a reset out to the board.
0x0000 looks to be a clear buffer flush. Its used between raster , changing LEDs and sometimes before starting a new raster update of the LCD.
0x30xx (Green numbers)  look to be LCD command selection.
0x70XX is outgoing data to the LCD or to an LCD command.
0x0800 looks to be a request for the controller status OR what switch has been released.
0x0900 looks to be a request for what switch has been pressed.
0x90X0 is used to turn on and off the LEDs.

A one off Initialization of sending 0xA000 and 0x0000 is then followed by a loop that waits until sending 0x0800 returns something other than 0x4001. ( Green block 0)
I think sending a 0x3004 , 0x7003 may be Clear Screen. (Violet block 1)
Next ( Blue block 2) looks to be setting the address to top left. The 0x70C0 is always the same but the 0x70XX after the 0x3004 increments from 0x00 through to 0x13 ( 20dec) as the columns are addressed.
The pixel data is fed in until the last lower right byte is sent ( Pink block 3)

Then starts a whole new screen update from top left again, but this time and then for all new screen updates we have the added config starting with 0x3002.

Each of the 0x70XX following a 0x30XX shown in the two Dumps here are the same in all my dumps with the exception of the data following the 0x3004 ( addressing) and 0x3007 ( i think is either here comes pixel data or Auto increment address with data).

I knew i was in the ball park when i spotted the binary in lines 1755 to 1760 in the above image.
A little ASCII art shows i have an Asterisk that matches the ones on the LCD at the time while the printer is initializing. Further trawling through the spread sheet found the memory test digits and "MB" characters that also told me i had the bits the correct way around. 


The LCD turns out to be 32 x 160 pixels ( 32 rows of 20x8bits ).
With the way the data is sent from SPI to the LCD  and the yet to be found initialisation settings, the byte pixel data is top left to bottom right.


Dump2 - LEDs and Switches

Switches look to be read between screen updates or every 0.1 seconds.
LED updates or toggles are on 0.250 sec ticks.

Sw11= 11101111 OFF 0x9000 00000000
Sw12= 11110111 LED1 0x9010 00010000
Sw13= 11111011 LED2 0x9020 00100000
Sw14= 11111101 LED3 0x9040 01000000
Sw15= 11111110
Sw16= 01111111
Sw17=  10111111


I have not been able to find any GLCD controller chips with commands and registers with numbers like the ones in the right two digits of the 0x30XX and 0x70XX in the dumps.

I have enough to connect an Arduino up to replicate the above method of putting data on the LCD. I would like to find that the controller can also do character mode.


I connected the 8 channel LA to the 8 data pins on the LCD display its self.  The data is exactly the same as the last byte of the data sent via the SPI bus. I sort of thought they may have been interpreted and sent to the LCD is a string of raw commands, but no.
The data to the LCD its self is clocked in 8 bits wide at about 30 uS 

I hope someone can tell me what controller this display looks to be running.

7 comments:

  1. Hi can you tell what pibout on this board please

    ReplyDelete
    Replies
    1. Arvo Eis , sorry i thought i had ...i will look at my notes tonight and put them up.

      ta,

      Delete
  2. ...still looking for my note book.. I may have to reconnect the BP if i cant find it <:-(

    ReplyDelete
  3. Ok. Thank you for your answer. I'll wait its not urgent.

    ReplyDelete
  4. Ok. Thank you for your answer. I'll wait its not urgent.

    ReplyDelete
  5. Hi Zukjeff, I have the same board. Since there is no enough information available about this, I've taken a step forward and I've reverse enginered the protocol. You have some kind of error in your dump, or at least my version doesn't have the same bytes. (which is weird, since the answers 0x4001 are the same in my case).
    MSB goes out first, SPI mode is 0, and transfers are 16 bits wide.

    Here is the init and an example:
    /* Array contains the data to send (16 bits) and the delay in usec that you should wait between SPI transfers */
    0xF000, 148,
    0xF000, 26,
    0xF30A, 6500,
    0xA000, 6500,
    0x2002, 180,
    0x60C4, 180,
    0x2003, 180,
    0x600B, 180,
    0x200C, 180,
    0x6098, 180,
    0x2000, 180,
    0x6007, 180,
    0x2006, 180,
    0x6023, 180

    And a example (which should write the number 0 in the top left corner of the screen):
    0x2001, 180, /* unknown, step 1 */
    0x6003, 180, /* unknown, step 2 */
    0x2004, 180, /* unknown, step 3 */
    0x6000, 180, /* after sending the previous 3 bytes, 0x60XX carries the column address in its lower byte (XX), in this case its 0 */
    0x60C0, 180, /* unknown, step 4 */
    0x2007, 180, /* unknown, step 5 */
    0x6000, 180, /* raw data (contained in the lowest byte) */
    0x6000, 180,
    0x6000, 180,
    0x6018, 180,
    0x6024, 180,
    0x6046, 180,
    0x604A, 180,
    0x604A, 180,
    0x6052, 180,
    0x6052, 180,
    0x6062, 180,
    0x6024, 180,
    0x6018, 180,
    0x6000, 180,
    0x6000, 180,
    0x6000, 180 /* only 16 rows are written. there are 32 available! */

    Pinout:
    J3 (in the GLCD board): (to align this, check for continuity of GND and Vcc in the capacitor C2)
    1: GND
    2: Vcc 3.3V
    3: MISO (data out from the BU6740AK)
    4: MOSI (data in to the BU6740AK)
    5: SCK (clock in)
    6: /CS
    Note: Those pins have a pull up in the board, and they are 3.3v only! If you're using a 5V SPI device to drive this, put a 1k resistor in series with those pins that are outputs from your device (CS, SCK, MOSI).

    The screen seems to be divided in 20 columns, each one has 8 pixels. When you start feeding data, the first byte corresponds to the row 0 of the screen, and it auto increments until the bottom of the screen.

    Maybe I'll upload an arduino sketch to drive this display.

    If you need help, please contact me via mail!

    Cheers!

    ReplyDelete
  6. This blog is really helpful to deliver updated educational affairs over internet which is really appraisable. I found one successful example of this truth through this blog. I am going to use such information now. stone display solution

    ReplyDelete