LCDGFX LCD display driver  1.2.0
Lightweight graphics library for SSD1306, SSD1325, SSD1327, SSD1331, SSD1351, SH1106, SH1107, IL9163, ST7735, ST7789, ILI9341, PCD8544 displays over I2C/SPI
docs/migration_v1_v2.md
1 # Migrating from the v1 API to the v2 API
2 
3 lcdgfx evolved from the older `ssd1306` library. The v2 API
4 (under `src/v2/`) is the preferred entry point — it is the only API
5 that supports colour displays (TFT, SSD1331, SSD1351), `NanoCanvas`
6 templates parameterised by colour depth, and the modern `NanoEngine`.
7 
8 This guide is a side-by-side cheatsheet for projects originally written
9 against the legacy v1 (`ssd1306.h` style) API, and for v1 patterns that
10 still appear in older examples.
11 
12 > **TL;DR**: Include `lcdgfx.h`, instantiate a `Display…` object, call
13 > `display.begin()`, and use member functions instead of free functions.
14 > Pixel coordinates and font handles are unchanged.
15 
16 ## Header includes
17 
18 | v1 (legacy) | v2 (current) |
19 |---|---|
20 | `#include "ssd1306.h"` | `#include "lcdgfx.h"` |
21 | `#include "nano_gfx.h"` | included transitively from `lcdgfx.h` |
22 | `#include "nano_engine.h"` | included transitively from `lcdgfx.h` |
23 | `#include "intf/i2c/ssd1306_i2c.h"` | not needed — bus selection is via the display class name |
24 | `#include "ssd1306_console.h"` | included transitively from `lcdgfx.h` |
25 | `#include "menu.h"` | `#include "lcdgfx_gui.h"` |
26 
27 ## Display construction
28 
29 | v1 (free functions, mutates global state) | v2 (member functions on a Display object) |
30 |---|---|
31 | `ssd1306_128x64_i2c_init();` | `DisplaySSD1306_128x64_I2C display(-1);` then `display.begin();` |
32 | `ssd1306_128x64_spi_init(rstPin, ces, dc);` | `DisplaySSD1306_128x64_SPI display(rstPin, {-1, ces, dc, 0, -1, -1});` then `display.begin();` |
33 | `il9163_128x128_spi_init(rst, ces, dc);` | `DisplayIL9163_128x128x16_SPI display(rst, {-1, ces, dc, 0, -1, -1});` |
34 | `ssd1331_96x64_spi_init(rst, ces, dc);` | `DisplaySSD1331_96x64x16_SPI display(rst, {-1, ces, dc, 0, -1, -1});` |
35 
36 The v2 display class name encodes the controller, resolution, and (for
37 colour controllers) the bit depth. See
38 [docs/controller_matrix.md](controller_matrix.md) for the full list.
39 
40 ## Drawing primitives
41 
42 All the pixel coordinates, colour conventions, and font handles are
43 identical between v1 and v2. The only change is that you call them on
44 the `display` object instead of as free functions.
45 
46 | v1 | v2 |
47 |---|---|
48 | `ssd1306_clearScreen()` | `display.clear()` |
49 | `ssd1306_fillScreen(0xFF)` | `display.fill(0xFF)` |
50 | `ssd1306_putPixel(x, y)` | `display.putPixel(x, y)` |
51 | `ssd1306_drawLine(x1, y1, x2, y2)` | `display.drawLine(x1, y1, x2, y2)` |
52 | `ssd1306_drawRect(x1, y1, x2, y2)` | `display.drawRect(x1, y1, x2, y2)` |
53 | `ssd1306_drawHLine(x1, y1, x2)` | `display.drawHLine(x1, y1, x2)` |
54 | `ssd1306_drawVLine(x1, y1, y2)` | `display.drawVLine(x1, y1, y2)` |
55 | `ssd1306_drawBitmap(x, y, w, h, bmp)` | `display.drawBitmap1(x, y, w, h, bmp)` (mono) |
56 | `ssd1306_drawXBitmap(x, y, w, h, bmp)` | `display.drawXBitmap(x, y, w, h, bmp)` |
57 | `ssd1306_setColor(c)` | `display.setColor(c)` |
58 | `ssd1306_negativeMode()` / `ssd1306_positiveMode()` | `display.invertColors()` / `display.normalColors()` (semantics preserved) |
59 
60 For colour displays, prefer the explicit-depth variants:
61 `drawBitmap1` (1 bpp), `drawBitmap4` (4 bpp), `drawBitmap8` (8 bpp),
62 `drawBitmap16` (16 bpp).
63 
64 ## Text rendering
65 
66 | v1 | v2 |
67 |---|---|
68 | `ssd1306_setFixedFont(ssd1306xled_font6x8)` | `display.setFixedFont(ssd1306xled_font6x8)` |
69 | `ssd1306_printFixed(0, 8, "hi", STYLE_NORMAL)` | `display.printFixed(0, 8, "hi", STYLE_NORMAL)` |
70 | `ssd1306_printFixedN(0, 8, "BIG", STYLE_NORMAL, FONT_SIZE_2X)` | `display.printFixedN(0, 8, "BIG", STYLE_NORMAL, FONT_SIZE_2X)` |
71 | `ssd1306_setFont6x8(...)` *(deprecated even in v1)* | use `setFixedFont` with a 6x8 font handle |
72 
73 Font binaries themselves (`ssd1306xled_font6x8`, `digital_font5x7`,
74 etc.) are unchanged. The only runtime difference is that v2 stores the
75 active font on the `display` object rather than as a global.
76 
77 ## Display modes / control
78 
79 | v1 | v2 |
80 |---|---|
81 | `ssd1306_displayOff()` / `ssd1306_displayOn()` | `display.getInterface().displayOff()` / `displayOn()` *(controller-dependent — see capability matrix)* |
82 | `ssd1306_setContrast(level)` | `display.getInterface().setContrast(level)` |
83 | `ssd1306_flipHorizontal(1)` / `ssd1306_flipVertical(1)` | `display.getInterface().flipHorizontal(1)` / `flipVertical(1)` |
84 | `ssd1306_setStartLine(n)` | `display.getInterface().setStartLine(n)` *(mono OLEDs only)* |
85 
86 The `getInterface()` call returns a reference to the controller-specific
87 implementation, which exposes only the operations that controller
88 actually supports. See `docs/controller_matrix.md`.
89 
90 ## NanoCanvas (offscreen buffer)
91 
92 v2 introduces depth-parameterised canvases.
93 
94 | v1 | v2 |
95 |---|---|
96 | `NanoCanvas1 canvas(W, H, buf);` | `NanoCanvas<W,H,1> canvas;` (template) or `NanoCanvas1 canvas(W,H,buf)` (still available) |
97 | `NanoCanvas8 canvas(W, H, buf);` | `NanoCanvas<W,H,8> canvas;` |
98 | `ssd1306_drawCanvas(x, y, canvas);` | `display.drawCanvas(x, y, canvas);` |
99 
100 The template form sizes the buffer at compile time (no manual
101 `buf[W*H/8]` array), which is the recommended pattern for new code.
102 
103 ## NanoEngine (sprite / tile engine)
104 
105 v1's `NanoEngine` was tied to monochrome SSD1306. v2 generalises it
106 across all controllers.
107 
108 | v1 | v2 |
109 |---|---|
110 | `NanoEngine<TILE_8x8_MONO> engine;` | `NanoEngine1<DisplaySSD1306_128x64_I2C> engine(display);` |
111 | `engine.begin(); engine.refresh(); engine.display();` | identical method names |
112 | `engine.canvas.drawRect(...)` | `engine.canvas.drawRect(...)` (canvas type matches the display) |
113 | `engine.insertSprite(x, y, w, h, bmp);` | identical signature |
114 
115 The integer suffix on the engine class (`NanoEngine1`, `NanoEngine8`,
116 `NanoEngine16`) selects the colour depth.
117 
118 ## Menu / GUI widgets
119 
120 | v1 (`menu.h`) | v2 (`lcdgfx_gui.h`) |
121 |---|---|
122 | `SAppMenu menu; ssd1306_createMenu(&menu, items, count);` | `LcdGfxMenu menu(items, count);` |
123 | `ssd1306_showMenu(&menu);` | `menu.show(display);` |
124 | `ssd1306_menuDown(&menu);` | `menu.down();` |
125 | `ssd1306_menuUp(&menu);` | `menu.up();` |
126 | `ssd1306_menuSelection(&menu);` | `menu.selection();` |
127 
128 v2 additionally ships `LcdGfxCheckboxMenu`, `LcdGfxButton`, and
129 `LcdGfxYesNo` — see `examples/gui/`.
130 
131 ## Common pitfalls
132 
133 - **Two displays in one sketch.** v1's free-function API made this
134  impossible. v2 supports it — just instantiate two display objects.
135 - **Forgetting `display.begin()`.** v1's `*_init()` did this implicitly
136  on first call; v2 requires an explicit `begin()`.
137 - **Mixing v1 and v2 headers.** Don't include both `ssd1306.h` and
138  `lcdgfx.h` in the same translation unit. Pick one.
139 - **Colour displays and `setColor`.** The `RGB_COLOR8` and
140  `RGB_COLOR16` macros (and, soon, the `Color` helper in
141  `src/canvas/color.h`) are the supported ways to compose values for
142  `setColor()` on colour controllers.
143 - **Rotation.** v1 had software rotation only. v2 colour displays use
144  hardware rotation via `setRotation(0..3)`. See the capability matrix
145  for which controllers support which.
146 
147 ## Where to look next
148 
149 - `examples/` — every example in the repo uses the v2 API.
150 - [docs/controller_matrix.md](controller_matrix.md) — per-controller
151  feature support.
152 - `src/lcdgfx.h` and `src/lcdgfx_gui.h` — top-level entry headers.
153 - `src/v2/` — implementation. Note that `src/v2/lcd/<controller>/` is
154  auto-generated; edit templates in `tools/templates/lcd/<controller>/`
155  and re-run the code generator.