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

LVGL Font corruption on SSD1306 display (IDFGH-7736) #9277

Open
VikOlliver opened this issue Jul 3, 2022 · 10 comments
Open

LVGL Font corruption on SSD1306 display (IDFGH-7736) #9277

VikOlliver opened this issue Jul 3, 2022 · 10 comments
Assignees
Labels
Status: Opened Issue is new

Comments

@VikOlliver
Copy link

Environment

  • Development Kit: [none]
  • Module or chip used: [ESP32-WROOM-32]
  • IDF version (run git describe --tags to find it): v5.0-dev-3654-gc2ccc383da
  • Build System: [Make|CMake|idf.py]
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it): 1.22.0-80-g6c4433a
  • Operating System: [Linux]
  • Using an IDE?: [No]
  • Power Supply: [USB]

Problem Description

Default UNSCII fonts are displayed half height when rendered using the stock example code on a 128x32 SSD1306 monochrome OLED display.

Problem is exhibited by other monospace fonts, but the stock examples are probably better for illustrating the bug.

Expected Behavior

UNSCII 8 font displayed 8 pixels high, UNSCII 16 font displayed 16 pixels high

Actual Behavior

UNSCII 8 font displayed 4 pixels high and completely illegible.
UNSCII 16 font displayed 8 pixels high, 16 pixels wide.

Steps to reproduce

  1. Set appropriate LVGL UNSCII font in idf.py menuconfig
  2. build/flash esp-idf/examples/peripherals/lcd/i2c_oled

// If possible, attach a picture of your setup/wiring here.
Unable to attach. Github reports "something has gone seriously wrong" when attempting to attach a 294KiB JPEG

Code to reproduce this issue

Stock example.

Debug Logs

No errors logged.
I (388) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (398) example: Initialize I2C bus
I (408) example: Install panel IO
I (408) example: Install SSD1306 panel driver
I (508) example: Initialize LVGL library
I (508) example: Register display driver to LVGL
I (508) example: Install LVGL tick timer
I (508) example: Display LVGL Scroll Text

@espressif-bot espressif-bot added the Status: Opened Issue is new label Jul 3, 2022
@github-actions github-actions bot changed the title LVGL Font corruption on SSD1306 display LVGL Font corruption on SSD1306 display (IDFGH-7736) Jul 3, 2022
@VikOlliver
Copy link
Author

font_bug

OK, managed to upload images of the corrupt and squashed font on the OLED display by using Firefox in debug mode :)

@VikOlliver
Copy link
Author

Playing with this a bit more, it looks like every other line is missed off everything. Creating a 128x32 text area only puts characters on the top of the screen even when the content scrolls. Expanding it to a 128x64 text box will make it fill the whole screen (as you might see from the pictures above, it's definitely a 128x32 display).

@andershedberg
Copy link

andershedberg commented Jul 19, 2022

[edit - I'm not really sure what example code we have run and put together]

We see some similar behavior as well when we tried out the i2c bus and choose this display we had used in a previous Raspberry Pie project - https://www.adafruit.com/product/3527 [edit - one pull up resistor was not attached, so my remark on 400kHz was not legit. Now it runs at 400 kHz, but still shows strange things]

Is it related to #9209 ? [Edit - the first initial fix in references 9209 does not seem to help. Still strange display.]
(there are also a lot of other i2c issues when searching for issues)

@VikOlliver
Copy link
Author

I'm not playing with the I2C interface myself, just using the defaults from the esp-idf demo code, and I'm not seeing any other corruption (well, the cursor does temporarily shave the rightmost pixel off the previous character, but that fixes itself eventually). I have done a simple workaround, which is basically just using fontforge to double the height of the font. Not exactly memory-efficient, but functional.

@yuanyihan
Copy link

Hi,you can add some code in init():

#if SSD1306_LCD_DISP_IS_128X32 == 1
    esp_lcd_panel_io_tx_param(io_handle, 0xa8, (uint8_t[1]){0x1f}, 1); // 0x3F for 128x64, 0x1F for 128x32
    esp_lcd_panel_io_tx_param(io_handle, 0xda, (uint8_t[1]){0x02}, 1); // 0x12 for 128x64, 0x02 for 128x32
#else
    esp_lcd_panel_io_tx_param(io_handle, 0xa8, (uint8_t[1]){0x3f}, 1); // 0x3F for 128x64, 0x1F for 128x32
    esp_lcd_panel_io_tx_param(io_handle, 0xda, (uint8_t[1]){0x12}, 1); // 0x12 for 128x64, 0x02 for 128x32
#endif

between ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); and ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); in https://github.com/espressif/esp-idf/blob/master/examples/peripherals/lcd/i2c_oled/main/i2c_oled_example_main.c#L126

befor:
bef

after:
aft

@mbelt
Copy link

mbelt commented Nov 7, 2022

esp_lcd_panel_init(...) only does the bare minimum setup.
Set Addressing Mode0x20 0x00
Enable Charge Pump 0x8D, 0x14
Turn On 0xAF.

The datasheet describes a longer set of initialization steps.
(edited 11/7 w/corrections from @yuanyihan)
Set MUX Ratio 0xA8, 0x3F for 128x64, 0xA8, 0x1F for 128x32
Set Addressing Mode0x20 0x00 (Not in the datasheet init flowchart, but necessary)
Set Display Offset 0xD3, 0x00
Set Display Start Line 0x40, 0x00
Set Segment Re-Map 0xA0
Set COM Output Scan Direction 0xC0 (or 0xC8 for 180° rotation)
Set COM Pins Hardware Configuration 0xDA, 0x12 for 128x64 or 0xDA, 0x02 for 128x32px
Set Contrast Control 0x8a, 0x7F
Disable Display On 0xA4
Set Normal Display 0xA6
Set Osc Frequency 0xD5, 0x80
Enable Charge Pump Regulator 0x8D, 0x14
Display On 0xAF

Note:
There are many possible combinations for Mux Ratio, Output Direction, and Pins Configuration.

@yuanyihan
Copy link

yuanyihan commented Nov 7, 2022

@mbelt
THINKS,It‘s very useful
Some minor mistakes:

  • Set Display Offset 0xD2, 0x00 is Set Display Offset 0xD3, 0x00
  • Set Segment Re-Map 0xA0, 0xA1 means Set Segment Re-Map 0xA0 for normal or 0xA1 for rotation180
  • Set COM Output Scan Direction 0xC0 is Set COM Output Scan Direction 0xC0 for normal or 0xC8 for rotation180
  • Set COM Pins Hardware Configuration 0xDA, 0x12 for 128x64 or 0xDA, 0x021 for 128x32pxis Set COM Pins Hardware Configuration 0xDA, 0x12 for 128x64 or 0xDA, 0x02 for 128x32px
  • for 128x32px,I'd like Set MUX Ratio 0xA8,0x3F for 128x64 or 0xA8,0x1F for 128x32

@mbelt
Copy link

mbelt commented Nov 7, 2022

@yuanyihan
No, thank you.
| Set Segment Re-Map 0xA0 for normal or 0xA1 for rotation180
Fixed an issue I was having.

Edited previous comment with corrections.

@yuanyihan
Copy link

yuanyihan commented Nov 8, 2022

I mean :
Acording SSD1306-DATASHEET

We know :

  • Normal:A0H and C0H ('and' means both)
  • rot180: A1H and C8H
#if (SSD1306_LCD_DISP_ROT_180 == true)                   //  https://bugxia.com/931.html
    esp_lcd_panel_io_tx_param(io_handle, 0xC8, NULL, 0); // Set COM Output Scan Direction 0xC0 OR 0xC8
    esp_lcd_panel_io_tx_param(io_handle, 0xA1, NULL, 0); // Set Segment Re-Map 0xA0 OR 0xA1
#else
    esp_lcd_panel_io_tx_param(io_handle, 0xC0, NULL, 0); // Set COM Output Scan Direction 0xC0 OR 0xC8
    esp_lcd_panel_io_tx_param(io_handle, 0xA0, NULL, 0); // Set Segment Re-Map 0xA0 OR 0xA1
#endif

I think esp_lcd_panel_ssd1306.c @ esp-idf's CODE is very obvious.
They use MIRROR in static esp_err_t panel_ssd1306_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y)

C8A1
C0A0
C0A1
C8A0

@storoj
Copy link
Contributor

storoj commented Oct 23, 2023

@VikOlliver I had the same issue and I did my best to provide the fix: #12450. Thanks @yuanyihan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Opened Issue is new
Projects
None yet
Development

No branches or pull requests

7 participants