qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

oled_driver.md (26524B)


      1 # OLED Driver
      2 
      3 ## Supported Hardware
      4 
      5 OLED modules using SSD1306, SH1106 or SH1107 driver ICs, communicating over I2C or SPI.
      6 Tested combinations:
      7 
      8 |IC       |Size   |Platform|Notes                   |
      9 |---------|-------|--------|------------------------|
     10 |SSD1306  |128x32 |AVR     |Primary support         |
     11 |SSD1306  |128x64 |AVR     |Verified working        |
     12 |SSD1306  |128x32 |Arm     |                        |
     13 |SSD1306  |128x64 |Arm     |Verified working        |
     14 |SH1106   |128x64 |AVR     |No scrolling            |
     15 |SH1107   |64x128 |AVR     |No scrolling            |
     16 |SH1107   |64x128 |Arm     |No scrolling            |
     17 |SH1107   |128x128|Arm     |No scrolling            |
     18 
     19 Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
     20 
     21 ## Usage
     22 
     23 To enable the OLED feature, there are two steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
     24 
     25 ```make
     26 OLED_ENABLE = yes
     27 ```
     28 
     29 ## OLED type
     30 
     31 |OLED Driver        |Supported Device                    |
     32 |-------------------|------------------------------------|
     33 |`ssd1306` (default)|For both SSD1306, SH1106, and SH1107|
     34 
     35 e.g.
     36 ```make
     37 OLED_DRIVER = ssd1306
     38 ```
     39 
     40 |OLED Transport |                                                |
     41 |---------------|------------------------------------------------|
     42 |`i2c` (default)| Uses I2C for communication with the OLED panel |
     43 |`spi`          | Uses SPI for communication with the OLED panel |
     44 
     45 e.g.
     46 ```make
     47 OLED_TRANSPORT = i2c
     48 ```
     49 
     50 Then in your `keymap.c` file, implement the OLED task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`:
     51 
     52 ```c
     53 #ifdef OLED_ENABLE
     54 bool oled_task_user(void) {
     55     // Host Keyboard Layer Status
     56     oled_write_P(PSTR("Layer: "), false);
     57 
     58     switch (get_highest_layer(layer_state)) {
     59         case _QWERTY:
     60             oled_write_P(PSTR("Default\n"), false);
     61             break;
     62         case _FN:
     63             oled_write_P(PSTR("FN\n"), false);
     64             break;
     65         case _ADJ:
     66             oled_write_P(PSTR("ADJ\n"), false);
     67             break;
     68         default:
     69             // Or use the write_ln shortcut over adding '\n' to the end of your string
     70             oled_write_ln_P(PSTR("Undefined"), false);
     71     }
     72 
     73     // Host Keyboard LED Status
     74     led_t led_state = host_keyboard_led_state();
     75     oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR("    "), false);
     76     oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR("    "), false);
     77     oled_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR("    "), false);
     78     
     79     return false;
     80 }
     81 #endif
     82 ```
     83 
     84 ## Logo Example
     85 
     86 In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the OLED screen, use the following code example:
     87 
     88 ```c
     89 static void render_logo(void) {
     90     static const char PROGMEM qmk_logo[] = {
     91         0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94,
     92         0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4,
     93         0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00
     94     };
     95 
     96     oled_write_P(qmk_logo, false);
     97 }
     98 
     99 bool oled_task_user(void) {
    100     render_logo();
    101     return false;
    102 }
    103 ```
    104 
    105 ::: tip
    106 The default font file is located at `drivers/oled/glcdfont.c` and its location can be overwritten with the `OLED_FONT_H` configuration option. Font file content can be edited with external tools such as [Helix Font Editor](https://helixfonteditor.netlify.app/) and [Logo Editor](https://joric.github.io/qle/).
    107 :::
    108 
    109 ## Buffer Read Example
    110 For some purposes, you may need to read the current state of the OLED display
    111 buffer. The `oled_read_raw` function can be used to safely read bytes from the
    112 buffer.
    113 
    114 In this example, calling `fade_display` in the `oled_task_user` function will
    115 slowly fade away whatever is on the screen by turning random pixels black over
    116 time.
    117 ```c
    118 //Setup some mask which can be or'd with bytes to turn off pixels
    119 const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254};
    120 
    121 static void fade_display(void) {
    122     //Define the reader structure
    123     oled_buffer_reader_t reader;
    124     uint8_t buff_char;
    125     if (random() % 30 == 0) {
    126         srand(timer_read());
    127         // Fetch a pointer for the buffer byte at index 0. The return structure
    128         // will have the pointer and the number of bytes remaining from this
    129         // index position if we want to perform a sequential read by
    130         // incrementing the buffer pointer
    131         reader = oled_read_raw(0);
    132         //Loop over the remaining buffer and erase pixels as we go
    133         for (uint16_t i = 0; i < reader.remaining_element_count; i++) {
    134             //Get the actual byte in the buffer by dereferencing the pointer
    135             buff_char = *reader.current_element;
    136             if (buff_char != 0) {
    137                 oled_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i);
    138             }
    139             //increment the pointer to fetch a new byte during the next loop
    140             reader.current_element++;
    141         }
    142     }
    143 }
    144 ```
    145 
    146 ## Other Examples
    147 
    148 In split keyboards, it is very common to have two OLED displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g:
    149 
    150 ```c
    151 #ifdef OLED_ENABLE
    152 oled_rotation_t oled_init_user(oled_rotation_t rotation) {
    153     if (!is_keyboard_master()) {
    154         return OLED_ROTATION_180;  // flips the display 180 degrees if offhand
    155     }
    156 
    157     return rotation;
    158 }
    159 
    160 bool oled_task_user(void) {
    161     if (is_keyboard_master()) {
    162         render_status();  // Renders the current keyboard state (layer, lock, caps, scroll, etc)
    163     } else {
    164         render_logo();  // Renders a static logo
    165         oled_scroll_left();  // Turns on scrolling
    166     }
    167     return false;
    168 }
    169 #endif
    170 ```
    171 
    172 Render a message before booting into bootloader mode.
    173 ```c
    174 void oled_render_boot(bool bootloader) {
    175     oled_clear();
    176     for (int i = 0; i < 16; i++) {
    177         oled_set_cursor(0, i);
    178         if (bootloader) {
    179             oled_write_P(PSTR("Awaiting New Firmware "), false);
    180         } else {
    181             oled_write_P(PSTR("Rebooting "), false);
    182         }
    183     }
    184 
    185     oled_render_dirty(true);
    186 }
    187 
    188 bool shutdown_user(bool jump_to_bootloader) {
    189     oled_render_boot(jump_to_bootloader);
    190 }
    191 
    192 ```
    193 
    194 ## Basic Configuration
    195 
    196 These configuration options should be placed in `config.h`. Example:
    197 ```c
    198 #define OLED_BRIGHTNESS 128
    199 ```
    200 
    201 |Define                     |Default                        |Description                                                                                                          |
    202 |---------------------------|-------------------------------|---------------------------------------------------------------------------------------------------------------------|
    203 |`OLED_BRIGHTNESS`          |`255`                          |The default brightness level of the OLED, from 0 to 255.                                                             |
    204 |`OLED_COLUMN_OFFSET`       |`0`                            |Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC.          |
    205 |`OLED_DISPLAY_CLOCK`       |`0x80`                         |Set the display clock divide ratio/oscillator frequency.                                                             |
    206 |`OLED_FONT_H`              |`"glcdfont.c"`                 |The font code file to use for custom fonts                                                                           |
    207 |`OLED_FONT_START`          |`0`                            |The starting character index for custom fonts                                                                        |
    208 |`OLED_FONT_END`            |`223`                          |The ending character index for custom fonts                                                                          |
    209 |`OLED_FONT_WIDTH`          |`6`                            |The font width                                                                                                       |
    210 |`OLED_FONT_HEIGHT`         |`8`                            |The font height (untested)                                                                                           |
    211 |`OLED_IC`                  |`OLED_IC_SSD1306`              |Set to `OLED_IC_SH1106` or `OLED_IC_SH1107` if the corresponding controller chip is used.                            |
    212 |`OLED_FADE_OUT`            |*Not defined*                  |Enables fade out animation. Use together with `OLED_TIMEOUT`.                                                        |
    213 |`OLED_FADE_OUT_INTERVAL`   |`0`                            |The speed of fade out animation, from 0 to 15. Larger values are slower.                                             |
    214 |`OLED_SCROLL_TIMEOUT`      |`0`                            |Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable.                |
    215 |`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined*                  |Scroll timeout direction is right when defined, left when undefined.                                                 |
    216 |`OLED_TIMEOUT`             |`60000`                        |Turns off the OLED screen after 60000ms of screen update inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
    217 |`OLED_UPDATE_INTERVAL`     |`0` (`50` for split keyboards) |Set the time interval for updating the OLED display in ms. This will improve the matrix scan rate.                   |
    218 |`OLED_UPDATE_PROCESS_LIMIT`|`1`                            |Set the number of dirty blocks to render per loop. Increasing may degrade performance.                               |
    219 
    220 ### I2C Configuration
    221 |Define                     |Default          |Description                                                                                                               |
    222 |---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------|
    223 |`OLED_DISPLAY_ADDRESS`     |`0x3C`           |The i2c address of the OLED Display                                                                                       |
    224 
    225 ### SPI Configuration
    226 
    227 |Define                     |Default          |Description                                                                                                               |
    228 |---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------|
    229 |`OLED_DC_PIN`              | Required        |The pin used for the DC connection of the OLED Display.                                                                   |
    230 |`OLED_CS_PIN`              | Required        |The pin used for the CS connection of the OLED Display.                                                                   |
    231 |`OLED_RST_PIN`             | *Not defined*   |The pin used for the RST connection of the OLED Display (may be left undefined if the RST pin is not connected).          |
    232 |`OLED_SPI_MODE`            |`3` (default)    |The SPI Mode for the OLED Display (not typically changed).                                                                |
    233 |`OLED_SPI_DIVISOR`         |`2` (default)    |The SPI Multiplier to use for the OLED Display.                                                                           |
    234 
    235 ## 128x64 & Custom sized OLED Displays
    236 
    237  The default display size for this feature is 128x32, and the defaults are set with that in mind.  However, there are a number of additional presets for common sizes that we have added.  You can define one of these values to use the presets.  If your display doesn't match one of these presets, you can define `OLED_DISPLAY_CUSTOM` to manually specify all of the values.
    238 
    239 |Define                |Default        |Description                                                                                                                            |
    240 |----------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------|
    241 |`OLED_DISPLAY_128X64` |*Not defined*  |Changes the display defines for use with 128x64 displays.                                                                              |
    242 |`OLED_DISPLAY_64X32`  |*Not defined*  |Changes the display defines for use with 64x32 displays.                                                                               |
    243 |`OLED_DISPLAY_64X48`  |*Not defined*  |Changes the display defines for use with 64x48 displays.                                                                               |
    244 |`OLED_DISPLAY_64X128` |*Not defined*  |Changes the display defines for use with 64x128 displays.                                                                              |
    245 |`OLED_DISPLAY_128X128`|*Not defined*  |Changes the display defines for use with 128x128 displays.                                                                             |
    246 |`OLED_DISPLAY_CUSTOM` |*Not defined*  |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines.                             |
    247 
    248 ::: warning
    249 64x128 and 128x128 displays default to the SH1107 IC type, as these heights are not supported by the other IC types.
    250 :::
    251 
    252 |Define               |Default        |Description                                                                                                                             |
    253 | --------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
    254 |`OLED_DISPLAY_WIDTH` |`128`          |The width of the OLED display.                                                                                                          |
    255 |`OLED_DISPLAY_HEIGHT`|`32`           |The height of the OLED display.                                                                                                         |
    256 |`OLED_MATRIX_SIZE`   |`512`          |The local buffer size to allocate.<br>`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`.                                                 |
    257 |`OLED_BLOCK_TYPE`    |`uint16_t`     |The unsigned integer type to use for dirty rendering.                                                                                   |
    258 |`OLED_BLOCK_COUNT`   |`16`           |The number of blocks the display is divided into for dirty rendering.<br>`(sizeof(OLED_BLOCK_TYPE) * 8)`.                               |
    259 |`OLED_BLOCK_SIZE`    |`32`           |The size of each block for dirty rendering<br>`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`.                                                  |
    260 |`OLED_COM_PINS`      |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.<br>Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.|
    261 |`OLED_COM_PIN_COUNT` |*Not defined*  |Number of COM pins supported by the controller.<br>If not defined, the value appropriate for the defined `OLED_IC` is used.             |
    262 |`OLED_COM_PIN_OFFSET`|`0`            |Number of the first COM pin used by the OLED matrix.                                                                                    |
    263 |`OLED_SOURCE_MAP`    |`{ 0, ... N }` |Precalculated source array to use for mapping source buffer to target OLED memory in 90 degree rendering.                               |
    264 |`OLED_TARGET_MAP`    |`{ 24, ... N }`|Precalculated target array to use for mapping source buffer to target OLED memory in 90 degree rendering.                               |
    265 
    266 ### 90 Degree Rotation - Technical Mumbo Jumbo
    267 
    268 ```c
    269 // OLED Rotation enum values are flags
    270 typedef enum {
    271     OLED_ROTATION_0   = 0,
    272     OLED_ROTATION_90  = 1,
    273     OLED_ROTATION_180 = 2,
    274     OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180
    275 } oled_rotation_t;
    276 ```
    277 
    278 OLED displays driven by SSD1306, SH1106 or SH1107 drivers only natively support in hardware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an ATmega32U4 board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms.
    279 
    280 90 degree rotation is achieved by using bitwise operations to rotate each 8 block of memory and uses two precalculated arrays to remap buffer memory to OLED memory. The memory map defines are precalculated for remap performance and are calculated based on the display height, width, and block size. For example, in the 128x32 implementation with a `uint8_t` block type, we have a 64 byte block size. This gives us eight 8 byte blocks that need to be rotated and rendered. The OLED renders horizontally two 8 byte blocks before moving down a page, e.g:
    281 
    282 |   |   |   |   |   |   |
    283 |---|---|---|---|---|---|
    284 | 0 | 1 |   |   |   |   |
    285 | 2 | 3 |   |   |   |   |
    286 | 4 | 5 |   |   |   |   |
    287 | 6 | 7 |   |   |   |   |
    288 
    289 However the local buffer is stored as if it was Height x Width display instead of Width x Height, e.g:
    290 
    291 |   |   |   |   |   |   |
    292 |---|---|---|---|---|---|
    293 | 3 | 7 |   |   |   |   |
    294 | 2 | 6 |   |   |   |   |
    295 | 1 | 5 |   |   |   |   |
    296 | 0 | 4 |   |   |   |   |
    297 
    298 So those precalculated arrays just index the memory offsets in the order in which each one iterates its data.
    299 
    300 Rotation on SH1106 and SH1107 is noticeably less efficient than on SSD1306, because these controllers do not support the “horizontal addressing mode”, which allows transferring the data for the whole rotated block at once; instead, separate address setup commands for every page in the block are required.  The screen refresh time for SH1107 is therefore about 45% higher than for a same size screen with SSD1306 when using STM32 MCUs (on AVR the slowdown is about 20%, because the code which actually rotates the bitmap consumes more time).
    301 
    302 ## OLED API
    303 
    304 ```c
    305 // OLED Rotation enum values are flags
    306 typedef enum {
    307     OLED_ROTATION_0   = 0,
    308     OLED_ROTATION_90  = 1,
    309     OLED_ROTATION_180 = 2,
    310     OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180
    311 } oled_rotation_t;
    312 
    313 // Initialize the oled display, rotating the rendered output based on the define passed in.
    314 // Returns true if the OLED was initialized successfully
    315 bool oled_init(oled_rotation_t rotation);
    316 
    317 // Called at the start of oled_init, weak function overridable by the user
    318 // rotation - the value passed into oled_init
    319 // Return new oled_rotation_t if you want to override default rotation
    320 oled_rotation_t oled_init_kb(oled_rotation_t rotation);
    321 oled_rotation_t oled_init_user(oled_rotation_t rotation);
    322 
    323 // Send commands/data to screen
    324 bool oled_send_cmd(const uint8_t *data, uint16_t size);
    325 bool oled_send_cmd_P(const uint8_t *data, uint16_t size);
    326 bool oled_send_data(const uint8_t *data, uint16_t size);
    327 
    328 // Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering
    329 void oled_clear(void);
    330 
    331 // Alias to oled_render_dirty to avoid a change in api.
    332 #define oled_render() oled_render_dirty(false)
    333 
    334 // Renders all dirty blocks to the display at one time or a subset depending on the value of
    335 // all.
    336 void oled_render_dirty(bool all);
    337 
    338 // Moves cursor to character position indicated by column and line, wraps if out of bounds
    339 // Max column denoted by 'oled_max_chars()' and max lines by 'oled_max_lines()' functions
    340 void oled_set_cursor(uint8_t col, uint8_t line);
    341 
    342 // Advances the cursor to the next page, writing ' ' if true
    343 // Wraps to the beginning when out of bounds
    344 void oled_advance_page(bool clearPageRemainder);
    345 
    346 // Moves the cursor forward 1 character length
    347 // Advance page if there is not enough room for the next character
    348 // Wraps to the beginning when out of bounds
    349 void oled_advance_char(void);
    350 
    351 // Writes a single character to the buffer at current cursor position
    352 // Advances the cursor while writing, inverts the pixels if true
    353 // Main handler that writes character data to the display buffer
    354 void oled_write_char(const char data, bool invert);
    355 
    356 // Writes a string to the buffer at current cursor position
    357 // Advances the cursor while writing, inverts the pixels if true
    358 void oled_write(const char *data, bool invert);
    359 
    360 // Writes a string to the buffer at current cursor position
    361 // Advances the cursor while writing, inverts the pixels if true
    362 // Advances the cursor to the next page, wiring ' ' to the remainder of the current page
    363 void oled_write_ln(const char *data, bool invert);
    364 
    365 // Pans the buffer to the right (or left by passing true) by moving contents of the buffer
    366 // Useful for moving the screen in preparation for new drawing
    367 void oled_pan(bool left);
    368 
    369 // Returns a pointer to the requested start index in the buffer plus remaining
    370 // buffer length as struct
    371 oled_buffer_reader_t oled_read_raw(uint16_t start_index);
    372 
    373 // Writes a string to the buffer at current cursor position
    374 void oled_write_raw(const char *data, uint16_t size);
    375 
    376 // Writes a single byte into the buffer at the specified index
    377 void oled_write_raw_byte(const char data, uint16_t index);
    378 
    379 // Sets a specific pixel on or off
    380 // Coordinates start at top-left and go right and down for positive x and y
    381 void oled_write_pixel(uint8_t x, uint8_t y, bool on);
    382 
    383 #if defined(__AVR__)
    384 // Writes a PROGMEM string to the buffer at current cursor position
    385 // Advances the cursor while writing, inverts the pixels if true
    386 // Remapped to call 'void oled_write(const char *data, bool invert);' on ARM
    387 void oled_write_P(const char *data, bool invert);
    388 
    389 // Writes a PROGMEM string to the buffer at current cursor position
    390 // Advances the cursor while writing, inverts the pixels if true
    391 // Advances the cursor to the next page, wiring ' ' to the remainder of the current page
    392 // Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM
    393 void oled_write_ln_P(const char *data, bool invert);
    394 
    395 // Writes a PROGMEM string to the buffer at current cursor position
    396 void oled_write_raw_P(const char *data, uint16_t size);
    397 #else
    398 # define oled_write_P(data, invert) oled_write(data, invert)
    399 # define oled_write_ln_P(data, invert) oled_write_ln(data, invert)
    400 # define oled_write_raw_P(data, size) oled_write_raw(data, size)
    401 #endif // defined(__AVR__)
    402 
    403 // Can be used to manually turn on the screen if it is off
    404 // Returns true if the screen was on or turns on
    405 bool oled_on(void);
    406 
    407 // Can be used to manually turn off the screen if it is on
    408 // Returns true if the screen was off or turns off
    409 bool oled_off(void);
    410 
    411 // Returns true if the oled is currently on, false if it is
    412 // not
    413 bool is_oled_on(void);
    414 
    415 // Sets the brightness level of the display
    416 uint8_t oled_set_brightness(uint8_t level);
    417 
    418 // Gets the current brightness level of the display
    419 uint8_t oled_get_brightness(void);
    420 
    421 // Basically it's oled_render, but with timeout management and oled_task_user calling!
    422 void oled_task(void);
    423 
    424 // Called at the start of oled_task, weak function overridable by the user
    425 bool oled_task_kb(void);
    426 bool oled_task_user(void);
    427 
    428 // Set the specific 8 lines rows of the screen to scroll.
    429 // 0 is the default for start, and 7 for end, which is the entire
    430 // height of the screen.  For 128x32 screens, rows 4-7 are not used.
    431 void oled_scroll_set_area(uint8_t start_line, uint8_t end_line);
    432 
    433 // Sets scroll speed, 0-7, fastest to slowest. Default is three.
    434 // Does not take effect until scrolling is either started or restarted
    435 // the ssd1306 supports 8 speeds with the delay
    436 // listed below between each frame of the scrolling effect
    437 // 0=2, 1=3, 2=4, 3=5, 4=25, 5=64, 6=128, 7=256
    438 void oled_scroll_set_speed(uint8_t speed);
    439 
    440 // Begin scrolling the entire display right
    441 // Returns true if the screen was scrolling or starts scrolling
    442 // NOTE: display contents cannot be changed while scrolling
    443 bool oled_scroll_right(void);
    444 
    445 // Begin scrolling the entire display left
    446 // Returns true if the screen was scrolling or starts scrolling
    447 // NOTE: display contents cannot be changed while scrolling
    448 bool oled_scroll_left(void);
    449 
    450 // Turns off display scrolling
    451 // Returns true if the screen was not scrolling or stops scrolling
    452 bool oled_scroll_off(void);
    453 
    454 // Returns true if the oled is currently scrolling, false if it is
    455 // not
    456 bool is_oled_scrolling(void);
    457 
    458 // Inverts the display
    459 // Returns true if the screen was or is inverted
    460 bool oled_invert(bool invert);
    461 
    462 // Returns the maximum number of characters that will fit on a line
    463 uint8_t oled_max_chars(void);
    464 
    465 // Returns the maximum number of lines that will fit on the OLED
    466 uint8_t oled_max_lines(void);
    467 ```
    468 
    469 ::: warning
    470 Scrolling is unsupported on the SH1106 and SH1107.
    471 :::
    472 
    473 ::: warning
    474 Scrolling does not work properly on the SSD1306 if the display width is smaller than 128.
    475 :::
    476 
    477 ## SSD1306.h Driver Conversion Guide
    478 
    479 |Old API                  |Recommended New API              |
    480 |-------------------------|---------------------------------|
    481 |`struct CharacterMatrix` |*removed - delete all references*|
    482 |`iota_gfx_init`          |`oled_init`                      |
    483 |`iota_gfx_on`            |`oled_on`                        |
    484 |`iota_gfx_off`           |`oled_off`                       |
    485 |`iota_gfx_flush`         |`oled_render`                    |
    486 |`iota_gfx_write_char`    |`oled_write_char`                |
    487 |`iota_gfx_write`         |`oled_write`                     |
    488 |`iota_gfx_write_P`       |`oled_write_P`                   |
    489 |`iota_gfx_clear_screen`  |`oled_clear`                     |
    490 |`matrix_clear`           |*removed - delete all references*|
    491 |`matrix_write_char_inner`|`oled_write_char`                |
    492 |`matrix_write_char`      |`oled_write_char`                |
    493 |`matrix_write`           |`oled_write`                     |
    494 |`matrix_write_ln`        |`oled_write_ln`                  |
    495 |`matrix_write_P`         |`oled_write_P`                   |
    496 |`matrix_write_ln_P`      |`oled_write_ln_P`                |
    497 |`matrix_render`          |`oled_render`                    |
    498 |`iota_gfx_task`          |`oled_task`                      |
    499 |`iota_gfx_task_user`     |`oled_task_user`                 |