Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

samples/cfb/display flickers with SSD1306 #25161

Closed
jeremyherbert opened this issue May 9, 2020 · 2 comments
Closed

samples/cfb/display flickers with SSD1306 #25161

jeremyherbert opened this issue May 9, 2020 · 2 comments
Assignees
Labels
area: Display bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug

Comments

@jeremyherbert
Copy link
Contributor

Describe the bug
When running the example for the SSD1306, the display flickers between "012345" shown, to blank.

The following code in the example sets the font to the largest available (in my case, height of 32)

    for (int idx = 0; idx < 42; idx++) {
        if (cfb_get_font_size(dev, idx, &font_width, &font_height)) {
            break;
        }
        cfb_framebuffer_set_font(dev, idx);
        printf("font width %d, font height %d\n",
               font_width, font_height);
    }

In the console output, it prints:

x_res 128, y_res 32, ppt 8, rows 4, cols 128

which I assume means:

  • x_res = x resolution, 128 pixels
  • y_res = y resolution, 32 pixels
  • ppt = pixels per tile, 8 pixels (tiles are vertical only, so it is a 1x8 pixel tile)
  • rows = number of tile rows, 4 (= y_res/ppt)
  • cols = number of tile cols, 128

However in the main loop it then runs a for loop for each tile row, not character row:

    while (1) {
        for (int i = 0; i < rows; i++) { // <<<< rows is the number of vertical tiles, not character spaces
            cfb_framebuffer_clear(dev, false);
            if (cfb_print(dev,
                          "0123456789mMgj!\\\"§$%&/()=",
                          0, i * ppt)) {
                printf("Failed to print a string\n");
                continue;
            }

            cfb_framebuffer_finalize(dev);
        }
    }

Should it actually be something like:

    while (1) {
        for (int i = 0; i < (display_height / font_height); i++) { // use the number of character rows
            cfb_framebuffer_clear(dev, false);
            if (cfb_print(dev,
                          "0123456789mMgj!\\\"§$%&/()=",
                          0, i * font_height)) {
                printf("Failed to print a string\n");
                continue;
            }

            cfb_framebuffer_finalize(dev);
        }
    }

Although this causes flickering if there is more than one character row (in my example, font_height=16), as the display will

  1. draw the row=0 case, wrapping the extra characters onto the next row
  2. erase the display, wiping rows 0 and 1
  3. write to row 1 only
  4. erase the display, wiping rows 0 and 1

So row 0 flickers between having text and being blank, and row 1 flickers between wrapped characters and written characters.

I think the actual intention of this example is to do something like:

    while (1) {
        cfb_framebuffer_clear(dev, false);
        for (int i = 0; i < (display_height / font_height); i++) {
            if (cfb_print(dev,
                          "0123456789mMgj!\\\"§$%&/()=",
                          0, i * font_height)) {
                printf("Failed to print a string\n");
                continue;
            }
        }
        cfb_framebuffer_finalize(dev);
    }

Which just prints that text on every line (or as much as possible). This seems much more sensible than the existing sample.

I can create a PR for this last case, I'm just looking for some guidance as to what the sample is actually supposed to do.

To Reproduce
Steps to reproduce the behavior:

  1. Run the sample with an SSD1306

Expected behavior
The display should not flicker, or it should at least be documented that this is the expected behaviour (although I'm not sure how useful that is as an example).

Screenshots or console output

*** Booting Zephyr OS build v2.1.99-ncs1  ***
initialized SSD1306
font width 10, font height 16
font width 15, font height 24
font width 20, font height 32
x_res 128, y_res 32, ppt 8, rows 4, cols 128
[00:00:00.012,390] <dbg> cfb.cfb_framebuffer_init: number of fonts 3

Environment (please complete the following information):

  • OS: Ubuntu 18.04
  • Toolchain: gnuarmemb
  • Commit: ff214d6
@jeremyherbert jeremyherbert added the bug The issue is a bug, or the PR is fixing a bug label May 9, 2020
@jfischer-no jfischer-no added the priority: low Low impact/importance bug label May 11, 2020
@jfischer-no
Copy link
Collaborator

I can not see any flicker for example on nrf52dk_nrf52832, but that may be happen on other board where i2c and cpu clock is much faster. Anyway it is not the issue in the sample. It is intended to "runs a for loop for each tile row, not character row" and should not be changed.

Please consider to use LVGL instead, which provides much more features with relatively small resource consumption.

@jeremyherbert
Copy link
Contributor Author

FWIW, I was using the nrf52840, so the I2C and clock speed would have been the same.

I have since moved to lgvl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Display bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug
Projects
None yet
Development

No branches or pull requests

4 participants