Way to Rotate lvgl example?

Hi,

I have been working on a project involving an LCD screen using the LVGL sample as a base. However, it would be nice if I could rotate either the text itself or the screen by 90 degrees. I tried the lv_disp_set _rotation command found in lv_hal_disp.c but rather than rotating the screen it just broke the display. The same thing happens if I flip the width and height in the overlay. 1) is this error some how caused by the lv_disp library and 2) is there a fix for this? I am using the SH1107 OLED which is compatible with the ssd1306 drivers and I am using an unedited version of the lvgl example. Any help would be appreciated.

Thanks!

Parents
  • Hi,

    I tried the lv_disp_set _rotation command found in lv_hal_disp.c but rather than rotating the screen it just broke the display

    What does it look like when it breaks?

    It seems like others are experiencing this with the SSD1306 driver:

    https://github.com/lvgl/lvgl/issues/3379#issuecomment-1147954592

    https://github.com/zephyrproject-rtos/zephyr/issues/46446

    https://github.com/zmkfirmware/zmk/issues/1749

  • So looking more into it looks like the fixes posted on the LVGL forum are a little outdated. Kconfig.graphical doesn't exist anymore, for example and the fixes in the Zephyr forums don't work in isolation. Still looking into seeing if there is a fix.

  • Hi 

    Have you tried to change the rotation property in the device tree node for the display driver? 

    I believe this is the recommended way to set the orientation of the display. 

    Best regards
    Torbjørn

  • I tried to but I was under them impression from research that there wasn't a rotation property. Can I just set that in the overlay?

  • Hi 

    Can you check the zephyr.dts file in the build/zephyr directory? 

    This file will contain the complete device tree configuration, after all board files, overlays etc has been compiled. 

    As an example, if I build the display/lvgl sample I can find the display node under spi3, and see that it includes the rotation property:

    ili9340: ili9340@0 {
    		compatible = "ilitek,ili9340";
    		spi-max-frequency = < 0xe7319b >;
    		reg = < 0x0 >;
    		cmd-data-gpios = < &arduino_header 0xf 0x1 >;
    		width = < 0x140 >;
    		height = < 0xf0 >;
    		pixel-format = < 0x1 >;
    		rotation = < 0x5a >;
    		frmctr1 = [ 00 18 ];
    		pwctrl1 = [ 23 00 ];
    		vmctrl1 = [ 3E 28 ];
    		vmctrl2 = [ 86 ];
    		pgamctrl = [ 0F 31 2B 0C 0E 08 4E F1 37 07 10 03 0E 09 00 ];
    		ngamctrl = [ 00 0E 14 03 11 07 31 C1 48 08 0F 0C 31 36 0F ];
    	};

    You should be able to change this property through the overlay, yes. 

    Once the project gets more mature I would recommend making your own board definition, rather than relying on overlays. 

    Best regards
    Torbjørn

  • Ah, I see. Unfortunately I am using I2C rather than SPI.

    i2c1: arduino_i2c: i2c@9000 {
                    compatible = "nordic,nrf-twim";
                    #address-cells = < 0x1 >;
                    #size-cells = < 0x0 >;
                    reg = < 0x9000 0x1000 >;
                    clock-frequency = < 0x61a80 >;
                    interrupts = < 0x9 0x1 >;
                    status = "okay";
                    pinctrl-0 = < &i2c1_default >;
                    pinctrl-1 = < &i2c1_sleep >;
                    pinctrl-names = "default", "sleep";
                    zephyr,concat-buf-size = < 0x1000 >;
                    ssd1306_ssd1306_128x64: ssd1306: ssd1306@3c {
                        compatible = "solomon,ssd1306fb";
                        reg = < 0x3c >;
                        width = < 0x40 >;
                        height = < 0x80 >;
                        segment-offset = < 0x0 >;
                        page-offset = < 0x0 >;
                        display-offset = < 0x1f >;
                        multiplex-ratio = < 0x3f >;
                        segment-remap;
                        com-invdir;
                        prechargep = < 0x22 >;
                        com-sequential;
                    };
                };

    As you can see there is no rotation here.

  • Hi 

    My bad, you are correct that there is no rotation property for the ssd1306 driver. 

    Looking at the driver implementation in ssd1306.c I see that the set_orientation function will just return the not supported error:
    https://github.com/nrfconnect/sdk-zephyr/blob/main/drivers/display/ssd1306.c#L365-L371

    As far as I can tell from the SSD1306 datasheet the driver doesn't provide any kind of rotation register, which is why it is not supported in the driver. 

    What happens if you remove the segment-remap or com-invdir properties from the ssd1306 node? 

    Possibly you can invert the display horizontally or vertically this way, but I am not sure that will solve your issue or not. 

    Best regards
    Torbjørn

Reply Children
  • Hi,

    So I tried playing around with removing those two properties and as far as I can tell nothing happened? Im a little confused by that. I modified both the overlay and zephyr.dts tp remove one/both of those properties and as far as I can tell that had zero visual effect on the output. That doesn't feel right to me though. It feels like that should have done something.

  • Hi 

    zephyr.dts is generated by the build system, changing this file will have no effect. Instead you can use this file to verify if the changes you make in the overlay or other places are actually picked up by the build system. 

    How did you try to remove the property? 

    There is an example here showing how you can delete a property in the overlay:

    &serial0 {
         /delete-property/ some-unwanted-property;
    };

    After trying that, do a pristine build, and check zephyr.dts again to see if the property is still there. 

    Best regards
    Torbjørn

  • Hi,

    Thanks for the .dts clarification and the /delete-property clarification. I am not as good at the overlay stuff as I would like to be so I appreciate the patient clarification.

    Deleting segment-remap rotates the screen by 180 degrees which is neat but not the 90 that I am looking for. Deleting com-invdir just breaks the output which is unfortunate. I tried messing around with some of the together settings to try to get a version working after deleting com-invdir but to no avail. 

  • Hi 

    Really odd that the com-invdir change wouldn't work. Looking at the driver implementation this seems to be a standard feature. 

    Regarding the lv_disp_set_rotation command, did you try this with all possible rotation values? 

    Did you try to enable the software rotation feature?
    Possibly this one will allow you to rotate the display, even if it is a slower method compared to hardware rotation. 

    Best regards
    Torbjørn

  • I did try lv_set_rotation with all the possible rotation values. None of them gave a legible output.

    I tried setting driver->sw_rotate = LV_DISP_ROT_90 in the lv_disp_drv_init() function. Doesn't seem to accomplish anything. I have tried a few other things (like trying to change it in the lv_disp_drv_t typdef declaration) but I havn;t been able to get it to work. If you have an idea of how I could better use that then I would love to hear about it. I don't really care how slow it is. I just need to do it once during initialization. 

    Thanks,

    Rainier

Related