I've been looking at various components of a broken FormLabs Form 1+ laser resin 3D printer, right now the focus is its front panel dot matrix OLED display. My first attempt at using a logic analyzer on its control signals told me which wires were active, but the actual data were gibberish. Fortunately, a second attempt retrieved sensical data waveforms. Someone on the FormLabs forums speculated this was an OLED display built around a SSD1305 controller, so now I will see if my captured data matches commands listed in SSD1305 documentation.

This stream of data represents system powerup, a set of commands (channel 0 white line is low) sent just before the first batch of data (channel 1 white line is high). If I interpret these bytes in context of SSD1305 datasheet, I get the following:

  • 0xAE: Display OFF.
  • 0xD5 0x10: Set display clock divide ratio to 1:1 and oscillator frequency to 300kHz.
  • 0xA8 0x1F: Set multiplex ratio to 31. (0x1F)
  • 0xD3 0x00: Set display offset to zero.
  • 0x40: Set display start line to zero.
  • 0xAD: Master Configuration for external Vcc power supply.
  • 0x8E: ???
  • 0x20 0x02: Set memory addressing mode to 0x02 (Page Addressing Mode.)
  • 0xA0: Set segment remap to 0 (Column address 0 is SEG0)
  • 0xC8: Set COM output scan direction to 1 (Remapped mode. Scan from COM[N~1] to COM0)
  • 0xDA 0x12: Set COM pins hardware configuration. (Disable COM Left/Right remap, Alternative COM pin configuration.)
  • 0x91 0x3F 0x3F 0x3F 0x3F: Set current drive pulse width of BANK0, color A, B, and C all to maximum valid value of 0x3F (63 clocks).
  • 0x81 0xFF: Set contrast control for BANK0 to 0xFF. (256, which is maximum contrast.)
  • 0x82 0xFF: Set brightness for area color banks to 0xFF. (256, which is maximum brightness.)
  • 0xD9 0xD2: Set precharge period to 0xD2. (Phase 1 period of 0x2 clocks, phase 2 period of 0xD or 13)
  • 0xDB 0x08: Set VCOMH Deselect Level to 0x08, but 0x08 is not in the list of valid values?
  • 0xA4: Entire display ON to display RAM content.
  • 0xA6: Set Normal Display. (Instead of 0xA7 for Inverted.)

This looks like an entirely sensible chain of commands for initial startup, aside from the two gaps: command 0x8E and parameter 0x08 for command 0xDB. The datasheet I have is rev 1.9 dated May 2008, so it's possible those commands were added later. Even though they didn't quite line up with the datasheet, these matches are too close to have been a coincidence. I'm now convinced there is a SSD1305 (or very closely related derivative) controller inside this OLED module.

Three more commands round out the end of the startup sequence:

  • 0xB0: Set Page Start Address to 0.
  • 0x00: Set Lower Column Start address to 0.
  • 0x10: Set Higher Column Start address to 0.

After these are sent, the Command/Data line was raised signifying data transmission. A large number of zeros followed, then the C/D line was lowered in for another trio of commands:

  • 0xB1: Set Page Start Address to 1.
  • 0x00: Set Lower Column Start address to 0.
  • 0x10: Set Higher Column Start address to 0.

Followed by another large chunk of zeroes, and this repeated for all eight pages of memory. Documentation section 8.7 Graphic Display Data RAM (GDDRAM) gave a size of 132 x 64 bits divided into eight pages. By that math, there should be 132 bytes in each block of zeros, but I'm not going to count that by hand. There's probably a way to count inside Saleae Logic software, but I went with a low-tech approach:

  1. Zoom into the trace so one large block of zeros span majority of my computer monitor.
  2. Using a ruler, I measured the physical width on screen of the first eight decoded bytes of 0x00: they are 33mm wide.
  3. 132 bytes / 8 bytes = 16. So if there are 132 bytes in the block of zeros, they should be (16 * 33mm =) 528mm wide.
  4. I measured the entire block, 525mm wide. Close enough!

Having learned this information about initial startup including clearing the screen memory, I can better interpret the data captured by the logic analyzer during my other test activities.