Skip to content

Commit

Permalink
Merge pull request #7 from adafruit/philb_lvgl
Browse files Browse the repository at this point in the history
2.0 overhaul for LittlevGL 7.11 compatibility
  • Loading branch information
PaintYourDragon authored Mar 30, 2021
2 parents 4667e88 + 4529d5c commit 5b69c8d
Show file tree
Hide file tree
Showing 16 changed files with 3,564 additions and 292 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
html/
# Our handy .gitignore for automation ease
Doxyfile*
doxygen_sqlite3.db
html
7 changes: 0 additions & 7 deletions Adafruit_LvGL_Glue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,8 @@ static void lv_flush_callback(lv_disp_drv_t *disp, const lv_area_t *area,
uint16_t height = (area->y2 - area->y1 + 1);
display->startWrite();
display->setAddrWindow(area->x1, area->y1, width, height);
// Not sure yet why endian handling isn't consistent...work on this...
#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYPORTAL_M4_TITANO) || \
defined(NRF52_SERIES)
display->writePixels((uint16_t *)color_p, width * height, false,
LV_COLOR_16_SWAP);
#else
display->writePixels((uint16_t *)color_p, width * height, false,
!LV_COLOR_16_SWAP);
#endif

lv_disp_flush_ready(disp);
}
Expand Down
1 change: 1 addition & 0 deletions Adafruit_LvGL_Glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef enum {
LVGL_ERR_ALLOC,
LVGL_ERR_TIMER,
} LvGLStatus;

/**
* @brief Class to act as a "glue" layer between the LvGL graphics library and
* most of Adafruit's TFT displays
Expand Down
2,458 changes: 2,458 additions & 0 deletions Doxyfile

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,18 @@ docs.littlevgl.com for a thorough explanation of capabilities and use.
* [Adafruit Zero DMA Library](https://github.com/adafruit/Adafruit_ZeroDMA)
* [Adafruit ZeroTimer Library](https://github.com/adafruit/Adafruit_ZeroTimer)

# Contributing
# Compatibility
Version 2.0.0 is a breaking change, mostly due to significant structural
changes in the LittlevGL library for Arduino. If you were previously using
an earlier version of this library and/or LittlevGL, both will need updating,
and you should skim the examples and read through the hello_changes example
specifically.

Use on M0 (SAMD21) boards isn't recommended anymore, as LittlevGL has grown.
Simple programs might still work, but it's better to move up to a device
with more RAM -- M4 (SAMD51), nRF52 and ESP32 are currently supported.

# Contributing
Contributions are welcome! Please read our [Code of Conduct](https://github.com/adafruit/Adafruit_LvGL_Glue/blob/master/CODE_OF_CONDUCT.md>)
before contributing to help this project stay welcoming.

Expand Down
88 changes: 88 additions & 0 deletions examples/hello_changes/hello_changes.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
THIS EXAMPLE IS REALLY JUST DOCUMENTATION TO GUIDE YOU THROUGH CHANGES IN
Adafruit_LvGL_Glue 2.0.
If you’re coming to Adafruit_LvGL_Glue for the first time as a current user
of LittlevGL on other platforms, you're fine, there are no surprises here,
have a look at the other examples to see how to set up an Adafruit display
for your LittlevGL application.
BUT...if you've used a prior version of Adafruit_LvGL_Glue, and had written
Arduino sketches around it, you're unfortunately in for some extra work.
The "glue" hasn't changed at all, but LittlevGL has seen repeated overhauls,
and projects using earlier versions of Adafruit_LvGL_Glue will no longer
compile in the new system without substantial changes. Many function names,
constants, and styles in particular, will require updating. Many LittlevGL
projects are too much to fit on M0 (SAMD21) boards now -- it's best to work
with a device with more RAM -- M4 (SAMD51), nRF52 and ESP32 are currently
supported.
If desperate to get old code working, you can downgrade to lv_arduino 2.1.5
and Adafruit_LvGL_Glue 1.0.2, but this is NOT recommended when developing
for the long haul -- lv_arduino is altogether deprecated now and won't be
staging a comeback.
For starters, LittlevGL has moved to an entirely different Arduino library.
"lv_arduino" should be UNINSTALLED, and in its place, "lvgl" should be
INSTALLED. The latter is at version 7.11.0 as this is being written...if
there's a newer release, and if you find our glue examples failing to
compile, it's recommended to install that version until this library can be
updated. The LittlevGL developers' preference favors structural and
consistency upgrades over backwards compatibility -- and that's fine, their
project, their rules -- just explaining why this overhaul is necessary.
To repeat: in the Arduino Library Manager, uninstall lv_arduino, install
lvgl.
Also in the Arduino Library Manager, you'll see a related library called
"lv_examples" from the same developer. You can install that if you want, but
understand that this is not actually a library, nor will any of the examples
there compile in the Arduino IDE! But if you pick through these files
manually, there's C code you can dissect for insights in creating interfaces
with LittlevGL, and might create mash-ups with Adafruit_LvGL_Glue examples.
Adafruit_LvGL_Glue includes a lv_conf.file (LittlevGL configuration) that
should "just work" and enables some settings for best compatibility with
Adafruit displays. The only "gotcha" here is that user sketches MUST
#include Adafruit_LvGL_Glue.h BEFORE including lvgl.h, in order for
LittlevGL to pick up on the location of this header file.
BELOW IS A HYPOTHETICAL AND MINIMAL BUT ESSENTIALLY VALID ADAFRUIT_LVGL_GLUE
ARDUINO SKETCH. Please see the other examples for more realistic use. Actual
projects will have different display interfacing, backlight control, a set
of UI widgets and so forth.
*/

#include <Adafruit_LvGL_Glue.h> // Glue library header INCLUDE THIS FIRST!
#include <lvgl.h> // LittlevGL header
#include <Adafruit_ST7789.h> // Display-specific header

#define TFT_CS 1 // Display chip-select pin
#define TFT_DC 2 // Display data/command pin
#define TFT_RST 3 // Display reset pin

Adafruit_ST7789 tft(TFT_CS, TFT_DC, TFT_RST); // TFT on default SPI port
Adafruit_LvGL_Glue glue;

void setup(void) {
Serial.begin(115200);

tft.init(240, 240); // Initialize display

// Initialize glue, passing in address of display
LvGLStatus status = glue.begin(&tft);
if(status != LVGL_OK) {
Serial.printf("Glue error %d\r\n", (int)status);
for(;;);
}

// Create simple label centered on screen
lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Hello Arduino!");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
}

void loop(void) {
lv_task_handler(); // Call LittleVGL task handler periodically
delay(5);
}
4 changes: 3 additions & 1 deletion examples/hello_clue/hello_clue.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// LittlevGL, Adafruit_LvGL_Glue, Adafruit_GFX and Adafruit_ST7735
// libraries.

// Prior Adafruit_LvGL_Glue users: see hello_changes example for updates!

#include <Adafruit_LvGL_Glue.h> // Always include this BEFORE lvgl.h!
#include <lvgl.h>
#include <Adafruit_ST7789.h>
#include <Adafruit_LvGL_Glue.h>

#define TFT_ROTATION 1 // Landscape orientation on CLUE
#define TFT_SPI SPI1 // CLUE display peripheral & pins
Expand Down
4 changes: 3 additions & 1 deletion examples/hello_featherwing/hello_featherwing.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
// other projects. If display is scrambled, check that correct FeatherWing
// type is selected below (set BIG_FEATHERWING to 0 or 1 as needed).

// Prior Adafruit_LvGL_Glue users: see hello_changes example for updates!

#define BIG_FEATHERWING 0 // Set this to 1 for 3.5" (480x320) FeatherWing!

#include <Adafruit_LvGL_Glue.h> // Always include this BEFORE lvgl.h!
#include <lvgl.h>
#include <Adafruit_LvGL_Glue.h>
#include <Adafruit_STMPE610.h>

#ifdef ESP32
Expand Down
6 changes: 4 additions & 2 deletions examples/hello_gizmo/hello_gizmo.ino
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Minimal "Hello" example for LittlevGL on TFT Gizmo display for Adafruit
// Circuit Playground Express and Circuit Playground Bluefruit. Requires
// Circuit Playground Express or Circuit Playground Bluefruit. Requires
// LittlevGL, Adafruit_LvGL_Glue, Adafruit_GFX and Adafruit_ST7735 libraries.

// Prior Adafruit_LvGL_Glue users: see hello_changes example for updates!

#include <Adafruit_LvGL_Glue.h> // Always include this BEFORE lvgl.h!
#include <lvgl.h>
#include <Adafruit_ST7789.h>
#include <Adafruit_LvGL_Glue.h>

#define TFT_ROTATION 2
#define TFT_CS A6
Expand Down
4 changes: 3 additions & 1 deletion examples/hello_pyportal/hello_pyportal.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
// as a starting point for other projects. If display is scrambled, check
// that the correct board is selected -- PyPortal vs PyPortal Titano.

// Prior Adafruit_LvGL_Glue users: see hello_changes example for updates!

#include <Adafruit_LvGL_Glue.h> // Always include this BEFORE lvgl.h!
#include <lvgl.h>
#include <TouchScreen.h>
#include <Adafruit_LvGL_Glue.h>

#define TFT_ROTATION 3 // Landscape orientation on PyPortal
#define TFT_D0 34 // PyPortal TFT pins
Expand Down
94 changes: 46 additions & 48 deletions examples/widgets_clue/widgets_clue.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
// displaying different information. The code's a bit more complex than
// the hello_clue example, so best get that working before trying this.

// Prior Adafruit_LvGL_Glue users: see hello_changes example for updates!

#include <Adafruit_LvGL_Glue.h> // Always include this BEFORE lvgl.h!
#include <lvgl.h>
#include <Adafruit_ST7789.h>
#include <Adafruit_LvGL_Glue.h>

#define TFT_ROTATION 1 // Landscape orientation on CLUE
#define TFT_SPI SPI1 // CLUE display peripheral & pins
Expand Down Expand Up @@ -35,8 +37,8 @@ lv_chart_series_t *series; // 'Series' data for the bar chart
#define CANVAS_HEIGHT 150
lv_color_t canvas_buffer[
LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];
lv_style_t draw_style; // Drawing style (for canvas) is similarly global
lv_draw_line_dsc_t draw_dsc; // Drawing style (for canvas) is similarly global

void lvgl_setup(void) {
// Create a tabview object, by default this covers the full display.
tabview = lv_tabview_create(lv_disp_get_scr_act(NULL), NULL);
Expand All @@ -48,43 +50,39 @@ void lvgl_setup(void) {
// to be permanent in scope; either declared globally (outside all
// functions), or static. The styles used on tabs are never modified after
// they're used here, so let's use static on those...
static lv_style_t tab_on_style, tab_off_style, tab_background_style,
indicator_style;

// This is the background style "behind" the tabs. Later we'll set up
// a foreground style that's transparent, so this is what shows through
// for "off" (inactive) tabs:
lv_style_copy(&tab_background_style, &lv_style_plain); // Init defaults
tab_background_style.body.main_color = lv_color_hex(0x408040); // Green
tab_background_style.body.grad_color = lv_color_hex(0x304030); // gradient
tab_background_style.body.padding.top = 0; // Minimize size on screen
tab_background_style.body.padding.bottom = 0;
lv_tabview_set_style(tabview, LV_TABVIEW_STYLE_BTN_BG,
&tab_background_style);

// Style for "off" (inactive) tabs. It's set transparent so the background
// shows through; only the white text is seen.
lv_style_copy(&tab_off_style, &lv_style_plain); // Init defaults
tab_off_style.body.opa = LV_OPA_TRANSP;
tab_off_style.text.color = LV_COLOR_WHITE;
lv_tabview_set_style(tabview, LV_TABVIEW_STYLE_BTN_REL, &tab_off_style);
lv_tabview_set_style(tabview, LV_TABVIEW_STYLE_BTN_TGL_REL, &tab_off_style);

// This should be the style for an "on" (active) tab. For whatever reason
// I don't yet understand, this isn't rendering. Fortunately the indicator
// (below) gives some visual feedback on which tab is active.
lv_style_copy(&tab_on_style, &lv_style_plain); // Init defaults
tab_on_style.body.opa = LV_OPA_COVER;
tab_on_style.body.main_color = tab_on_style.body.grad_color = LV_COLOR_WHITE;
tab_on_style.text.color = LV_COLOR_GRAY;
lv_tabview_set_style(tabview, LV_TABVIEW_STYLE_BTN_PR, &tab_on_style);
lv_tabview_set_style(tabview, LV_TABVIEW_STYLE_BTN_TGL_PR, &tab_on_style);
static lv_style_t tab_style, tab_background_style, indicator_style;

// This is the background style "behind" the tabs. This is what shows
// through for "off" (inactive) tabs -- a vertical green gradient,
// minimal padding around edges (zero at bottom).
lv_style_init(&tab_background_style);
lv_style_set_bg_color(&tab_background_style, LV_STATE_DEFAULT, lv_color_hex(0x408040));
lv_style_set_bg_grad_color(&tab_background_style, LV_STATE_DEFAULT, lv_color_hex(0x304030));
lv_style_set_bg_grad_dir(&tab_background_style, LV_STATE_DEFAULT, LV_GRAD_DIR_VER);
lv_style_set_pad_top(&tab_background_style, LV_STATE_DEFAULT, 2);
lv_style_set_pad_left(&tab_background_style, LV_STATE_DEFAULT, 2);
lv_style_set_pad_right(&tab_background_style, LV_STATE_DEFAULT, 2);
lv_style_set_pad_bottom(&tab_background_style, LV_STATE_DEFAULT, 0);
lv_obj_add_style(tabview, LV_TABVIEW_PART_TAB_BG, &tab_background_style);

// Style for tabs. Active tab is white with opaque background, inactive
// tabs are transparent so the background shows through (only the white
// text is seen). A little top & bottom padding reduces scrunchyness.
lv_style_init(&tab_style);
lv_style_set_pad_top(&tab_style, LV_STATE_DEFAULT, 3);
lv_style_set_pad_bottom(&tab_style, LV_STATE_DEFAULT, 10);
lv_style_set_bg_color(&tab_style, LV_STATE_CHECKED, LV_COLOR_WHITE);
lv_style_set_bg_opa(&tab_style, LV_STATE_CHECKED, LV_OPA_100);
lv_style_set_text_color(&tab_style, LV_STATE_CHECKED, LV_COLOR_GRAY);
lv_style_set_bg_opa(&tab_style, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_style_set_text_color(&tab_style, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_add_style(tabview, LV_TABVIEW_PART_TAB_BTN, &tab_style);

// Style for the small indicator bar that appears below the active tab.
lv_style_copy(&indicator_style, &lv_style_plain); // Init defaults
indicator_style.body.main_color = indicator_style.body.grad_color =
LV_COLOR_RED;
lv_tabview_set_style(tabview, LV_TABVIEW_STYLE_INDIC, &indicator_style);
lv_style_init(&indicator_style);
lv_style_set_bg_color(&indicator_style, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_style_set_size(&indicator_style, LV_STATE_DEFAULT, 5);
lv_obj_add_style(tabview, LV_TABVIEW_PART_INDIC, &indicator_style);

// Back to creating widgets...

Expand All @@ -98,7 +96,7 @@ void lvgl_setup(void) {
// The first tab holds a gauge. To keep the demo simple, let's just use
// the default style and range (0-100). See LittlevGL docs for options.
gauge = lv_gauge_create(tab1, NULL);
lv_obj_set_size(gauge, 200, 180);
lv_obj_set_size(gauge, 186, 186);
lv_obj_align(gauge, NULL, LV_ALIGN_CENTER, 0, 0);

// Second tab, make a chart...
Expand All @@ -118,11 +116,11 @@ void lvgl_setup(void) {
lv_canvas_set_buffer(canvas, canvas_buffer,
CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
lv_obj_align(canvas, NULL, LV_ALIGN_CENTER, 0, 0);
lv_canvas_fill_bg(canvas, LV_COLOR_WHITE);
// Set up canvas line-drawing style based on the "plain" defaults.
// Later we'll fiddle with the color settings when drawing each line.
lv_style_copy(&draw_style, &lv_style_plain);
lv_canvas_fill_bg(canvas, LV_COLOR_WHITE, LV_OPA_100);

// Set up canvas line-drawing style based on defaults.
// Later we'll change color settings when drawing each line.
lv_draw_line_dsc_init(&draw_dsc);
}

void setup(void) {
Expand Down Expand Up @@ -190,10 +188,10 @@ void loop(void) {
points[0].y = random(CANVAS_HEIGHT);
points[1].x = random(CANVAS_WIDTH);
points[1].y = random(CANVAS_HEIGHT);
draw_style.line.color.ch.red = random();
draw_style.line.color.ch.green = random();
draw_style.line.color.ch.blue = random();
lv_canvas_draw_line(canvas, points, 2, &draw_style);
draw_dsc.color.ch.red = random();
draw_dsc.color.ch.green = random();
draw_dsc.color.ch.blue = random();
lv_canvas_draw_line(canvas, points, 2, &draw_dsc);
// This forces the canvas to update (otherwise changes aren't
// seen unless leaving and returning to the canvas tab):
lv_canvas_set_buffer(canvas, canvas_buffer,
Expand Down
Loading

0 comments on commit 5b69c8d

Please sign in to comment.