Module improvements: lvgl, gps, crypt (#585)

This commit is contained in:
Ken Van Hoeylandt
2026-07-25 23:04:39 +02:00
committed by GitHub
parent ca5b071859
commit db7468d0c8
92 changed files with 261 additions and 271 deletions
+58
View File
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Affects LVGL widget style */
enum UiDensity {
/** Ideal for very small non-touch screen devices (e.g. Waveshare S3 LCD 1.3") */
LVGL_UI_DENSITY_COMPACT,
/** Nothing was changed in the LVGL UI/UX */
LVGL_UI_DENSITY_DEFAULT
};
/**
* @brief Locks the LVGL mutex.
*
* This should be called before any LVGL API calls from threads other than the LVGL task.
* It is a recursive mutex.
* @retval true when a lock was acquired, false otherwise
*/
void lvgl_lock(void);
/**
* @brief Tries to lock the LVGL mutex with a timeout.
*
* @param timeout Timeout in ticks
* @return true if the lock was acquired, false otherwise.
*/
bool lvgl_try_lock(uint32_t timeout);
/**
* @brief Unlocks the LVGL mutex.
*/
void lvgl_unlock(void);
/**
* @brief Checks if the LVGL module is currently running.
*
* @return true if running, false otherwise.
*/
bool lvgl_is_running(void);
/**
* @brief Gets the desired UI density for the target hardware.
* The density is defined in the `device.properties` of a hardware device.
* This setting is read by CMakeLists.txt and passed as a target compile definition of the LVGL module.
* @return the UI density
*/
enum UiDensity lvgl_get_ui_density(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <lvgl.h>
#include <tactility/device.h>
#include <tactility/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configuration for binding a kernel DisplayApi device to an lv_display_t.
*/
struct LvglDisplayConfig {
/**
* Number of horizontal lines per draw buffer. 0 means the full vertical resolution.
* Ignored when the device exposes its own frame buffer(s) (display_get_frame_buffer_count() > 0).
*/
uint16_t buffer_height;
/**
* Allocates a second draw buffer for double buffering.
* Ignored when the device exposes its own frame buffer(s).
*/
bool double_buffer;
/**
* Rotate LVGL_rendered content in software instead of calling display_swap_xy()/display_mirror()
* on the device. Use this for panels whose driver can't rotate in hardware (e.g. RGB/DPI panels).
* Allocates one extra buffer sized like the primary draw buffer.
*/
bool sw_rotate;
/**
* Endianness of the 2 bytes of each RGB565/BGR565 pixel sent to the panel. False (default)
* keeps this little-endian CPU's native byte order (no-op). True swaps the 2 bytes of every
* pixel (big-endian) in the flush callback, via lv_draw_sw_rgb565_swap() - for panels that
* expect the opposite byte order over the bus. Ignored for color formats other than
* RGB565/BGR565 (e.g. RGB888, MONOCHROME).
*/
bool swap_bytes;
/**
* Forces LV_DISPLAY_RENDER_MODE_FULL with a full-resolution buffer, ignoring buffer_height,
* and always flushes the entire display rather than per-tile dirty regions. Set this when the
* device reports DISPLAY_CAPABILITY_REQUIRES_FULL_FRAME - see that capability's doc comment.
* Ignored when the device exposes its own frame buffer(s) (already always-full-frame) or uses
* the LV_COLOR_FORMAT_I1 path (already always-full-frame).
*/
bool force_full_frame;
};
/**
* @brief Creates an lv_display_t bound to the given DISPLAY_TYPE device and registers a flush callback
* that draws through the device's DisplayApi.
*
* The device's swap_xy/mirror_x/mirror_y state at the time of this call (via display_get_swap_xy() etc.)
* is treated as the LV_DISPLAY_ROTATION_0 baseline; LVGL-driven rotation changes are applied relative to it.
*
* @warning Caller must hold the LVGL lock (see lvgl_lock() in lvgl_module.h) — call this from
* LvglModuleConfig.on_start, or after calling lvgl_lock() explicitly.
*
* @param[in] device a device of type DISPLAY_TYPE
* @param[in] config binding configuration
* @param[out] out_display the created display, valid only when ERROR_NONE is returned
* @retval ERROR_NONE on success
* @retval ERROR_INVALID_ARGUMENT if device, config or out_display is NULL, or device is not of type DISPLAY_TYPE
* @retval ERROR_NOT_SUPPORTED if the device's color format has no LVGL equivalent
* @retval ERROR_OUT_OF_MEMORY if buffer or lv_display_t allocation failed
*/
error_t lvgl_display_add(struct Device* device, const struct LvglDisplayConfig* config, lv_display_t** out_display);
/**
* @brief Removes a display previously created with lvgl_display_add(), freeing any buffers it owns.
* @warning Caller must hold the LVGL lock.
*/
void lvgl_display_remove(lv_display_t* display);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <lvgl.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
enum LvglFontSize {
FONT_SIZE_SMALL,
FONT_SIZE_DEFAULT,
FONT_SIZE_LARGE,
};
const lv_font_t* lvgl_get_shared_icon_font(void);
uint32_t lvgl_get_shared_icon_font_height(void);
const lv_font_t* lvgl_get_text_font(enum LvglFontSize font_size);
uint32_t lvgl_get_text_font_height(enum LvglFontSize font_size);
const lv_font_t* lvgl_get_launcher_icon_font(void);
uint32_t lvgl_get_launcher_icon_font_height(void);
const lv_font_t* lvgl_get_statusbar_icon_font(void);
uint32_t lvgl_get_statusbar_icon_font_height(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,5 @@
#pragma once
#define LVGL_ICON_LAUNCHER_APPS "\xEE\x97\x83"
#define LVGL_ICON_LAUNCHER_FOLDER "\xEE\x8B\x87"
#define LVGL_ICON_LAUNCHER_SETTINGS "\xEE\xA2\xB8"
@@ -0,0 +1,45 @@
#pragma once
#define LVGL_ICON_SHARED_ADD "\xEE\x85\x85"
#define LVGL_ICON_SHARED_APPS "\xEE\x97\x83"
#define LVGL_ICON_SHARED_AREA_CHART "\xEE\x9D\xB0"
#define LVGL_ICON_SHARED_APP_REGISTRATION "\xEE\xBD\x80"
#define LVGL_ICON_SHARED_CALENDAR_MONTH "\xEE\xAF\x8C"
#define LVGL_ICON_SHARED_CABLE "\xEE\xBF\xA6"
#define LVGL_ICON_SHARED_CIRCLE "\xEE\xBD\x8A"
#define LVGL_ICON_SHARED_CLOSE "\xEE\x97\x8D"
#define LVGL_ICON_SHARED_CLOUD "\xEF\x85\x9C"
#define LVGL_ICON_SHARED_CHECK "\xEE\x97\x8A"
#define LVGL_ICON_SHARED_DELETE "\xEE\xA4\xAE"
#define LVGL_ICON_SHARED_DEVICES "\xEE\x8C\xA6"
#define LVGL_ICON_SHARED_DISPLAY_SETTINGS "\xEE\xAE\x97"
#define LVGL_ICON_SHARED_EDIT_NOTE "\xEE\x9D\x85"
#define LVGL_ICON_SHARED_ELECTRIC_BOLT "\xEE\xB0\x9C"
#define LVGL_ICON_SHARED_FOLDER "\xEE\x8B\x87"
#define LVGL_ICON_SHARED_DEPLOYED_CODE "\xEF\x9C\xA0"
#define LVGL_ICON_SHARED_DOWNLOAD "\xEF\x82\x90"
#define LVGL_ICON_SHARED_FORUM "\xEE\xA2\xAF"
#define LVGL_ICON_SHARED_GAMEPAD "\xEE\x8C\x8F"
#define LVGL_ICON_SHARED_HELP "\xEE\xA3\xBD"
#define LVGL_ICON_SHARED_HUB "\xEE\xA7\xB4"
#define LVGL_ICON_SHARED_IMAGE "\xEE\x8F\xB4"
#define LVGL_ICON_SHARED_KEYBOARD_ARROW_UP "\xEE\x8C\x96"
#define LVGL_ICON_SHARED_LIGHTBULB "\xEE\xA4\x8F"
#define LVGL_ICON_SHARED_LANGUAGE "\xEE\xA2\x94"
#define LVGL_ICON_SHARED_LISTS "\xEE\xA6\xB9"
#define LVGL_ICON_SHARED_MAIL "\xEE\x85\x99"
#define LVGL_ICON_SHARED_MENU "\xEE\x97\x92"
#define LVGL_ICON_SHARED_MOP "\xEE\x8A\x8D"
#define LVGL_ICON_SHARED_MORE_VERT "\xEE\x97\x94"
#define LVGL_ICON_SHARED_MUSIC_NOTE "\xEE\x90\x85"
#define LVGL_ICON_SHARED_NOTE_ADD "\xEE\xA2\x9C"
#define LVGL_ICON_SHARED_POWER_SETTINGS_NEW "\xEF\xA3\x87"
#define LVGL_ICON_SHARED_REFRESH "\xEE\x97\x95"
#define LVGL_ICON_SHARED_SEARCH "\xEE\xA2\xB6"
#define LVGL_ICON_SHARED_SETTINGS "\xEE\xA2\xB8"
#define LVGL_ICON_SHARED_TOOLBAR "\xEE\xA7\xB7"
#define LVGL_ICON_SHARED_NAVIGATION "\xEE\x95\x9D"
#define LVGL_ICON_SHARED_KEYBOARD_ALT "\xEF\x80\xA8"
#define LVGL_ICON_SHARED_USB "\xEE\x87\xA0"
#define LVGL_ICON_SHARED_WIFI "\xEE\x98\xBE"
#define LVGL_ICON_SHARED_BLUETOOTH "\xEE\x86\xA7"
@@ -0,0 +1,27 @@
#pragma once
#define LVGL_ICON_STATUSBAR_LOCATION_ON "\xEF\x87\x9B"
#define LVGL_ICON_STATUSBAR_CLOUD "\xEF\x85\x9C"
#define LVGL_ICON_STATUSBAR_MEMORY "\xEE\x8C\xA2"
#define LVGL_ICON_STATUSBAR_SD_CARD "\xEE\x98\xA3"
#define LVGL_ICON_STATUSBAR_SD_CARD_ALERT "\xEF\x81\x97"
#define LVGL_ICON_STATUSBAR_SIGNAL_WIFI_0_BAR "\xEF\x82\xB0"
#define LVGL_ICON_STATUSBAR_NETWORK_WIFI_1_BAR "\xEE\xAF\xA4"
#define LVGL_ICON_STATUSBAR_NETWORK_WIFI_2_BAR "\xEE\xAF\x96"
#define LVGL_ICON_STATUSBAR_NETWORK_WIFI_3_BAR "\xEE\xAF\xA1"
#define LVGL_ICON_STATUSBAR_SIGNAL_WIFI_4_BAR "\xEF\x81\xA5"
#define LVGL_ICON_STATUSBAR_SIGNAL_WIFI_OFF "\xEE\x87\x9A"
#define LVGL_ICON_STATUSBAR_SIGNAL_WIFI_BAD "\xEF\x81\xA4"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_1 "\xEF\x89\x97"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_2 "\xEF\x89\x96"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_3 "\xEF\x89\x95"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_4 "\xEF\x89\x94"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_5 "\xEF\x89\x93"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_6 "\xEF\x89\x92"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_FULL "\xEF\x89\x8F"
#define LVGL_ICON_STATUSBAR_BATTERY_ANDROID_FRAME_BOLT "\xEF\x89\x90"
#define LVGL_ICON_STATUSBAR_BLUETOOTH "\xEE\x86\xA7"
#define LVGL_ICON_STATUSBAR_BLUETOOTH_SEARCHING "\xEE\x98\x8F"
#define LVGL_ICON_STATUSBAR_BLUETOOTH_CONNECTED "\xEE\x86\xA8"
#define LVGL_ICON_STATUSBAR_BLUETOOTH_DISABLED "\xEE\x86\xA9"
#define LVGL_ICON_STATUSBAR_USB "\xEE\x87\xA0"
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <lvgl.h>
#include <tactility/device.h>
#include <tactility/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Creates an lv_indev_t bound to the given KEYBOARD_TYPE device and registers a read callback
* that polls the device through its KeyboardApi.
*
* @warning Caller must hold the LVGL lock (see lvgl_lock() in lvgl_module.h) — call this from
* LvglModuleConfig.on_start, or after calling lvgl_lock() explicitly.
*
* @param[in] device a device of type KEYBOARD_TYPE
* @param[in] display the display this indev should be associated with, or NULL to leave it unset
* @param[out] out_indev the created indev, valid only when ERROR_NONE is returned
* @retval ERROR_NONE on success
* @retval ERROR_INVALID_ARGUMENT if device or out_indev is NULL, or device is not of type KEYBOARD_TYPE
* @retval ERROR_OUT_OF_MEMORY if allocation failed
*/
error_t lvgl_keyboard_add(struct Device* device, lv_display_t* display, lv_indev_t** out_indev);
/**
* @brief Removes an indev previously created with lvgl_keyboard_add().
* @warning Caller must hold the LVGL lock.
*/
void lvgl_keyboard_remove(lv_indev_t* indev);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,90 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <lvgl.h>
#include <tactility/device.h>
#include <tactility/error.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Linear per-axis calibration range for raw pointer coordinates.
*
* Values are the raw (pre-calibration) coordinates that should map to the display's
* [0, hor_res-1] / [0, ver_res-1] range. Corrects scale+offset error only; axis
* swap/mirror is handled separately by PointerApi and applied by the driver before
* lvgl_pointer_read_cb() sees the coordinates.
*/
struct LvglPointerCalibration {
int32_t x_min;
int32_t x_max;
int32_t y_min;
int32_t y_max;
};
/**
* @brief Sets (or clears, when calibration is NULL) the calibration applied to raw coordinates
* read from the device before they are written into LVGL indev data, on an indev previously
* created with lvgl_pointer_add().
*
* @warning Caller must hold the LVGL lock (see lvgl_lock() in lvgl_module.h).
*
* @param[in] indev an indev previously created by lvgl_pointer_add()
* @param[in] calibration the calibration range to apply, or NULL to clear/disable calibration
* @retval ERROR_NONE on success
* @retval ERROR_INVALID_ARGUMENT if indev is NULL, or calibration is non-NULL but invalid
* (x_max <= x_min, y_max <= y_min, or either span smaller than the minimum allowed range)
*/
error_t lvgl_pointer_set_calibration(lv_indev_t* indev, const struct LvglPointerCalibration* calibration);
/**
* @brief Retrieves the calibration currently active on indev, if any.
* @warning Caller must hold the LVGL lock.
* @return true when a calibration is currently set on indev (out_calibration is filled), false otherwise
*/
bool lvgl_pointer_get_calibration(lv_indev_t* indev, struct LvglPointerCalibration* out_calibration);
/**
* @brief Returns the first indev created by lvgl_pointer_add() that hasn't been removed yet.
*
* Unlike iterating LVGL's own indev list, this only ever returns an indev created by
* lvgl_pointer_add() — safe to pass to lvgl_pointer_set_calibration()/lvgl_pointer_get_calibration()
* without risking a foreign indev (e.g. one registered by the deprecated HAL layer) whose driver
* data isn't a struct LvglPointerCtx*.
*
* @warning Caller must hold the LVGL lock.
* @return the indev, or NULL if none is currently registered.
*/
lv_indev_t* lvgl_pointer_get_default(void);
/**
* @brief Creates an lv_indev_t bound to the given POINTER_TYPE device and registers a read callback
* that polls the device through its PointerApi.
*
* @warning Caller must hold the LVGL lock (see lvgl_lock() in lvgl_module.h) — call this from
* LvglModuleConfig.on_start, or after calling lvgl_lock() explicitly.
*
* @param[in] device a device of type POINTER_TYPE
* @param[in] display the display this indev should be associated with, or NULL to leave it unset
* @param[out] out_indev the created indev, valid only when ERROR_NONE is returned
* @retval ERROR_NONE on success
* @retval ERROR_INVALID_ARGUMENT if device or out_indev is NULL, or device is not of type POINTER_TYPE
* @retval ERROR_OUT_OF_MEMORY if allocation failed
*/
error_t lvgl_pointer_add(struct Device* device, lv_display_t* display, lv_indev_t** out_indev);
/**
* @brief Removes an indev previously created with lvgl_pointer_add().
* @warning Caller must hold the LVGL lock.
*/
void lvgl_pointer_remove(lv_indev_t* indev);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <lvgl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// True on targets with a PPA (Pixel Processing Accelerator) unit that lvgl_ppa can use to
// hardware-rotate rotated flush tiles instead of lv_draw_sw_rotate(). False (always) on the
// simulator and on ESP32 targets without a PPA (see SOC_PPA_SUPPORTED).
bool lvgl_ppa_is_supported(void);
// True when color_format has a PPA color mode this module supports (RGB565/RGB888 - see
// lvgl_ppa_color_mode()). LV_COLOR_FORMAT_I1 and others fall back to lv_draw_sw_rotate().
bool lvgl_ppa_supports_color_format(lv_color_format_t color_format);
// Lazily creates (on first call) a PPA client and an output buffer at least out_buffer_size_bytes
// large, big enough for the largest tile this display will ever rotate. Returns NULL on failure -
// callers should fall back to lv_draw_sw_rotate() when that happens. Not thread-safe; callers must
// already hold the LVGL lock (true for all flush_cb callers).
void* lvgl_ppa_get_or_create(size_t out_buffer_size_bytes);
void lvgl_ppa_delete(void* ppa_handle);
// Rotates the tightly-packed w x h block at in_buff by rotation (LV_DISPLAY_ROTATION_90/180/270 -
// numerically identical to ppa_srm_rotation_angle_t's CCW convention, see the .c file) into the
// PPA's own output buffer and returns it. in_buff must have no row padding (PPA reads pic_w/pic_h
// in pixels, not a byte stride) - true for every lvgl_display_flush_cb() tile, which LVGL always
// renders compact. Returns NULL on failure - caller should fall back to lv_draw_sw_rotate().
void* lvgl_ppa_rotate(
void* ppa_handle,
const uint8_t* in_buff,
int32_t w,
int32_t h,
lv_display_rotation_t rotation,
lv_color_format_t color_format,
bool swap_bytes
);
#ifdef __cplusplus
}
#endif
+51
View File
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The LVGL module instance.
*/
extern struct Module lvgl_module;
/**
* @brief Configuration for the LVGL module.
*/
struct LvglModuleConfig {
/**
* @brief Callback invoked when the LVGL task starts.
* Use this to add devices (e.g. displays, pointers), start services, create widgets, etc.
*/
void (*on_start)(void);
/**
* @brief Callback invoked when the LVGL task stops.
* Use this to remove devices, stop services, etc.
*/
void (*on_stop)(void);
/** @brief Priority of the LVGL task. */
int task_priority;
/** @brief Stack size of the LVGL task in bytes. */
int task_stack_size;
#ifdef ESP_PLATFORM
/** @brief CPU affinity of the LVGL task (ESP32 specific). */
int task_affinity;
#endif
};
/**
* @brief Configures the LVGL module.
*
* @warning This must be called before starting the module.
* @param config The configuration to apply.
*/
void lvgl_module_configure(struct LvglModuleConfig config);
#ifdef __cplusplus
}
#endif