diff --git a/.gitmodules b/.gitmodules index 2ebfb8a..5647056 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,3 +37,12 @@ [submodule "extras/multipwm"] path = extras/multipwm url = https://github.com/nochkin/multipwm +[submodule "lvgl/lvgl"] + path = lvgl/lvgl + url = https://github.com/littlevgl/lvgl.git +[submodule "lvgl/lv_drivers"] + path = lvgl/lv_drivers + url = https://github.com/littlevgl/lv_drivers.git +[submodule "lvgl/lv_examples"] + path = lvgl/lv_examples + url = https://github.com/littlevgl/lv_examples.git diff --git a/examples/lvgl_ssd1306/Makefile b/examples/lvgl_ssd1306/Makefile new file mode 100644 index 0000000..b11bbb5 --- /dev/null +++ b/examples/lvgl_ssd1306/Makefile @@ -0,0 +1,4 @@ +PROGRAM = LVGL_SSD1306 +EXTRA_COMPONENTS = lvgl extras/i2c + +include ../../common.mk diff --git a/examples/lvgl_ssd1306/lv_conf.h b/examples/lvgl_ssd1306/lv_conf.h new file mode 100644 index 0000000..48235dd --- /dev/null +++ b/examples/lvgl_ssd1306/lv_conf.h @@ -0,0 +1,316 @@ +/** + * @file lv_conf.h + * + */ +#ifndef LV_CONF_H +#define LV_CONF_H + +//include complement to LV_TICK_CUSTOM_INCLUDE. +#include "FreeRTOS.h" + +/*=================== + Dynamic memory + *===================*/ + +/* Memory size which will be used by the library + * to store the graphical objects and other data */ +#define LV_MEM_CUSTOM 1 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/ +#if LV_MEM_CUSTOM == 0 +#define LV_MEM_SIZE (32U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +#define LV_MEM_ATTR /*Complier prefix for big array declaration*/ +#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ +#else /*LV_MEM_CUSTOM*/ +#define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ +#define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ +#define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ + +/*=================== + Graphical settings + *===================*/ + +/* Horizontal and vertical resolution of the library.*/ +#define LV_HOR_RES (128) +#define LV_VER_RES (64) +#define LV_DPI (72) + +/* Size of VDB (Virtual Display Buffer: the internal graphics buffer). + * Required for buffered drawing, opacity and anti-aliasing + * VDB makes the double buffering, you don't need to deal with it! + * Typical size: ~1/10 screen */ +#define LV_VDB_SIZE (LV_VER_RES * LV_HOR_RES / 2) /*Size of VDB in pixel count (1/10 screen size is good for first)*/ +#define LV_VDB_PX_BPP 1 /*Bit-per-pixel of VDB. Useful for monochrome or non-standard color format displays. (Set `disp_drv->vdb_wr` and `disp_drv->vdb_rd` too)*/ +#define LV_VDB_ADR 0 /*Place VDB to a specific address (e.g. in external RAM) (0: allocate automatically into RAM; LV_VDB_ADR_INV: to replace it later with `lv_vdb_set_adr()`)*/ + +/* Use two Virtual Display buffers (VDB) parallelize rendering and flushing (optional) + * The flushing should use DMA to write the frame buffer in the background*/ +#define LV_VDB_DOUBLE 0 /*1: Enable the use of 2 VDBs*/ +#define LV_VDB2_ADR 0 /*Place VDB2 to a specific address (e.g. in external RAM) (0: allocate automatically into RAM; LV_VDB_ADR_INV: to replace it later with `lv_vdb_set_adr()`)*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 0 /*1: Enable anti-aliasing*/ + +/*Screen refresh settings*/ +#define LV_REFR_PERIOD 50 /*Screen refresh period in milliseconds*/ +#define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */ + +/*================= + Misc. setting + *=================*/ + +/*Input device settings*/ +#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ +#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/ +#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ +#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */ +#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/ +#define LV_INDEV_LONG_PRESS_REP_TIME 100 /*Repeated trigger period in long press [ms] */ + +/*Color settings*/ +#define LV_COLOR_DEPTH 1 /*Color depth: 1/8/16/32*/ +#define LV_COLOR_16_SWAP 0 /*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/ +#define LV_COLOR_SCREEN_TRANSP 0 /*1: Enable screen transparency. Useful for OSD or other overlapping GUIs. Requires ARGB8888 colors*/ +#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/ + +/*Text settings*/ +#define LV_TXT_UTF8 0 /*Enable UTF-8 coded Unicode character usage */ +#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ + +/*Graphics feature usage*/ +#define USE_LV_ANIMATION 1 /*1: Enable all animations*/ +#define USE_LV_SHADOW 0 /*1: Enable shadows*/ +#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ +#define USE_LV_GPU 0 /*1: Enable GPU interface*/ +#define USE_LV_REAL_DRAW 1 /*1: Enable function which draw directly to the frame buffer instead of VDB (required if LV_VDB_SIZE = 0)*/ +#define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/ + +/*Compiler settings*/ +#define LV_ATTRIBUTE_TICK_INC __attribute__((section(".iram1.text"))) /* Define a custom attribute to `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TASK_HANDLER __attribute__((section(".iram1.text"))) /* Define a custom attribute to `lv_task_handler` function */ +#define LV_COMPILER_VLA_SUPPORTED 0 /* 1: Variable length array is supported*/ +#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 0 /* 1: Initialization with non constant values are supported */ + +/*HAL settings*/ +#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */ +#if LV_TICK_CUSTOM == 1 +#define LV_TICK_CUSTOM_INCLUDE "task.h" +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (xTaskGetTickCount()*10) /*Expression evaluating to current systime in ms*/ +#endif /*LV_TICK_CUSTOM*/ + + +/*Log settings*/ +#define USE_LV_LOG 0 /*Enable/disable the log module*/ +#if USE_LV_LOG +/* How important log should be added: + * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + * LV_LOG_LEVEL_INFO Log important events + * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't caused problem + * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + */ +#define LV_LOG_LEVEL LV_LOG_LEVEL_INFO +/* 1: Print the log with 'printf'; 0: user need to register a callback*/ + +#define LV_LOG_PRINTF 0 +#endif /*USE_LV_LOG*/ + +/*================ + * THEME USAGE + *================*/ +#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/ + +#define USE_LV_THEME_TEMPL 0 /*Just for test*/ +#define USE_LV_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/ +#define USE_LV_THEME_ALIEN 0 /*Dark futuristic theme*/ +#define USE_LV_THEME_NIGHT 0 /*Dark elegant theme*/ +#define USE_LV_THEME_MONO 0 /*Mono color theme for monochrome displays*/ +#define USE_LV_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/ +#define USE_LV_THEME_ZEN 0 /*Peaceful, mainly light theme */ +#define USE_LV_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/ + +/*================== + * FONT USAGE + *===================*/ + +/* More info about fonts: https://littlevgl.com/basics#fonts + * To enable a built-in font use 1,2,4 or 8 values + * which will determine the bit-per-pixel */ +#define USE_LV_FONT_DEJAVU_10 1 +#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_10_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_10 1 + +#define USE_LV_FONT_DEJAVU_20 1 +#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_20_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_20 1 + +#define USE_LV_FONT_DEJAVU_30 1 +#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_30_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_30 1 + +#define USE_LV_FONT_DEJAVU_40 0 +#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_40_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_40 0 + +#define USE_LV_FONT_MONOSPACE_8 0 + +/* Optionally declare your custom fonts here. + * You can use these fonts as default font too + * and they will be available globally. E.g. + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ + * LV_FONT_DECLARE(my_font_2) \ + */ +#define LV_FONT_CUSTOM_DECLARE + +#define LV_FONT_DEFAULT &lv_font_dejavu_10 /*Always set a default font from the built-in fonts*/ + +/*=================== + * LV_OBJ SETTINGS + *==================*/ +#define LV_OBJ_FREE_NUM_TYPE uint32_t /*Type of free number attribute (comment out disable free number)*/ +#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/ + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://littlevgl.com/object-types + */ + +/***************** + * Simple object + *****************/ + +/*Label (dependencies: -*/ +#define USE_LV_LABEL 1 +#if USE_LV_LABEL != 0 +#define LV_LABEL_SCROLL_SPEED 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/ +#endif + +/*Image (dependencies: lv_label*/ +#define USE_LV_IMG 1 +#if USE_LV_IMG != 0 +#define LV_IMG_CF_INDEXED 1 /*Enable indexed (palette) images*/ +#define LV_IMG_CF_ALPHA 1 /*Enable alpha indexed images*/ +#endif + +/*Line (dependencies: -*/ +#define USE_LV_LINE 1 + +/*Arc (dependencies: -)*/ +#define USE_LV_ARC 1 + +/******************* + * Container objects + *******************/ + +/*Container (dependencies: -*/ +#define USE_LV_CONT 1 + +/*Page (dependencies: lv_cont)*/ +#define USE_LV_PAGE 1 + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define USE_LV_WIN 1 + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define USE_LV_TABVIEW 1 +#if USE_LV_TABVIEW != 0 +#define LV_TABVIEW_ANIM_TIME 300 /*Time of slide animation [ms] (0: no animation)*/ +#endif + +/************************* + * Data visualizer objects + *************************/ + +/*Bar (dependencies: -)*/ +#define USE_LV_BAR 1 + +/*Line meter (dependencies: *;)*/ +#define USE_LV_LMETER 1 + +/*Gauge (dependencies:bar, lmeter)*/ +#define USE_LV_GAUGE 1 + +/*Chart (dependencies: -)*/ +#define USE_LV_CHART 1 + +/*LED (dependencies: -)*/ +#define USE_LV_LED 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define USE_LV_MBOX 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define USE_LV_TA 1 +#if USE_LV_TA != 0 +#define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/ +#define LV_TA_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +/*Calendar (dependencies: -)*/ +#define USE_LV_CALENDAR 1 + +/*Preload (dependencies: arc)*/ +#define USE_LV_PRELOAD 1 +#if USE_LV_PRELOAD != 0 +#define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/ +#define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ +#endif + +/************************* + * User input objects + *************************/ + +/*Button (dependencies: lv_cont*/ +#define USE_LV_BTN 1 +#if USE_LV_BTN != 0 +#define LV_BTN_INK_EFFECT 1 /*Enable button-state animations - draw a circle on click (dependencies: USE_LV_ANIMATION)*/ +#endif + +/*Image Button (dependencies: lv_btn*/ +#define USE_LV_IMGBTN 1 + +/*Button matrix (dependencies: -)*/ +#define USE_LV_BTNM 1 + +/*Keyboard (dependencies: lv_btnm)*/ +#define USE_LV_KB 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define USE_LV_CB 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ +#define USE_LV_LIST 1 +#if USE_LV_LIST != 0 +#define LV_LIST_FOCUS_TIME 100 /*Default animation time of focusing to a list element [ms] (0: no animation) */ +#endif + +/*Drop down list (dependencies: lv_page, lv_label)*/ +#define USE_LV_DDLIST 1 +#if USE_LV_DDLIST != 0 +#define LV_DDLIST_ANIM_TIME 200 /*Open and close default animation time [ms] (0: no animation)*/ +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define USE_LV_ROLLER 1 +#if USE_LV_ROLLER != 0 +#define LV_ROLLER_ANIM_TIME 200 /*Focus animation time [ms] (0: no animation)*/ +#endif + +/*Slider (dependencies: lv_bar)*/ +#define USE_LV_SLIDER 1 + +/*Switch (dependencies: lv_slider)*/ +#define USE_LV_SW 1 + +/************************* + * Non-user section + *************************/ +#ifdef _MSC_VER /* Disable warnings for Visual Studio*/ +# define _CRT_SECURE_NO_WARNINGS +#endif + +#endif /*LV_CONF_H*/ diff --git a/examples/lvgl_ssd1306/lv_drv_conf.h b/examples/lvgl_ssd1306/lv_drv_conf.h new file mode 100644 index 0000000..00788c7 --- /dev/null +++ b/examples/lvgl_ssd1306/lv_drv_conf.h @@ -0,0 +1,578 @@ +/** + * @file lv_drv_conf.h + * + */ + +#if 1 /*Remove this to enable the content*/ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * INCLUDES + *********************/ +/* Add specific sdk include here */ +#include +#include +#include +#include + +#include +#include +#include +/********************* + * DEFINES + *********************/ +/* Disable with 0 if driver don't use an specific api */ +#define LV_DRIVER_ENABLE_COMMON 1 +#define LV_DRIVER_ENABLE_DELAY 1 +#define LV_DRIVER_ENABLE_I2C 1 +#define LV_DRIVER_ENABLE_SPI 1 +#define LV_DRIVER_ENABLE_PAR 1 + +/* use this macro if you want ignore a gpio write/read. e.g: spi.cs = LV_DRIVER_NOPIN */ +#define LV_DRIVER_NOPIN (0xFF) + +/* use this macro to add specific attribute to function call into an interupt routines */ +#define INTERUPT_ATTRIBUTE __attribute__((section(".iram1.text"))) + +/********************** + * TYPEDEFS + **********************/ +/* You can use a pointer handler or just a id number to reder to a device + * e.g: typedef const uint8_t lv_gpio_handle_t if you need just a bus id + * You can use device descriptor from your sdk too. + */ +//typedef const void* lv_gpio_handle_t ; +//typedef const void* lv_i2c_handle_t ; +//typedef const void* lv_spi_handle_t ; +typedef const void* lv_par_handle_t ; +typedef const void* lv_uart_handle_t ; + +typedef struct { + uint8_t bus; + uint8_t cs; + uint8_t dc; + spi_settings_t *s; //XXX:experimental for multi spi device + SemaphoreHandle_t* mutex; //XXX:experimental for multi spi device +} lv_spi_dev_t, *lv_spi_handle_t; + +typedef const i2c_dev_t *lv_i2c_handle_t ; +typedef uint8_t lv_gpio_handle_t ; + +/********************* + * HAL INTERFACE + *********************/ +/* + * All used peripherals must be initialized in user application, library only + * manipulate them. + * You can use a device descriptor from your SDK or do your own in this file too. + * example: + * typedef struct lv_spi_dev_t { .... }; + */ + +/*------------ + * Delay + *------------*/ +#if LV_DRIVER_ENABLE_DELAY + +/** + * Delay the given number of microseconds + * @param us Time to wait in us + */ +static inline void lv_delay_us(const uint32_t us) +{ + sdk_os_delay_us(us); +} + +/** + * Delay the given number of milliseconds + * @param ms Time to wait in ms + */ +static inline void lv_delay_ms(const uint32_t ms) +{ + if (ms/portTICK_PERIOD_MS) //if we wait more than a tick, use vTaskDelay + { + vTaskDelay(((ms-1)/portTICK_PERIOD_MS)+1); //Round superior + return; + } + for (uint32_t x = 0 ; x < ms ; x++) + { + sdk_os_delay_us(1000); + } +} + +/** + * Return system time + * @return system time (ms) + */ +static inline uint32_t lv_get_ms() +{ + return xTaskGetTickCount()*portTICK_PERIOD_MS; +} + +#endif +/*------------ + * Common + *------------*/ +#if LV_DRIVER_ENABLE_COMMON + +/** + * Change a pin level + * @param pin gpio Number + * @param val Level to set + */ +static inline void lv_gpio_write(lv_gpio_handle_t gpio, const uint8_t val) +{ + gpio_write(gpio, val); +} + +/** + * Read current level gpio + * @param pin gpio to read + * @return gpio value + */ +static inline uint8_t lv_gpio_read(lv_gpio_handle_t gpio) +{ + return gpio_read(gpio); +} + +#endif + +/*--------- + * UART + *---------*/ +/** + * Do a uart write transmission. + * @param uart_dev Pointer to uart device + * @param data_out Pointer to data buffer to send if non-null + * @param datalen Number of data byte to send + * @return Non-Zero if error occured + */ +static inline int lv_uart_write(lv_uart_handle_t uart_dev, const void* data_out, uint16_t datalen) +{ + return -1; +} + +/** + * Do a uart read transmission + * @param uart_dev Pointer to uart device + * @param data_out Pointer to data buffer to send if non-null + * @param datalen Number of data byte to read + * @return Non-Zero if error occured + */ +static inline int lv_uart_read(lv_uart_handle_t uart_dev, void* data_in, uint16_t datalen) +{ + return -1; +} + +/*--------- + * I2C + *---------*/ +#if LV_DRIVER_ENABLE_I2C + +/** + * Do a I2C write transmission on 8 bits register device. + * @param i2c_dev Pointer to i2c device + * @param reg Pointer to register address to send if non-null + * @param data_out Pointer to data buffer to send if non-null + * @param datalen Number of data byte to send + * @return Non-Zero if error occured + */ +static inline int lv_i2c_write(lv_i2c_handle_t i2c_dev, const uint8_t* reg, const void* data_out, uint16_t datalen) +{ + return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, reg, (uint8_t*)data_out, datalen); +} + +/** + * Do a I2C read transmission on 8 bits register device. + * @param i2c_dev Pointer to i2c device + * @param reg Pointer to register address to send if non-null + * @param data_out Pointer to data buffer to send if non-null + * @param datalen Number of data byte to send + * @return Non-Zero if error occured + */ +static inline int lv_i2c_read(lv_i2c_handle_t i2c_dev, const uint8_t* reg, void* data_in, uint16_t datalen) +{ + return i2c_slave_read(i2c_dev->bus, i2c_dev->addr, reg, (uint8_t*)data_in, datalen); +} + +/** + * Do a I2C write transmissionon 16 bits register device + * @param i2c_dev Pointer to i2c device + * @param reg Pointer to register address to send if non-null + * @param data_out Pointer to data buffer to send if non-null + * @param datalen Number of data byte to send + * @return Non-Zero if error occured + */ +static inline int lv_i2c_write16(lv_i2c_handle_t i2c_dev, const uint16_t* reg, const void* data_out, uint16_t datalen) +{ + return -1; +} + +/** + * Do a I2C write transmissionon 16 bits register device. + * @param i2c_dev Pointer to i2c device + * @param reg Pointer to register address to send if non-null + * @param data_out Pointer to data buffer to send if non-null + * @param datalen Number of data byte to send + * @return Non-Zero if error occured + */ +static inline int lv_i2c_read16(lv_i2c_handle_t i2c_dev, const uint16_t* reg, void* data_in, uint16_t datalen) +{ + return -1; +} + +#endif +/*--------- + * SPI + *---------*/ +#if LV_DRIVER_ENABLE_SPI + +typedef enum { + LV_SPI_COMMAND, + LV_SPI_ADDRESS, + LV_SPI_DUMMY, +} lv_spi_reg_t; + +/** + * Control SPI cs pin. + * @param spi_dev Pointer to spi device + * @param lvl Gpio Level + */ +static inline void lv_spi_wr_cs(lv_spi_handle_t spi_dev, uint8_t lvl) +{ + gpio_write(spi_dev->cs, lvl); +} + +/** + * Control SPI dc pin. + * @param spi_dev Pointer to spi device + * @param lvl Gpio Level + */ +static inline void lv_spi_wr_dc(lv_spi_handle_t spi_dev, uint8_t lvl) +{ + gpio_write(spi_dev->dc, lvl); +} + +/** + * Do a SPI transaction . + * @param spi_dev Pointer to spi device + * @param data_in Receive buffer. If NULL, received data will be lost. + * @param data_out Data to send buffer. If NULL, it will only receive data. + * @param len Buffer size in words + * @param word_size Size of the word in byte + * @return Non-Zero if error occured + */ +static inline int lv_spi_transaction(lv_spi_handle_t spi_dev, void* data_in, const void* data_out, uint16_t len, uint8_t word_size) +{ + spi_transfer(spi_dev->bus, data_out, data_in, len, word_size); + return 0; +} + +/** + * Do a SPI repeat send. + * @param spi_dev Pointer to spi device + * @param template Pointer toTemplate to send throw spi. + * @param repeats Copy number + * @param template_size Size of the template in byte + * @return Non-Zero if error occured + */ +static inline int lv_spi_repeat(lv_spi_handle_t spi_dev, const void* template, uint32_t repeats, uint8_t template_size) +{ + uint32_t data = 0; + if(!template) + { + template = (void*)&data ; + } + switch (template_size) + { + case 1: + spi_repeat_send_8(spi_dev->bus,*(uint8_t*)template,repeats); + break; + case 2: + spi_repeat_send_16(spi_dev->bus,*(uint16_t*)template,repeats); + break; + case 4: + spi_repeat_send_32(spi_dev->bus,*(uint32_t*)template,repeats); + break; + default: + return -1; + break; + } + return 0; +} + +/** + * Set command to send for spi transaction + * @param spi_dev Pointer to spi device + * @param reg SPI register to set (dummy/command/address) + * @param value Value + * @param bits Bits number + * @return Non-Zero if error occured + */ +static inline int lv_spi_set_preemble(lv_spi_handle_t spi_dev, lv_spi_reg_t reg, uint32_t value, uint8_t bits) +{ + switch(reg) { + case LV_SPI_COMMAND: + spi_set_command(spi_dev->bus, bits, value); + break; + case LV_SPI_ADDRESS: + spi_set_address(spi_dev->bus, bits, value); + break; + case LV_SPI_DUMMY: + spi_set_dummy_bits(spi_dev->bus, bits, false); + break; + default: + return -1; + break; + } + return 0; +} + +/** + * Clear spi bus command + * @param spi_dev Pointer to spi device + * @param reg SPI register to clear (dummy/command/address) + * @return Non-Zero if error occured + */ +static inline int lv_spi_clr_preemble(lv_spi_handle_t spi_dev, lv_spi_reg_t reg) +{ + switch(reg) { + case LV_SPI_COMMAND: + spi_clear_command(spi_dev->bus); + break; + case LV_SPI_ADDRESS: + spi_clear_address(spi_dev->bus); + break; + case LV_SPI_DUMMY: + spi_clear_dummy(spi_dev->bus); + break; + default: + return -1; + break; + } + return 0; +} + +#endif +/*------------------ + * Parallel port + *-----------------*/ +#if LV_DRIVER_ENABLE_PAR +/** + * Control Parallel cs pin. + * @param par_dev Pointer to parallel device + * @param lvl Gpio Level + */ +static inline void lv_par_wr_cs(lv_par_handle_t par_dev, uint8_t lvl) +{ + return; +} + +/** + * Control Parallel dc pin. + * @param par_dev Pointer to parallel device + * @param lvl Gpio Level + */ +static inline void lv_par_wr_dc(lv_par_handle_t par_dev, uint8_t lvl) +{ + return; +} + +/** + * Do a Parallel port write. + * @param par_dev Pointer to parallel port device + * @param data_out Pointer to data buffer to send + * @param len Buffer size in words + * @param word_size Size of the word in byte + * @return Non-Zero if error occured + */ +static inline int lv_par_write(lv_par_handle_t par_dev, const void* data_out, uint16_t len, uint8_t word_size) +{ + return -1; +} + +/** + * Do a Parallel port read. + * @param par_dev Pointer to parallel port device + * @param data_in Pointer to data buffer to read + * @param len Buffer size in words + * @param word_size Size of the word in byte + * @return Non-Zero if error occured + */ +static inline int lv_par_read(lv_par_handle_t par_dev, void* data_in, uint16_t len, uint8_t word_size) +{ + return -1; +} + +#endif +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * Monitor of PC + *-------------------*/ +#define USE_MONITOR 0 +#if USE_MONITOR +#define MONITOR_HOR_RES LV_HOR_RES +#define MONITOR_VER_RES LV_HOR_VER +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#define USE_SSD1963 0 +#if USE_SSD1963 +#define SSD1963_HOR_RES LV_HOR_RES +#define SSD1963_VER_RES LV_VER_RES +#define SSD1963_HDP 479 +#define SSD1963_HT 531 +#define SSD1963_HPS 43 +#define SSD1963_LPS 8 +#define SSD1963_HPW 10 +#define SSD1963_VDP 271 +#define SSD1963_VT 288 +#define SSD1963_VPS 12 +#define SSD1963_FPS 4 +#define SSD1963_VPW 10 +#define SSD1963_HS_NEG 0 /*Negative hsync*/ +#define SSD1963_VS_NEG 0 /*Negative vsync*/ +#define SSD1963_ORI 0 /*0, 90, 180, 270*/ +#define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * ILI9341 + *--------------*/ +#define USE_ILI9341 0 +#if USE_ILI9341 +#define ILI9341_DEBUG 0 +#define ILI9341_ERR_CHECK 1 +#define ILI9341_PAR_SUPPORT 1 +#define ILI9341_SPI4WIRE_SUPPORT 1 +#define ILI9341_SPI3WIRE_SUPPORT 1 +#define ILI9341_EXTC_SUPPORT (0) +#define ILI9341_COLOR (65) //Color Mode : 65K or 262K +#define ILI9341_MAX_SAMPLE (32) //Buffer spi is 64, so select 32 for 2byte per pixel +#define ILI9341_SERIAL_BYTESWAP (0) // { 0 : None, 1: CPU Swap, 2: ILI9341 swap } +#endif + +/*---------------- + * SSD1306 + *--------------*/ +#define USE_SSD1306 1 +#if USE_SSD1306 +#define SSD1306_HOR_RES LV_HOR_RES +#define SSD1306_VER_RES LV_VER_RES +#define SSD1306_DEBUG 0 +#define SSD1306_ERR_CHECK 0 +#define SSD1306_I2C_SUPPORT 1 +#define SSD1306_SPI_4_WIRE_SUPPORT 1 +#define SSD1306_SPI_3_WIRE_SUPPORT 1 +#endif + +/*---------------- + * R61581 + *--------------*/ +#define USE_R61581 0 +#if USE_R61581 != 0 +#define R61581_HOR_RES LV_HOR_RES +#define R61581_VER_RES LV_VER_RES +#define R61581_HDP 479 +#define R61581_HT 531 +#define R61581_HPS 43 +#define R61581_LPS 8 +#define R61581_HPW 10 +#define R61581_VDP 271 +#define R61581_VT 319 +#define R61581_VPS 12 +#define R61581_FPS 4 +#define R61581_VPW 10 +#define R61581_HS_NEG 0 /*Negative hsync*/ +#define R61581_VS_NEG 0 /*Negative vsync*/ +#define R61581_ORI 180 /*0, 90, 180, 270*/ +#define R61581_LV_COLOR_DEPTH 16 +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#define USE_ST7565 0 +#if USE_ST7565 != 0 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#define USE_FBDEV 0 +#if USE_FBDEV != 0 +#define FBDEV_PATH "/dev/fb0" +#endif + +/*==================== + * Input devices + *===================*/ + +/*-------------- + * AR1000 + *--------------*/ +#define USE_AR10XX (1) +#if (USE_AR10XX != 0) +#define AR10XX_SPI_SUPPORT (1) +#define AR10XX_I2C_SUPPORT (1) +#define AR10XX_UART_SUPPORT (0) +#define AR10XX_DEBUG (1) +#define AR10XX_ERR_CHECK (0) +#define AR10XX_VERIFY_ANSWER (1) +#define AR10XX_USE_IRQ (0) +#define AR10XX_COMPONENT (21) // Version of XX (10, 11, 20 , 21) +#endif + +/*-------------- + * XPT2046 + *--------------*/ +#define USE_XPT2046 0 +#if USE_XPT2046 != 0 +#define XPT2046_HOR_RES 480 +#define XPT2046_VER_RES 320 +#define XPT2046_X_MIN 200 +#define XPT2046_Y_MIN 200 +#define XPT2046_X_MAX 3800 +#define XPT2046_Y_MAX 3800 +#define XPT2046_AVG 4 +#define XPT2046_INV 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#define USE_FT5406EE8 0 +#if USE_FT5406EE8 +#define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*------------------------------- + * Mouse or touchpad on PC + *------------------------------*/ +#define USE_MOUSE 0 +#if USE_MOUSE +/*No settings*/ +#endif + + +/*------------------------------- + * Keyboard of a PC + *------------------------------*/ +#define USE_KEYBOARD 0 +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ + +#endif /*Remove this to enable the content*/ diff --git a/examples/lvgl_ssd1306/main.c b/examples/lvgl_ssd1306/main.c new file mode 100644 index 0000000..8ebd57e --- /dev/null +++ b/examples/lvgl_ssd1306/main.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include +#include +#include +#include "lv_conf.h" +#include "lvgl/lvgl.h" +#include "lv_drivers/display/SSD1306.h" + +#define I2C_CONNECTION false +#define TICK_HANDLER false +#define OVERCLOCK false + +#define TICK_INC_MS (10) +#define RST_PIN (LV_DRIVER_NOPIN) +#define SECOND (1000 / portTICK_PERIOD_MS) + +#if (I2C_CONNECTION) +#include +#endif + +#if (I2C_CONNECTION) +#define PROTOCOL SSD1306_PROTO_I2C +#define ADDR SSD1306_I2C_ADDR_0 +#define I2C_BUS 0 +#define SCL_PIN 5 +#define SDA_PIN 4 + +const static i2c_dev_t i2c_dev = +{ + .bus = I2C_BUS, + .addr = ADDR +}; +#else +#define PROTOCOL SSD1306_PROTO_SPI3 +#define SPI_BUS 1 +#define CS_PIN 15 +#define DC_PIN 4 +/*Delare bus descriptor */ +const static lv_spi_dev_t spi_dev = +{ + .bus = SPI_BUS, + .cs = CS_PIN, + .dc = DC_PIN, +}; +#endif + +/* Declare device descriptor */ +static ssd1306_t dev; + +TimerHandle_t fps_timer_handle = NULL; // Timer handler +TimerHandle_t font_timer_handle = NULL; +TimerHandle_t lvgl_timer_handle = NULL; + +static lv_style_t style; +static lv_obj_t * label; + +static void ssd1306_task(void *pvParameters) +{ + printf("%s: Started user interface task\n", __FUNCTION__); + vTaskDelay(SECOND); + ssd1306_set_whole_display_lighting(&dev, false); + + //Set a style for the obj + lv_style_copy(&style, &lv_style_transp); + style.text.font = &lv_font_dejavu_10; /*Unicode and symbol fonts already assigned by the library*/ + style.text.color.full = 1; + style.text.opa = 255; + + style.body.main_color.full = 0; + style.body.grad_color.full = 0; + style.body.shadow.color.full = 0; + style.body.border.color.full = 0; + style.body.empty = 1; + + style.image.color.full = 1; + style.image.intense = 255; + style.image.opa = 255; + + style.line.color.full = 1; + style.line.opa = 255; + style.line.width = 1; + style.line.rounded = false; + + //Create main screen obj + lv_obj_t * scr = lv_obj_create(NULL, NULL); + lv_scr_load(scr); + lv_obj_set_style(scr, &style); + + //Create a simple label + label = lv_label_create(lv_scr_act(), NULL); + lv_obj_set_style(label, &style); + + lv_obj_align(label, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0); + lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + lv_label_set_text(label, "lvgl work with esp-open-rtos"); + lv_obj_set_width(label, LV_HOR_RES); + + while (1) { + /*draw system call */ + lv_task_handler(); + vTaskDelay(1); + } +} + + +void font_timer(TimerHandle_t h) +{ + static uint8_t index = 0; + if (index >= 2) + index=0; + else + index++; + + switch (index) { + case 0: + style.text.font = &lv_font_dejavu_10; + break; + case 1: + style.text.font = &lv_font_dejavu_20; + break; + case 2: + style.text.font = &lv_font_dejavu_30; + break; + default: + break; + } + lv_label_set_style(label, &style); + printf("Selected builtin font %d\n", index); +} + + +#if (!LV_TICK_CUSTOM) +#if (TICK_HANDLER) +void IRAM vApplicationTickHook(void) { + lv_tick_inc(portTICK_PERIOD_MS); +} +#else +void lvgl_timer(TimerHandle_t xTimerHandle) +{ + lv_tick_inc(TICK_INC_MS); +} +#endif +#endif + +void user_init(void) +{ +#if (OVERCLOCK) + sdk_system_update_cpu_freq(160); +#endif + + // Setup HW + uart_set_baud(0, 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + +#if (I2C_CONNECTION) + i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K); +#else +#if (CS_PIN == 15) + spi_init(SPI_BUS, SPI_MODE0, SPI_FREQ_DIV_8M, true, SPI_LITTLE_ENDIAN, false); +#else + spi_init(SPI_BUS, SPI_MODE0, SPI_FREQ_DIV_8M, true, SPI_LITTLE_ENDIAN, true); + gpio_enable(CS_PIN, GPIO_OUTPUT); +#endif +#endif +#if (RST_PIN != LV_DRIVER_NOPIN) + gpio_enable(RST_PIN, GPIO_OUTPUT); +#endif + + /*Gui initialization*/ + lv_init(); + + /*Screen initialization*/ +#if (I2C_CONNECTION) + dev.i2c_dev = (lv_i2c_handle_t)&i2c_dev; +#else + dev.spi_dev = (lv_spi_handle_t)&spi_dev; +#endif + dev.protocol = PROTOCOL ; //SSD1306_PROTO_SPI3; + dev.screen = SH1106_SCREEN; //SSD1306_SCREEN, SH1106_SCREEN + dev.width = LV_HOR_RES; + dev.height = LV_VER_RES; + dev.rst_pin = RST_PIN; //No RST PIN USED + + while (ssd1306_init(&dev) != 0) { + printf("%s: failed to init SSD1306 lcd\n", __func__); + vTaskDelay(SECOND); + } + + ssd1306_set_whole_display_lighting(&dev, true); + + /*inverse screen (180°) */ + ssd1306_set_scan_direction_fwd(&dev,true); + ssd1306_set_segment_remapping_enabled(&dev, false); + vTaskDelay(SECOND); + + /*lvgl screen registration */ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + /*Set up the functions to access to your display*/ + disp_drv.disp_flush = ssd1306_flush; /*Used in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/ + disp_drv.disp_fill = NULL;//ex_disp_fill; /*Used in unbuffered mode (LV_VDB_SIZE == 0 in lv_conf.h)*/ + disp_drv.disp_map = NULL;//ex_disp_map; /*Used in unbuffered mode (LV_VDB_SIZE == 0 in lv_conf.h)*/ + disp_drv.vdb_wr = ssd1306_vdb_wr; + lv_disp_drv_register(&disp_drv); + + /* Create user interface task */ + xTaskCreate(ssd1306_task, "ssd1306_task", 512, NULL, 2, NULL); + + font_timer_handle = xTimerCreate("font_timer", 5 * SECOND, pdTRUE, NULL, font_timer); + xTimerStart(font_timer_handle, 0); + +#if (!TICK_HANDLER && !LV_TICK_CUSTOM) + lvgl_timer_handle = xTimerCreate("lvgl_timer", TICK_INC_MS/portTICK_PERIOD_MS, pdTRUE, NULL, lvgl_timer); + xTimerStart(lvgl_timer_handle, 0); +#endif +} diff --git a/lvgl/component.mk b/lvgl/component.mk new file mode 100644 index 0000000..2c294e4 --- /dev/null +++ b/lvgl/component.mk @@ -0,0 +1,37 @@ +# Component makefile for lvgl/lvgl + +# expected anyone using this driver includes it as 'lvgl/lvgl.h' +INC_DIRS += $(lvgl_ROOT) + +# args for passing into compile rule generation +lvgl_SRC_DIR = $(lvgl_ROOT) \ + $(lvgl_ROOT)/lvgl \ + $(lvgl_ROOT)/lvgl/lv_core \ + $(lvgl_ROOT)/lvgl/lv_draw \ + $(lvgl_ROOT)/lvgl/lv_hal \ + $(lvgl_ROOT)/lvgl/lv_misc \ + $(lvgl_ROOT)/lvgl/lv_fonts \ + $(lvgl_ROOT)/lvgl/lv_objx \ + $(lvgl_ROOT)/lvgl/lv_themes \ + $(lvgl_ROOT)/lv_drivers/display \ + $(lvgl_ROOT)/lv_drivers/indev + +LVGL_DIR := $(dir $(lastword $(MAKEFILE_LIST))) + +#EXTRA_CFLAGS += -DLV_CONF_INCLUDE_SIMPLE=1 + +#include $(LVGL_DIR)defaults.mk +# +#fonts_CFLAGS = $(CFLAGS) \ + -DLV_HOR_RES=$(LV_HOR_RES) \ + -DLV_VER_RES=$(LV_VER_RES) \ + -DLV_DPI=$(LV_DPI) \ + -DLV_VDB_SIZE=$(LV_VDB_SIZE) \ + -DLV_VDB_ADR=$(LV_VDB_ADR) \ + -DLV_VDB_DOUBLE=$(LV_VDB_DOUBLE) \ + -DLV_VDB2_ADR=$(LV_VDB2_ADR) \ + -DLV_ANTIALIAS=$(LV_ANTIALIAS) \ + -DLV_FONT_ANTIALIAS=$(LV_FONT_ANTIALIAS) \ + -DLV_REFR_PERIOD=$(LV_REFR_PERIOD) + +$(eval $(call component_compile_rules,lvgl)) diff --git a/lvgl/lv_conf.h b/lvgl/lv_conf.h new file mode 100644 index 0000000..180c1c9 --- /dev/null +++ b/lvgl/lv_conf.h @@ -0,0 +1,3 @@ + +/* Use the defaults for everything else */ +#include_next diff --git a/lvgl/lv_drivers b/lvgl/lv_drivers new file mode 160000 index 0000000..8fe0804 --- /dev/null +++ b/lvgl/lv_drivers @@ -0,0 +1 @@ +Subproject commit 8fe0804ceb875193a37106a2e25d07c106650a86 diff --git a/lvgl/lv_drv_conf.h b/lvgl/lv_drv_conf.h new file mode 100644 index 0000000..b69f377 --- /dev/null +++ b/lvgl/lv_drv_conf.h @@ -0,0 +1,3 @@ + +/* Use the defaults for everything else */ +#include_next diff --git a/lvgl/lv_examples b/lvgl/lv_examples new file mode 160000 index 0000000..c3afbc9 --- /dev/null +++ b/lvgl/lv_examples @@ -0,0 +1 @@ +Subproject commit c3afbc9819f5492a7fe7e7e18a37df95fb60f449 diff --git a/lvgl/lvgl b/lvgl/lvgl new file mode 160000 index 0000000..41695bf --- /dev/null +++ b/lvgl/lvgl @@ -0,0 +1 @@ +Subproject commit 41695bf9ac758ae3276424e06308e1bb89c4c019