1
\$\begingroup\$

I've recently ported a driver for the ssd1306 OLED controller. https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf http://www.ebay.co.uk/itm/0-96-inch-128x64-I2C-Interface-White-Color-OLED-Display-Module-for-Arduino-/382142082022

When writing to it, the 128x64 screen is arranged as eight horizontal sections of vertical bytes.

0 LSB
1
2
4
5
6
7 MSB

i.e. the top row shows the least significant bits, which the eighth row shows the most significant bits.

Each of the eight horizontal sections contain 128 bytes, which run from left to right. So the whole screen is addressed as:

  0    1 ...  127
128  129 ...  255
...
896  897 ... 1023

Even if your turn the screen 90 degrees, the arrangement makes no sense. (It's then 8 columns of bytes, but mapped top-to-bottom and then right-to-left.)

What reasons might have made this mapping of memory to display a good idea?

Update: One page 35 there is a "vertical addressing mode" which looks like a simple right-to-left raster, if you rotate the screen by 90 degrees.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ I am not sure what you want, look into the decision makers heads? \$\endgroup\$
    – PlasmaHH
    Commented Jul 12, 2017 at 7:56
  • 1
    \$\begingroup\$ @PlasmaHH No, I'm, looking for reasons which may be obvious to electronics professionals and hobbyists, but not to me. e.g. Perhaps OLEDs are physically wired in horizontal sections of eight lines? Or perhaps OLED widths can be non-multiples of 8, while heights are always multiples of 8? \$\endgroup\$
    – fadedbee
    Commented Jul 12, 2017 at 8:02
  • 2
    \$\begingroup\$ Given that most architectures have bytes of 8 bit, it makes sense to use that. Also, starting at one corner and then scanlining into the other makes sense too. Maybe you can explain why you think that arrangement makes no sense and which one would be superior to it? \$\endgroup\$
    – PlasmaHH
    Commented Jul 12, 2017 at 8:36
  • \$\begingroup\$ I didn't mean to query eight-bit bytes. Usually monochrome rasters are horizontal bits in horizontal bytes, or vertical bits in vertical bytes. This is vertical bits in horizontal bytes, which I hadn't seen before. The design makes no sense to me, yet. I'm sure that the designers had good reasons and those are what I'm interested in learning. \$\endgroup\$
    – fadedbee
    Commented Jul 12, 2017 at 9:08
  • 1
    \$\begingroup\$ Because you can drive the display matrix from the memory without needing a shift register? \$\endgroup\$
    – Finbarr
    Commented Jul 12, 2017 at 9:09

2 Answers 2

4
\$\begingroup\$

What reasons might have made this mapping of memory to display a good idea?

This layout makes it extremely easy to display 8 lines of text on the display -- an 8-pixel-high character font can be stored as a sequence of 8-bit values to be written to the display. This display mode has the advantage of making it easy to draw text at any horizontal position, allowing for the easy use of variable-width fonts. (A layout which treated each byte as eight horizontal pixels would require bit-shifting and masking operations to draw text at horizontal positions not divisible by 8.)

The main disadvantage of this layout is that it makes it difficult to draw text or graphics at arbitrary vertical positions. However, this is an acceptable limitation for many applications.

\$\endgroup\$
6
  • \$\begingroup\$ I've worked with displays oriented this way, generating displays with text at arbitrary horizontal and vertical positions. On an 8-bit processor which has a "rotate byte in memory through carry" instruction, using a 16-pixel-high buffer can be very efficient, without requiring that one have enough memory to hold an entire display. \$\endgroup\$
    – supercat
    Commented Oct 19, 2018 at 20:05
  • \$\begingroup\$ @supercat Writing text to unaligned vertical positions without a full redraw still requires some way to read data out of the framebuffer, though. Many small displays are write-only, so that isn't an option. \$\endgroup\$
    – user39382
    Commented Oct 19, 2018 at 20:13
  • \$\begingroup\$ My approach redraws the entire screen, but does so very quickly. Starting with the buffer clear, I "or" onto the bottom 8 pixels of the buffer everything that should appear in rows 0-7 of the screen, shift the buffer one bit, "or" (unshifted) everything that should appear in rows 1-8, then shift, etc. until I've shifted 8 times. Then I copy the top 8 pixels of the buffer to the screen, then "or' on the contents of rows 8-16, shift, 9-17, shift, etc. \$\endgroup\$
    – supercat
    Commented Oct 19, 2018 at 21:01
  • \$\begingroup\$ The shift instructions can be in a partially-unrolled loop, so they're very fast. Since the act of "or"'ing data onto the display doesn't require shifting, it too can be very fast. \$\endgroup\$
    – supercat
    Commented Oct 19, 2018 at 21:02
  • \$\begingroup\$ @supercat Right, that works if your application is structured to support a single "draw everything" pass. In some applications, that might not be an option -- information might be drawn to the display without being stored in memory. \$\endgroup\$
    – user39382
    Commented Oct 19, 2018 at 21:18
1
\$\begingroup\$

This type of display memory layout is actually more common on small display controllers than you might think. In all the different LCD / OLED graphics display controllers that I have programmed to over the years this layout is the most common. Horizontal byte layouts exist for sure but are less common.

The display controller designer works out the architecture of the controller memory in a manner that makes accessing the memory for display refresh as simple as possible to keep down the chip size and cost.

A properly designed display driver will have the MCU software draw the screen image into a memory buffer of the MCU so that read/write access to support merging in content is as high of performance as possible. Then the driver is designed to support a fast copy of the memory buffer to the display controller. This copy can then take advantage of auto address increment features of the controller to get the data loaded as fast as possible which can lead to nice snappy screen content updates. If you try to make a display driver without a memory buffer that wants to do read/modify/write accesses to the display controller expect the average screen update process to be three to five times slower.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.