1

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.

fadedbee
  • 994
  • 9
  • 24
  • 1
    I am not sure what you want, look into the decision makers heads? – PlasmaHH Jul 12 '17 at 07:56
  • 1
    @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? – fadedbee Jul 12 '17 at 08:02
  • 2
    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? – PlasmaHH Jul 12 '17 at 08:36
  • 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. – fadedbee Jul 12 '17 at 09:08
  • 1
    Because you can drive the display matrix from the memory without needing a shift register? – Finbarr Jul 12 '17 at 09:09
  • You can map a display left to right and bottom to top, but this is not the only way to do it. Another way is left to right and top to bottom and this is used here and for PC display too. It is no bad idea at all, it is a regular order and not scrambled in any way. – Uwe Jul 12 '17 at 09:30
  • @Uwe My question relates to the fact that the bits in a byte are used on different lines, rather than being different columns. The first line on this display is the LSB of the first 128 bytes, not the full first 32 bytes. – fadedbee Jul 12 '17 at 09:59
  • @chrisdew - For general graphics primitives the mapping of bits in bytes to rows or columns is immaterial. For painting fonts it is straight forward to build your font glyphs to match the way the display controller mapping. (i.e. vertical versus horizontal font glyph rastering. – Michael Karas Jul 12 '17 at 20:27

2 Answers2

4

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.

  • 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. – supercat Oct 19 '18 at 20:05
  • @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. –  Oct 19 '18 at 20:13
  • 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. – supercat Oct 19 '18 at 21:01
  • 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. – supercat Oct 19 '18 at 21:02
  • @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. –  Oct 19 '18 at 21:18
  • The approach I describe requires that divisions between separately-updated parts of the screen coincide with 8-pixel boundaries, but allows objects to be freely positioned within any "update region". It's necessary to have information in a form that can be quickly rendered, it doesn't all have to be in memory. When storing a list of strings stored in flash, for example, my code reads strings from flash within the update loop. – supercat Oct 19 '18 at 21:23
1

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.

Michael Karas
  • 56,889
  • 3
  • 70
  • 138