Coder Social home page Coder Social logo

hagl_pico_mipi's Introduction

MIPI DCS HAL for HAGL Graphics Library

HAL for HAGL graphics library for display drivers supporting the MIPI Display Command Set standard. This covers most displays currently used by hobbyists. Tested with ST7735S, ST7789, ST7789V ST7789VW, ILI9341 and ILI9163. There is ready made config files for popular displays.

Software License

Usage

To use with a Raspberry Pi Pico SDK project you include this HAL and the HAGL graphics library itself. For example applications see Old School Demo Effects and Graphics Speed Tests. If in a hurry check a video instead.

$ mkdir external
$ cd external
$ git submodule add [email protected]:tuupola/hagl_pico_mipi.git hagl_hal
$ git submodule add [email protected]:tuupola/hagl.git

Then in your CMakeLists.txt include both libraries in the build.

add_subdirectory(external/hagl)
add_subdirectory(external/hagl_hal)
target_link_libraries(firmware hagl hagl_hal)

Buffering

By default the HAL uses single buffering. The buffer is the GRAM of the display driver chip. You can enable double buffering with the following.

target_compile_definitions(firmware PRIVATE
  HAGL_HAL_USE_DOUBLE_BUFFER
)

By default flushing from back buffer to front buffer is a locking operation. You can avoid that by enabling DMA. This is faster but will cause screen tearing unless you handle vertical syncing in the software.

target_compile_definitions(firmware PRIVATE
  HAGL_HAL_USE_DOUBLE_BUFFER
  HAGL_HAL_USE_DMA
)

Alternatively you can also use triple buffering. This is the fastest and will not have screen tearing with DMA. Downside is that it uses lot of memory.

target_compile_definitions(firmware PRIVATE
  HAGL_HAL_USE_TRIPLE_BUFFER
  HAGL_HAL_USE_DMA
)

Pixel size

If you run out of memory you could try using bigger pixel size. For example if you have 240x240 pixel display and you want to try triple buffering you could do the following. In practice it will change your usable resolution to 120x120 pixels.

Note! At the time of writing HAGL_HAL_PIXEL_SIZE=2 will not work together with the HAGL_HAL_USE_DMA setting.

target_compile_definitions(firmware PRIVATE
  HAGL_HAL_USE_TRIPLE_BUFFER
  HAGL_HAL_PIXEL_SIZE=2
)

Power and Backlight

Some boards require power and / or backlight pins. Out of these the backlight pin is more usual.

target_compile_definitions(firmware PRIVATE
  MIPI_DISPLAY_PIN_BL=20
  MIPI_DISPLAY_PIN_POWER=22
)

Vertical Sync

While quite rare, some devices such as Pimoroni PicoSystem (awesome device btw) provide vsync signal on a pin. This can be used to reduce tearing when using double or triple buffering.

target_compile_definitions(firmware PRIVATE
    MIPI_DISPLAY_PIN_TE=8
)

Configuration

You can override any of the default settings setting in CMakeLists.txt. You only need to override a value if default is not ok. Below example shows all default values. Defaults are ok for Waveshare RP2040-LCD-0.96 in vertical mode.

target_compile_definitions(firmware PRIVATE
    MIPI_DISPLAY_PIN_CS=9
    MIPI_DISPLAY_PIN_DC=8
    MIPI_DISPLAY_PIN_RST=12
    MIPI_DISPLAY_PIN_BL=13
    MIPI_DISPLAY_PIN_CLK=10
    MIPI_DISPLAY_PIN_MOSI=11
    MIPI_DISPLAY_PIN_MISO=-1
    MIPI_DISPLAY_PIN_POWER=-1
    MIPI_DISPLAY_PIN_TE=-1

    MIPI_DISPLAY_SPI_PORT=spi1
    MIPI_DISPLAY_SPI_CLOCK_SPEED_HZ=62500000

    MIPI_DISPLAY_PIXEL_FORMAT=MIPI_DCS_PIXEL_FORMAT_16BIT
    MIPI_DISPLAY_ADDRESS_MODE=MIPI_DCS_ADDRESS_MODE_BGR
    MIPI_DISPLAY_WIDTH=80
    MIPI_DISPLAY_HEIGHT=160
    MIPI_DISPLAY_OFFSET_X=26
    MIPI_DISPLAY_OFFSET_Y=1
    MIPI_DISPLAY_INVERT=1
)

MIPI_DISPLAY_ADDRESS_MODE controls the orientation and the RGB order of the display. The value is a bit field which can consist of the following flags defined in mipi_dcs.h.

#define MIPI_DCS_ADDRESS_MODE_MIRROR_Y      0x80
#define MIPI_DCS_ADDRESS_MODE_MIRROR_X      0x40
#define MIPI_DCS_ADDRESS_MODE_SWAP_XY       0x20
#define MIPI_DCS_ADDRESS_MODE_BGR           0x08
#define MIPI_DCS_ADDRESS_MODE_RGB           0x00
#define MIPI_DCS_ADDRESS_MODE_FLIP_X        0x02
#define MIPI_DCS_ADDRESS_MODE_FLIP_Y        0x01

You should OR together the flags you want to use. For example if you have a 135x240 pixel display on vertical mode.

target_compile_definitions(firmware PRIVATE
  MIPI_DISPLAY_WIDTH=135
  MIPI_DISPLAY_HEIGHT=240
)

You can change it to 240x135 pixel vertical mode by swapping the X and Y coordinates. You will also need to mirror Y axis.

target_compile_definitions(firmware PRIVATE
  MIPI_DISPLAY_ADDRESS_MODE=MIPI_DCS_ADDRESS_MODE_SWAP_XY|MIPI_DCS_ADDRESS_MODE_MIRROR_Y
  MIPI_DISPLAY_WIDTH=240
  MIPI_DISPLAY_HEIGHT=135
)

You can OR together as many flags as you want. Not all combinations make sense but any display orientation can be achieved with correct combination of the flags. When in doubt just try different combinations.

Common problems

If red and blue are mixed but green is ok change to BGR mode.

target_compile_definitions(firmware PRIVATE
  MIPI_DISPLAY_ADDRESS_MODE=MIPI_DCS_ADDRESS_MODE_BGR
)

If display seems inverted turn of the inversion.

target_compile_definitions(firmware PRIVATE
  MIPI_DISPLAY_INVERT=0
)

If image is not center on screen adjust X and Y offsets as needed.

target_compile_definitions(firmware PRIVATE
  MIPI_DISPLAY_OFFSET_X=25
  MIPI_DISPLAY_OFFSET_Y=30
)

Speed

Below testing was done with Waveshare RP2040-LCD-0.96. Buffered refresh rate was set to 30 frames per second. Number represents operations per seconds ie. bigger number is better.

Single Double Double DMA Triple DMA
hagl_put_pixel() 156119 319931 364294 365326
hagl_draw_line() 3068 15655 17723 17794
hagl_draw_vline() 54779 72712 82412 82509
hagl_draw_hline() 68244 72637 82305 82497
hagl_draw_circle() 2345 13519 15345 15371
hagl_fill_circle() 1539 8571 9701 9744
hagl_draw_ellipse() 1563 7565 8543 8563
hagl_fill_ellipse() 668 3666 4153 4167
hagl_draw_triangle() 1025 5348 6045 6080
hagl_fill_triangle() 533 699 806 806
hagl_draw_rectangle() 14131 22244 25103 25244
hagl_fill_rectangle() 1503 9406 10699 10712
hagl_draw_rounded_rectangle() 5778 16984 19214 19288
hagl_fill_rounded_rectangle() 1361 8223 9307 9347
hagl_draw_polygon() 619 3235 3661 3678
hagl_fill_polygon() 323 421 476 486
hagl_put_char() 5296 25170 28534 28443
hagl_put_text() 392

License

The MIT License (MIT). Please see LICENSE for more information.

hagl_pico_mipi's People

Contributors

sebkuzminsky avatar tuupola avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

hagl_pico_mipi's Issues

Slowness on pico + ILI9341 (2.8" spi)

Hello !!

I'm trying to run the old school demo on the pico with ILI9341. Question is : is this supposed to be slow on this kind of screen ?
I'm not able to achieved a lot of fps , i think for plasma it's 14 fps max , and then it hangs on the second effect ..

(i had to comment the busy_wait_until (start + US_PER_FRAME_60_FPS); to achieve some fps !)
By the way, busy_wait_until waits for an absolute_time_t type, so it's not compiling anyway (update ?)

I tried using triple buffering, but it can't link as there not enough space on the pico( i guess ?) (error : firmware.elf section .bss' will not fit in region RAM')

Am i doing something wrong ?

thanks;

add screen rotation?

I just found this library and I'm very impressed with the design and the code quality!

I've been using a different (simpler) driver library to talk to little LCD screens from the Pico, and one feature i miss when switching to HAGL is screen rotation, e.g.:

https://github.com/gavinlyonsrepo/ST7735_TFT_PICO/blob/main/src/st7735/ST7735_TFT.cpp#L455-L509

I'm wondering if you are interested in a PR to add this feature to hagl, or maybe just to hagl_pico_mipi, I confess I don't know the best place to implement this.

Utilize PIO?

More of a question than an issue, but would utilizing PIO be a better strategy for communicating with the TFT screen? I notice that this library utilizes PIO for the pico driver. It is not better to utilize PIO as it utilizes a different processor than the cortex m0+?

I appreciate that you've made this library, absolutely amazing work!

having a hard time scaling up words

I'm making a digital log with encryption I hope (starting a YouTube channel)!
The 6x9 font is way too small for the 1.8 screen I'm using so I scaled it up using

hagl_bitmap_t bitmap;
bitmap.buffer = (uint8_t *) malloc(6 *  9 * sizeof(hagl_color_t));
    while (1) {
        adc_select_input(2);
        uint adc_x_mod = (adc_read()-70) /160;
        adc_select_input(1);
        uint adc_y_mod = (adc_read()+60) /160;
        if(adc_y_mod >12){
         int16_t x0 =80;
         int16_t y0 =64;
         cde++;
         hagl_color_t color = rand() % 0xffff;
         hagl_put_char(display,chaw(8,9), x0, y0, color, font6x9);
         //hagl_get_glyph(display, a, color, &bitmap, font6x9);
         printf("%d\n",cde);

        hagl_blit_xywh(display, x0, y0, 18, 27, &bitmap);
        hagl_flush(display);
        sleep_ms(50);
        }
        else{
         int16_t x0 =80;
         int16_t y0 =64;
         hagl_color_t color = rand() % 0xffff;
         uint16_t a = chaw(8,9) + cde;
         hagl_get_glyph(display, a, color, &bitmap, font6x9);

        hagl_blit_xywh(display, x0, y0, 18, 27, &bitmap);
        hagl_flush(display);
        sleep_ms(50);
        }
        }

the structure worked out fine for generating random things, but my goal is to create an editor.
So I create an array

char commonChars[8][10] = {
        {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
        {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')'},
        {'-', '_', '=', '+', '[', ']', '{', '}', '|', '\\'},
        {';', ':', '\'', '"', ',', '.', '<', '>', '/','?'},
        {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'},
        {'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'},
        {'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D'},
        {'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'}
    };

it didn't work when casting variables
#define chaw(i,j) (uint16_t)(commonChars[i][j])
so I noticed the number aren't created the same way and discover
#define chaw(i,j) (uint16_t)(commonChars[i][j]) -178
but it only work for capital letters
Can you tell me how to modify hagl_put_char for creating 18X27 char or I'm going to do it the hard way like finding it with a joystick (different formulas for each categories)
"my first code may be messed up hope you get my point"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.