From e740288cd49a43c4dcff1a0b364004d1cd457bd9 Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Mon, 2 Sep 2024 15:24:16 +0200 Subject: [PATCH 1/5] Prepare new PIC mechanism to be used in NBGL "shared" code --- include/os_pic.h | 2 +- src/pic.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/include/os_pic.h b/include/os_pic.h index 9445fce23..16eb0588c 100644 --- a/include/os_pic.h +++ b/include/os_pic.h @@ -9,5 +9,5 @@ #ifndef PIC #define PIC(x) pic((void *) x) void *pic(void *linked_address); -void *pic_internal(void *link_address); #endif +void pic_init(void *pic_flash_start, void *pic_ram_start); diff --git a/src/pic.c b/src/pic.c index aee063083..0592cad41 100644 --- a/src/pic.c +++ b/src/pic.c @@ -1,9 +1,10 @@ #include "bolos_target.h" #include "os_pic.h" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -__attribute__((naked, no_instrument_function)) void *pic_internal(void *link_address) +#if !defined(HAVE_BOLOS) || defined(BOLOS_OS_UPGRADER_APP) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +__attribute__((naked, no_instrument_function)) static void *pic_internal(void *link_address) { // compute the delta offset between LinkMemAddr & ExecMemAddr __asm volatile("mov r2, pc\n"); @@ -21,6 +22,7 @@ __attribute__((naked, no_instrument_function)) void *pic_internal(void *link_add // this way, PIC call are armless if the address is not meant to be converted extern void _nvram; extern void _envram; +#endif // !defined(HAVE_BOLOS) || defined(BOLOS_OS_UPGRADER_APP) #if defined(ST31) @@ -36,6 +38,7 @@ void *pic(void *link_address) #elif defined(ST33) || defined(ST33K1M5) +#if !defined(HAVE_BOLOS) || defined(BOLOS_OS_UPGRADER_APP) extern void _bss; extern void _estack; @@ -62,6 +65,64 @@ void *pic(void *link_address) return link_address; } +#else // !defined(HAVE_BOLOS) || defined(BOLOS_OS_UPGRADER_APP) + +/* physical base addresses of flash & RAM for the running app*/ +static void *flash_real_addr; +static void *ram_real_addr; + +// TODO: these 4constants should be extracted from linker script +// (public_sdk/target//script.ld) +/* base and end of relocated flash for the running app (usually 0xC0DE0000)*/ +#define APP_FLASH_RELOC_ADDR (void *) 0xC0DE0000 +#define APP_FLASH_RELOC_END (void *) (APP_FLASH_RELOC_ADDR + 400 * 1024) +/* base and end of relocated ram for the running app (usually 0xDA7A0000)*/ +#define APP_DATA_RELOC_ADDR (void *) 0xDA7A0000 +#define APP_DATA_RELOC_END (void *) (APP_DATA_RELOC_ADDR + 40 * 1024) + +/** + * @brief PIC function to be used in UX, to retrieve the physical address from the + * potentially relocated given address. + * @note This function only works if @ref pic_init() is called at Application start-up + * to initiate the relocated Flash and RAM limits and the corresponding physical Flash & RAM + * addresses + * + * @param link_address potentially relocated address + * @return the physical address + */ +void *pic_shared(const void *link_address) +{ + // check if in the LINKED TEXT zone + if ((link_address > APP_FLASH_RELOC_ADDR) && (link_address <= APP_FLASH_RELOC_END)) { + link_address = link_address - APP_FLASH_RELOC_ADDR + flash_real_addr; + } + + // check if in the LINKED RAM zone + if ((link_address >= APP_DATA_RELOC_ADDR) && (link_address <= APP_DATA_RELOC_END)) { + link_address = link_address - APP_DATA_RELOC_ADDR + ram_real_addr; + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" + return link_address; +#pragma GCC diagnostic pop +} + +/** + * @brief Function to be called just before Application start-up to initiate the relocated Flash and + * RAM limits and the corresponding physical Flash & RAM addresses + * + * @param real_flash_start physical base address for App code (= PIC(flash_start)) + * @param real_ram_start physical base address for App data (= PIC(ram_start)) + */ +void pic_init(void *real_flash_start, void *real_ram_start) +{ + flash_real_addr = real_flash_start; + ram_real_addr = real_ram_start; +} + +#endif // !defined(HAVE_BOLOS) || defined(BOLOS_OS_UPGRADER_APP) + #else #error "invalid architecture" From 43a2b44938855861621808410d4440a3300a4345 Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Mon, 2 Sep 2024 15:36:47 +0200 Subject: [PATCH 2/5] Adapt NBGL for sharing (RAM buffer) --- lib_nbgl/include/nbgl_obj.h | 7 ++++--- lib_nbgl/include/nbgl_step.h | 3 --- lib_nbgl/src/nbgl_flow.c | 3 +++ lib_nbgl/src/nbgl_obj.c | 10 ++++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib_nbgl/include/nbgl_obj.h b/lib_nbgl/include/nbgl_obj.h index 75f0c516b..89b37ef3e 100644 --- a/lib_nbgl/include/nbgl_obj.h +++ b/lib_nbgl/include/nbgl_obj.h @@ -574,9 +574,10 @@ void nbgl_refreshSpecialWithPostRefresh(nbgl_refresh_mode_t mode, nbgl_post_refr bool nbgl_refreshIsNeeded(void); void nbgl_refreshReset(void); -void nbgl_objInit(void); -void nbgl_objDraw(nbgl_obj_t *obj); -void nbgl_objAllowDrawing(bool enable); +void nbgl_objInit(void); +void nbgl_objDraw(nbgl_obj_t *obj); +void nbgl_objAllowDrawing(bool enable); +uint8_t *nbgl_objGetRAMBuffer(void); void nbgl_objPoolRelease(uint8_t layer); nbgl_obj_t *nbgl_objPoolGet(nbgl_obj_type_t type, uint8_t layer); diff --git a/lib_nbgl/include/nbgl_step.h b/lib_nbgl/include/nbgl_step.h index 38fdd27a0..c91608160 100644 --- a/lib_nbgl/include/nbgl_step.h +++ b/lib_nbgl/include/nbgl_step.h @@ -18,9 +18,6 @@ extern "C" { #include "nbgl_layout.h" #include "nbgl_obj.h" #include "nbgl_types.h" -#ifdef HAVE_LANGUAGE_PACK -#include "bolos_ux_loc_strings.h" -#endif // HAVE_LANGUAGE_PACK /********************* * DEFINES diff --git a/lib_nbgl/src/nbgl_flow.c b/lib_nbgl/src/nbgl_flow.c index 3ea974dd9..fe74e5926 100644 --- a/lib_nbgl/src/nbgl_flow.c +++ b/lib_nbgl/src/nbgl_flow.c @@ -13,6 +13,9 @@ #include "glyphs.h" #include "os_pic.h" #include "ux.h" +#ifdef HAVE_LANGUAGE_PACK +#include "bolos_ux_loc_strings.h" +#endif // HAVE_LANGUAGE_PACK /********************* * DEFINES diff --git a/lib_nbgl/src/nbgl_obj.c b/lib_nbgl/src/nbgl_obj.c index 6a4f445e5..717ccda2c 100644 --- a/lib_nbgl/src/nbgl_obj.c +++ b/lib_nbgl/src/nbgl_obj.c @@ -1646,3 +1646,13 @@ void nbgl_objAllowDrawing(bool enable) { objDrawingDisabled = !enable; } + +/** + * @brief This function is used to get the all purpose RAM buffer + * + * @param enable if true, enables drawing/refresh, otherwise disables + */ +uint8_t *nbgl_objGetRAMBuffer(void) +{ + return ramBuffer; +} From 0471705bf9d5ab636833e34d4c6f9ac8cfbded88 Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Mon, 2 Sep 2024 16:31:34 +0200 Subject: [PATCH 3/5] Use NBGL shared function --- Makefile.rules | 10 ++++-- include/nbgl_stubs.h | 54 ++++++++++++++++++++++++++++++++ include/os_pic.h | 5 +++ lib_nbgl/nbgl.export | 60 +++++++++++++++++++++++++++++++++++ src/nbgl_stubs.S | 74 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 include/nbgl_stubs.h create mode 100644 lib_nbgl/nbgl.export create mode 100644 src/nbgl_stubs.S diff --git a/Makefile.rules b/Makefile.rules index b45f41c5a..73daa9aa5 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -19,7 +19,11 @@ ifeq ($(USE_NBGL),0) SDK_SOURCE_PATH += lib_bagl lib_ux else - SDK_SOURCE_PATH += lib_nbgl lib_ux_nbgl lib_ux_sync + SDK_SOURCE_PATH += lib_ux_nbgl lib_ux_sync + NBGL_SOURCES := $(shell find $(BOLOS_SDK)/lib_nbgl/src -name 'nbgl_layout*.[csS]') + NBGL_SOURCES += $(shell find $(BOLOS_SDK)/lib_nbgl/src -name 'nbgl_page*.[csS]') + NBGL_SOURCES += $(shell find $(BOLOS_SDK)/lib_nbgl/src -name 'nbgl_use_case*.[csS]') + NBGL_INCLUDE_PATH := lib_nbgl endif define uniq = @@ -65,7 +69,7 @@ APP_SRC_PROTOC = $(filter %.pb.c, $(APP_SOURCE_FILES) $(SOURCE_FILES)) $(shell f APP_SRC_FILTER = $(filter-out $(APP_SRC_FROM_SDK) $(APP_SRC_GEN), $(APP_SOURCE_FILES)) # Separate SDK and APP and GEN sources -SOURCES_SDK += $(foreach libdir, src $(SDK_SOURCE_PATH), $(shell find $(BOLOS_SDK)/$(libdir) -name '*.[csS]')) $(APP_SRC_FROM_SDK) +SOURCES_SDK += $(foreach libdir, src $(SDK_SOURCE_PATH), $(shell find $(BOLOS_SDK)/$(libdir) -name '*.[csS]')) $(APP_SRC_FROM_SDK) $(NBGL_SOURCES) SOURCES_APP += $(filter-out %.pb.c, $(abspath $(SOURCE_FILES) $(foreach libdir, $(SOURCE_PATH) $(APP_SOURCE_PATH), $(shell find $(libdir) -name '*.[csS]')) $(APP_SRC_FILTER))) SOURCES_GEN += $(GLYPH_DESTC) $(APP_SRC_GEN) VPATH += $(call uniq, $(dir $(SOURCES_SDK) $(SOURCES_APP) $(GLYPH_DESTC))) @@ -75,7 +79,7 @@ INCLUDES_APP += $(shell find $(APP_SOURCE_PATH) -name '*.h') # Warn if a same header filename is found in both APP and SDK $(call check_duplicate, $(INCLUDES_APP), $(BOLOS_SDK)) # Compute header directories list -INCLUDES_PATH += $(call uniq, $(dir $(foreach libdir, $(SDK_SOURCE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) -name '*.h')))) include $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm $(dir $(INCLUDES_APP)) $(GLYPH_SRC_DIR)) +INCLUDES_PATH += $(call uniq, $(dir $(foreach libdir, $(SDK_SOURCE_PATH) $(NBGL_INCLUDE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) -name '*.h')))) include $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm $(dir $(INCLUDES_APP)) $(GLYPH_SRC_DIR)) # Separate object files from SDK and APP to avoid name conflicts OBJECTS_SDK += $(sort $(subst $(BOLOS_SDK), $(OBJ_DIR)/sdk, $(addsuffix .o, $(basename $(SOURCES_SDK))))) diff --git a/include/nbgl_stubs.h b/include/nbgl_stubs.h new file mode 100644 index 000000000..79238a25c --- /dev/null +++ b/include/nbgl_stubs.h @@ -0,0 +1,54 @@ +#pragma once + +// auto-generated by shared_export.py +#define _NR_nbgl_refresh 0x90 +#define _NR_nbgl_refreshSpecial 0x91 +#define _NR_nbgl_refreshSpecialWithPostRefresh 0x92 +#define _NR_nbgl_refreshIsNeeded 0x93 +#define _NR_nbgl_refreshReset 0x94 +#define _NR_nbgl_objInit 0x95 +#define _NR_nbgl_objDraw 0x96 +#define _NR_nbgl_objAllowDrawing 0x97 +#define _NR_nbgl_objGetRAMBuffer 0x98 +#define _NR_nbgl_screenContainsObjType 0x99 +#define _NR_nbgl_screenSet 0x9a +#define _NR_nbgl_screenPush 0x9b +#define _NR_nbgl_screenRedraw 0x9c +#define _NR_nbgl_screenPop 0x9d +#define _NR_nbgl_screenGetElements 0x9e +#define _NR_nbgl_screenGetCurrentStackSize 0x9f +#define _NR_nbgl_screenGetUxStackSize 0xa0 +#define _NR_nbgl_screenGetAt 0xa1 +#define _NR_nbgl_screenGetTop 0xa2 +#define _NR_nbgl_screenUpdateTicker 0xa3 +#define _NR_nbgl_screenUpdateBackgroundColor 0xa4 +#define _NR_nbgl_screenReset 0xa5 +#define _NR_nbgl_screenHandler 0xa6 +#define _NR_nbgl_objPoolGet 0xa7 +#define _NR_nbgl_objPoolGetArray 0xa8 +#define _NR_nbgl_containerPoolGet 0xa9 +#define _NR_nbgl_getCharWidth 0xaa +#define _NR_nbgl_getFont 0xab +#define _NR_nbgl_getFontHeight 0xac +#define _NR_nbgl_getFontLineHeight 0xad +#define _NR_nbgl_getSingleLineTextWidth 0xae +#define _NR_nbgl_getSingleLineTextWidthInLen 0xaf +#define _NR_nbgl_getTextHeight 0xb0 +#define _NR_nbgl_getTextHeightInWidth 0xb1 +#define _NR_nbgl_getTextNbLinesInWidth 0xb2 +#define _NR_nbgl_getTextNbPagesInWidth 0xb3 +#define _NR_nbgl_getTextWidth 0xb4 +#define _NR_nbgl_getTextMaxLenInNbLines 0xb5 +#define _NR_nbgl_textReduceOnNbLines 0xb6 +#define _NR_nbgl_textWrapOnNbLines 0xb7 +#define _NR_nbgl_refreshUnicodeFont 0xb8 +#define _NR_nbgl_touchHandler 0xb9 +#define _NR_nbgl_touchGetTouchDuration 0xba +#define _NR_nbgl_touchGetTouchedPosition 0xbb +#define _NR_nbgl_buttonsHandler 0xbc +#define _NR_nbgl_buttonsReset 0xbd +#define _NR_nbgl_keyboardCallback 0xbe +#define _NR_nbgl_keypadCallback 0xbf +#define _NR_nbgl_drawText 0xc0 +#define _NR_pic_shared 0xc1 +#define _NR_pic_init 0xc2 diff --git a/include/os_pic.h b/include/os_pic.h index 16eb0588c..40dcc0857 100644 --- a/include/os_pic.h +++ b/include/os_pic.h @@ -4,7 +4,12 @@ // Function that align the dereferenced value in a rom struct to use it depending on the execution // address. Can be used even if code is executing at the same place where it had been linked. #if defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP) +#ifndef OS_UNIT_TEST +#define PIC(x) pic_shared((const void *) x) +void *pic_shared(const void *linked_address); +#else // !OS_UNIT_TEST #define PIC(x) (x) +#endif // !OS_UNIT_TEST #endif #ifndef PIC #define PIC(x) pic((void *) x) diff --git a/lib_nbgl/nbgl.export b/lib_nbgl/nbgl.export new file mode 100644 index 000000000..961fc8404 --- /dev/null +++ b/lib_nbgl/nbgl.export @@ -0,0 +1,60 @@ +# This file contains the functions exported by shared lib. It is used by shared_export.py to +# generate asm stubs for the SDK and the NBGL functions table in shared lib. +# +# Making changes to this file (ie. removal, addition, ordering) require apps to +# be re-built since the ID of the exported functions will likely be different. + +nbgl_refresh +nbgl_refreshSpecial +nbgl_refreshSpecialWithPostRefresh +nbgl_refreshIsNeeded +nbgl_refreshReset +nbgl_objInit +nbgl_objDraw +nbgl_objAllowDrawing +nbgl_objGetRAMBuffer +nbgl_screenContainsObjType +nbgl_screenSet +nbgl_screenPush +nbgl_screenRedraw +nbgl_screenPop +nbgl_screenGetElements +nbgl_screenGetCurrentStackSize +nbgl_screenGetUxStackSize +nbgl_screenGetAt +nbgl_screenGetTop +nbgl_screenUpdateTicker +nbgl_screenUpdateBackgroundColor +nbgl_screenReset +nbgl_screenHandler +nbgl_objPoolGet +nbgl_objPoolGetArray +nbgl_containerPoolGet +nbgl_getCharWidth +nbgl_getFont +nbgl_getFontHeight +nbgl_getFontLineHeight +nbgl_getSingleLineTextWidth +nbgl_getSingleLineTextWidthInLen +nbgl_getTextHeight +nbgl_getTextHeightInWidth +nbgl_getTextNbLinesInWidth +nbgl_getTextNbPagesInWidth +nbgl_getTextWidth +nbgl_getTextMaxLenInNbLines +nbgl_textReduceOnNbLines +nbgl_textWrapOnNbLines +nbgl_refreshUnicodeFont +#ifdef HAVE_SE_TOUCH +nbgl_touchHandler +nbgl_touchGetTouchDuration +nbgl_touchGetTouchedPosition +#else // HAVE_SE_TOUCH +nbgl_buttonsHandler +nbgl_buttonsReset +nbgl_keyboardCallback +nbgl_keypadCallback +#endif // HAVE_SE_TOUCH +nbgl_drawText +pic_shared +pic_init diff --git a/src/nbgl_stubs.S b/src/nbgl_stubs.S new file mode 100644 index 000000000..6c28cd2d9 --- /dev/null +++ b/src/nbgl_stubs.S @@ -0,0 +1,74 @@ +// auto-generated by shared_export.py +#include "shared_trampoline.h" +#include "nbgl_stubs.h" + +.text +.thumb + +.macro NBGL_TRAMPOLINE id, name + .section .text.\name + .thumb_func + .weak \name + .type \name, "function" + \name: + push {r0-r1} + ldr r0, =\id + b nbgl_trampoline_helper +.endm + +NBGL_TRAMPOLINE _NR_nbgl_refresh nbgl_refresh +NBGL_TRAMPOLINE _NR_nbgl_refreshSpecial nbgl_refreshSpecial +NBGL_TRAMPOLINE _NR_nbgl_refreshSpecialWithPostRefresh nbgl_refreshSpecialWithPostRefresh +NBGL_TRAMPOLINE _NR_nbgl_refreshIsNeeded nbgl_refreshIsNeeded +NBGL_TRAMPOLINE _NR_nbgl_refreshReset nbgl_refreshReset +NBGL_TRAMPOLINE _NR_nbgl_objInit nbgl_objInit +NBGL_TRAMPOLINE _NR_nbgl_objDraw nbgl_objDraw +NBGL_TRAMPOLINE _NR_nbgl_objAllowDrawing nbgl_objAllowDrawing +NBGL_TRAMPOLINE _NR_nbgl_objGetRAMBuffer nbgl_objGetRAMBuffer +NBGL_TRAMPOLINE _NR_nbgl_screenContainsObjType nbgl_screenContainsObjType +NBGL_TRAMPOLINE _NR_nbgl_screenSet nbgl_screenSet +NBGL_TRAMPOLINE _NR_nbgl_screenPush nbgl_screenPush +NBGL_TRAMPOLINE _NR_nbgl_screenRedraw nbgl_screenRedraw +NBGL_TRAMPOLINE _NR_nbgl_screenPop nbgl_screenPop +NBGL_TRAMPOLINE _NR_nbgl_screenGetElements nbgl_screenGetElements +NBGL_TRAMPOLINE _NR_nbgl_screenGetCurrentStackSize nbgl_screenGetCurrentStackSize +NBGL_TRAMPOLINE _NR_nbgl_screenGetUxStackSize nbgl_screenGetUxStackSize +NBGL_TRAMPOLINE _NR_nbgl_screenGetAt nbgl_screenGetAt +NBGL_TRAMPOLINE _NR_nbgl_screenGetTop nbgl_screenGetTop +NBGL_TRAMPOLINE _NR_nbgl_screenUpdateTicker nbgl_screenUpdateTicker +NBGL_TRAMPOLINE _NR_nbgl_screenUpdateBackgroundColor nbgl_screenUpdateBackgroundColor +NBGL_TRAMPOLINE _NR_nbgl_screenReset nbgl_screenReset +NBGL_TRAMPOLINE _NR_nbgl_screenHandler nbgl_screenHandler +NBGL_TRAMPOLINE _NR_nbgl_objPoolGet nbgl_objPoolGet +NBGL_TRAMPOLINE _NR_nbgl_objPoolGetArray nbgl_objPoolGetArray +NBGL_TRAMPOLINE _NR_nbgl_containerPoolGet nbgl_containerPoolGet +NBGL_TRAMPOLINE _NR_nbgl_getCharWidth nbgl_getCharWidth +NBGL_TRAMPOLINE _NR_nbgl_getFont nbgl_getFont +NBGL_TRAMPOLINE _NR_nbgl_getFontHeight nbgl_getFontHeight +NBGL_TRAMPOLINE _NR_nbgl_getFontLineHeight nbgl_getFontLineHeight +NBGL_TRAMPOLINE _NR_nbgl_getSingleLineTextWidth nbgl_getSingleLineTextWidth +NBGL_TRAMPOLINE _NR_nbgl_getSingleLineTextWidthInLen nbgl_getSingleLineTextWidthInLen +NBGL_TRAMPOLINE _NR_nbgl_getTextHeight nbgl_getTextHeight +NBGL_TRAMPOLINE _NR_nbgl_getTextHeightInWidth nbgl_getTextHeightInWidth +NBGL_TRAMPOLINE _NR_nbgl_getTextNbLinesInWidth nbgl_getTextNbLinesInWidth +NBGL_TRAMPOLINE _NR_nbgl_getTextNbPagesInWidth nbgl_getTextNbPagesInWidth +NBGL_TRAMPOLINE _NR_nbgl_getTextWidth nbgl_getTextWidth +NBGL_TRAMPOLINE _NR_nbgl_getTextMaxLenInNbLines nbgl_getTextMaxLenInNbLines +NBGL_TRAMPOLINE _NR_nbgl_textReduceOnNbLines nbgl_textReduceOnNbLines +NBGL_TRAMPOLINE _NR_nbgl_textWrapOnNbLines nbgl_textWrapOnNbLines +NBGL_TRAMPOLINE _NR_nbgl_refreshUnicodeFont nbgl_refreshUnicodeFont +NBGL_TRAMPOLINE _NR_nbgl_touchHandler nbgl_touchHandler +NBGL_TRAMPOLINE _NR_nbgl_touchGetTouchDuration nbgl_touchGetTouchDuration +NBGL_TRAMPOLINE _NR_nbgl_touchGetTouchedPosition nbgl_touchGetTouchedPosition +NBGL_TRAMPOLINE _NR_nbgl_buttonsHandler nbgl_buttonsHandler +NBGL_TRAMPOLINE _NR_nbgl_buttonsReset nbgl_buttonsReset +NBGL_TRAMPOLINE _NR_nbgl_keyboardCallback nbgl_keyboardCallback +NBGL_TRAMPOLINE _NR_nbgl_keypadCallback nbgl_keypadCallback +NBGL_TRAMPOLINE _NR_nbgl_drawText nbgl_drawText +NBGL_TRAMPOLINE _NR_pic_shared pic_shared +NBGL_TRAMPOLINE _NR_pic_init pic_init + +.thumb_func +nbgl_trampoline_helper: + ldr r1, =SHARED_TRAMPOLINE_ADDR // _shared_trampoline address + bx r1 From 1f177df5e0202a567047753dcce9ccb65d54bb0e Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Mon, 9 Sep 2024 08:25:51 +0200 Subject: [PATCH 4/5] Put fonts in Shared library to access them without syscall --- include/shared_trampoline.h | 6 +++--- lib_nbgl/include/nbgl_fonts.h | 1 - lib_nbgl/src/nbgl_fonts.c | 11 +---------- src/syscalls.c | 7 ------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/include/shared_trampoline.h b/include/shared_trampoline.h index 0065178eb..7f3446fe5 100644 --- a/include/shared_trampoline.h +++ b/include/shared_trampoline.h @@ -7,9 +7,9 @@ #elif defined(TARGET_NANOX) #define SHARED_TRAMPOLINE_ADDR 0x00210001 #elif defined(TARGET_NANOS2) -#define SHARED_TRAMPOLINE_ADDR 0x00810001 +#define SHARED_TRAMPOLINE_ADDR 0x00808001 #elif defined(TARGET_STAX) -#define SHARED_TRAMPOLINE_ADDR 0x00818001 +#define SHARED_TRAMPOLINE_ADDR 0x00810001 #elif defined(TARGET_FLEX) -#define SHARED_TRAMPOLINE_ADDR 0x00818001 +#define SHARED_TRAMPOLINE_ADDR 0x00810001 #endif diff --git a/lib_nbgl/include/nbgl_fonts.h b/lib_nbgl/include/nbgl_fonts.h index 91bded048..a05c1eaa0 100644 --- a/lib_nbgl/include/nbgl_fonts.h +++ b/lib_nbgl/include/nbgl_fonts.h @@ -166,7 +166,6 @@ typedef struct nbgl_unicode_ctx_s { /********************** * GLOBAL PROTOTYPES **********************/ -const nbgl_font_t *nbgl_font_getFont(unsigned int fontId); const nbgl_font_t *nbgl_getFont(nbgl_font_id_e fontId); uint16_t nbgl_getSingleLineTextWidth(nbgl_font_id_e fontId, const char *text); uint16_t nbgl_getSingleLineTextWidthInLen(nbgl_font_id_e fontId, const char *text, uint16_t maxLen); diff --git a/lib_nbgl/src/nbgl_fonts.c b/lib_nbgl/src/nbgl_fonts.c index df9a612b9..c354118b6 100644 --- a/lib_nbgl/src/nbgl_fonts.c +++ b/lib_nbgl/src/nbgl_fonts.c @@ -44,7 +44,6 @@ static nbgl_unicode_ctx_t unicodeCtx = {0}; static const LANGUAGE_PACK *language_pack; #endif // HAVE_LANGUAGE_PACK -#if defined(BOLOS_OS_UPGRADER_APP) #ifdef SCREEN_SIZE_WALLET #ifdef TARGET_STAX #include "nbgl_font_inter_regular_24.inc" @@ -74,8 +73,6 @@ const nbgl_font_t *const C_nbgl_fonts[] = { }; const unsigned int C_nbgl_fonts_count = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]); -#endif - #if (defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP)) #if !defined(HAVE_LANGUAGE_PACK) const nbgl_font_unicode_t *const C_nbgl_fonts_unicode[] = { @@ -116,7 +113,6 @@ bool hard_caesura = false; * @param fontId font ID * @return the found font or NULL */ -#if defined(BOLOS_OS_UPGRADER_APP) const nbgl_font_t *nbgl_getFont(nbgl_font_id_e fontId) { unsigned int i = C_nbgl_fonts_count; @@ -132,12 +128,7 @@ const nbgl_font_t *nbgl_getFont(nbgl_font_id_e fontId) // id not found return NULL; } -#else -const nbgl_font_t *nbgl_getFont(nbgl_font_id_e fontId) -{ - return nbgl_font_getFont(fontId); -} -#endif // BOLOS_OS_UPGRADER_APP + /** * @brief Get the coming unicode value on the given UTF-8 string. If the value is a simple ASCII * character, is_unicode is set to false. diff --git a/src/syscalls.c b/src/syscalls.c index 9eb3256aa..001555a79 100644 --- a/src/syscalls.c +++ b/src/syscalls.c @@ -181,13 +181,6 @@ void nbgl_sideRefreshArea(nbgl_area_t *area, nbgl_post_refresh_t post_refresh) return; } -const nbgl_font_t *nbgl_font_getFont(unsigned int fontId) -{ - unsigned int parameters[1]; - parameters[0] = (unsigned int) fontId; - return (const nbgl_font_t *) SVC_Call(SYSCALL_nbgl_get_font_ID, parameters); -} - void nbgl_screen_reinit(void) { unsigned int parameters[1]; From 621b9be087fd2dc3fed50f1e1a1cbb22899e7232 Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Thu, 12 Sep 2024 14:13:20 +0200 Subject: [PATCH 5/5] Use different touch contexts for App & UX --- lib_nbgl/include/nbgl_obj.h | 1 + lib_nbgl/include/nbgl_touch.h | 11 +-- lib_nbgl/src/nbgl_fonts.c | 5 +- lib_nbgl/src/nbgl_obj.c | 29 +++++++- lib_nbgl/src/nbgl_screen.c | 2 +- lib_nbgl/src/nbgl_touch.c | 109 +++++++++++++++++----------- lib_ux_nbgl/ux.c | 4 +- unit-tests/lib_nbgl/test_nbgl_obj.c | 3 +- 8 files changed, 110 insertions(+), 54 deletions(-) diff --git a/lib_nbgl/include/nbgl_obj.h b/lib_nbgl/include/nbgl_obj.h index 89b37ef3e..f678c1a70 100644 --- a/lib_nbgl/include/nbgl_obj.h +++ b/lib_nbgl/include/nbgl_obj.h @@ -578,6 +578,7 @@ void nbgl_objInit(void); void nbgl_objDraw(nbgl_obj_t *obj); void nbgl_objAllowDrawing(bool enable); uint8_t *nbgl_objGetRAMBuffer(void); +bool nbgl_objIsUx(nbgl_obj_t *obj); void nbgl_objPoolRelease(uint8_t layer); nbgl_obj_t *nbgl_objPoolGet(nbgl_obj_type_t type, uint8_t layer); diff --git a/lib_nbgl/include/nbgl_touch.h b/lib_nbgl/include/nbgl_touch.h index 03e95df84..341dbb8a2 100644 --- a/lib_nbgl/include/nbgl_touch.h +++ b/lib_nbgl/include/nbgl_touch.h @@ -23,7 +23,7 @@ extern "C" { // duration of a short touch on touch panel (in ms) #define SHORT_TOUCH_DURATION 0 // duration of a long touch on touch panel (in ms) -#define LONG_TOUCH_DURATION 1500 +#define LONG_TOUCH_DURATION 3000 /********************** * TYPEDEFS **********************/ @@ -31,10 +31,11 @@ extern "C" { /********************** * GLOBAL PROTOTYPES **********************/ -void nbgl_touchHandler(nbgl_touchStatePosition_t *touchEvent, uint32_t currentTimeMs); -bool nbgl_touchGetTouchedPosition(nbgl_obj_t *obj, - nbgl_touchStatePosition_t **firstPos, - nbgl_touchStatePosition_t **lastPos); +void nbgl_touchInit(bool fromUx); +void nbgl_touchHandler(bool fromUx, nbgl_touchStatePosition_t *touchEvent, uint32_t currentTimeMs); +bool nbgl_touchGetTouchedPosition(nbgl_obj_t *obj, + nbgl_touchStatePosition_t **firstPos, + nbgl_touchStatePosition_t **lastPos); uint32_t nbgl_touchGetTouchDuration(nbgl_obj_t *obj); nbgl_obj_t *nbgl_touchGetObjectFromId(nbgl_obj_t *obj, uint8_t id); diff --git a/lib_nbgl/src/nbgl_fonts.c b/lib_nbgl/src/nbgl_fonts.c index c354118b6..d265428ca 100644 --- a/lib_nbgl/src/nbgl_fonts.c +++ b/lib_nbgl/src/nbgl_fonts.c @@ -66,12 +66,13 @@ static const LANGUAGE_PACK *language_pack; #include "nbgl_font_open_sans_light_16.inc" #endif // SCREEN_SIZE_WALLET -const nbgl_font_t *const C_nbgl_fonts[] = { +__attribute__((section("._nbgl_fonts_"))) const nbgl_font_t *const C_nbgl_fonts[] = { #include "nbgl_font_rom_struct.inc" }; -const unsigned int C_nbgl_fonts_count = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]); +__attribute__((section("._nbgl_fonts_"))) const unsigned int C_nbgl_fonts_count + = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]); #if (defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP)) #if !defined(HAVE_LANGUAGE_PACK) diff --git a/lib_nbgl/src/nbgl_obj.c b/lib_nbgl/src/nbgl_obj.c index 717ccda2c..318aac79d 100644 --- a/lib_nbgl/src/nbgl_obj.c +++ b/lib_nbgl/src/nbgl_obj.c @@ -14,6 +14,7 @@ #include "nbgl_front.h" #include "nbgl_debug.h" #include "nbgl_screen.h" +#include "nbgl_touch.h" #include "os_print.h" #include "os_helpers.h" #include "os_pic.h" @@ -1629,12 +1630,17 @@ void nbgl_refreshReset(void) /** * @brief This functions inits all internal of nbgl objects layer + * @note it is supposed to be called only from App * */ void nbgl_objInit(void) { // init area to the smallest size nbgl_refreshReset(); + objDrawingDisabled = false; +#ifdef HAVE_SE_TOUCH + nbgl_touchInit(false); +#endif } /** @@ -1650,9 +1656,30 @@ void nbgl_objAllowDrawing(bool enable) /** * @brief This function is used to get the all purpose RAM buffer * - * @param enable if true, enables drawing/refresh, otherwise disables + * @return a pointer to the all purpose RAM buffer */ uint8_t *nbgl_objGetRAMBuffer(void) { return ramBuffer; } + +/** + * @brief This function returns true if the object belongs to a UxScreen + * + * @return true if the object belongs to a UxScreen + */ +bool nbgl_objIsUx(nbgl_obj_t *obj) +{ + nbgl_obj_t *parent = obj; + // search screen in parenthood + while (parent->parent != NULL) { + parent = parent->parent; + } + if (parent->type == SCREEN) { + return (((nbgl_screen_t *) parent)->isUxScreen); + } + else { + // should never happen + return true; + } +} diff --git a/lib_nbgl/src/nbgl_screen.c b/lib_nbgl/src/nbgl_screen.c index ba07911b4..ce6fb4f87 100644 --- a/lib_nbgl/src/nbgl_screen.c +++ b/lib_nbgl/src/nbgl_screen.c @@ -368,7 +368,7 @@ int nbgl_screenPush(nbgl_obj_t ***elements, nbgl_touchStatePosition_t touchStatePosition = {.state = RELEASED, .x = 0, .y = 0}; // make a fake touch release for the current top-of-stack to avoid issue // (for example in long-touch press) - nbgl_touchHandler(&touchStatePosition, 0); + nbgl_touchHandler(topOfStack->isUxScreen, &touchStatePosition, 0); #endif // HAVE_SE_TOUCH // new top of stack topOfStack = &screenStack[screenIndex]; diff --git a/lib_nbgl/src/nbgl_touch.c b/lib_nbgl/src/nbgl_touch.c index 1e6881f8d..b2f2c25a1 100644 --- a/lib_nbgl/src/nbgl_touch.c +++ b/lib_nbgl/src/nbgl_touch.c @@ -20,10 +20,23 @@ /********************* * DEFINES *********************/ +enum { + UX_CTX = 0, + APP_CTX, + NB_CTXS +}; /********************** * TYPEDEFS **********************/ +typedef struct nbgl_touchCtx_s { + nbgl_touchState_t lastState; + uint32_t lastPressedTime; + uint32_t lastCurrentTime; + nbgl_obj_t *lastPressedObj; + nbgl_touchStatePosition_t firstTouchedPosition; + nbgl_touchStatePosition_t lastTouchedPosition; +} nbgl_touchCtx_t; /********************** * STATIC PROTOTYPES @@ -32,10 +45,7 @@ /********************** * STATIC VARIABLES **********************/ -static uint32_t lastPressedTime = 0; -static uint32_t lastCurrentTime = 0; -static nbgl_obj_t *lastPressedObj = NULL; -static nbgl_touchStatePosition_t firstTouchedPosition, lastTouchedPosition; +static nbgl_touchCtx_t touchCtxs[NB_CTXS]; /********************** * VARIABLES @@ -255,29 +265,41 @@ static nbgl_touchType_t nbgl_detectSwipe(nbgl_touchStatePosition_t *last, /********************** * GLOBAL FUNCTIONS **********************/ +/** + * @brief Function to initialize the touch context + * @param fromUx if true, means to initialize the UX context, otherwise App one + */ +void nbgl_touchInit(bool fromUx) +{ + nbgl_touchCtx_t *ctx = fromUx ? &touchCtxs[UX_CTX] : &touchCtxs[APP_CTX]; + memset(ctx, 0, sizeof(nbgl_touchCtx_t)); +} /** * @brief Function to be called periodically to check touchscreen state * and coordinates + * @param fromUx if true, means this is called from the UX, not the App * @param touchStatePosition state and position read from touch screen * @param currentTime current time in ms */ -void nbgl_touchHandler(nbgl_touchStatePosition_t *touchStatePosition, uint32_t currentTime) +void nbgl_touchHandler(bool fromUx, + nbgl_touchStatePosition_t *touchStatePosition, + uint32_t currentTime) { - static nbgl_touchState_t lastState = RELEASED; - nbgl_obj_t *foundObj; + nbgl_obj_t *foundObj; + nbgl_touchCtx_t *ctx = fromUx ? &touchCtxs[UX_CTX] : &touchCtxs[APP_CTX]; // save last received currentTime - lastCurrentTime = currentTime; + ctx->lastCurrentTime = currentTime; - if (lastState == RELEASED) { + if (ctx->lastState == RELEASED) { // filter out not realistic cases (successive RELEASE events) if (RELEASED == touchStatePosition->state) { - lastState = touchStatePosition->state; + ctx->lastState = touchStatePosition->state; return; } // memorize first touched position - memcpy(&firstTouchedPosition, touchStatePosition, sizeof(nbgl_touchStatePosition_t)); + memcpy(&ctx->firstTouchedPosition, touchStatePosition, sizeof(nbgl_touchStatePosition_t)); } // LOG_DEBUG(TOUCH_LOGGER,"state = %s, x = %d, y=%d\n",(touchStatePosition->state == // RELEASED)?"RELEASED":"PRESSED",touchStatePosition->x,touchStatePosition->y); @@ -289,86 +311,88 @@ void nbgl_touchHandler(nbgl_touchStatePosition_t *touchStatePosition, uint32_t c // foundObj->type); if (foundObj == NULL) { LOG_DEBUG(TOUCH_LOGGER, "nbgl_touchHandler: no found obj\n"); - if ((touchStatePosition->state == PRESSED) && (lastState == PRESSED) - && (lastPressedObj != NULL)) { + if ((touchStatePosition->state == PRESSED) && (ctx->lastState == PRESSED) + && (ctx->lastPressedObj != NULL)) { // finger has moved out of an object // make sure lastPressedObj still belongs to current screen before warning it - if (nbgl_screenContainsObj(lastPressedObj)) { - applytouchStatePosition(lastPressedObj, OUT_OF_TOUCH); + if (nbgl_screenContainsObj(ctx->lastPressedObj)) { + applytouchStatePosition(ctx->lastPressedObj, OUT_OF_TOUCH); } } // Released event has been handled, forget lastPressedObj - lastPressedObj = NULL; + ctx->lastPressedObj = NULL; } // memorize last touched position - memcpy(&lastTouchedPosition, touchStatePosition, sizeof(nbgl_touchStatePosition_t)); + memcpy(&ctx->lastTouchedPosition, touchStatePosition, sizeof(nbgl_touchStatePosition_t)); if (touchStatePosition->state == RELEASED) { - nbgl_touchType_t swipe = nbgl_detectSwipe(touchStatePosition, &firstTouchedPosition); + nbgl_touchType_t swipe = nbgl_detectSwipe(touchStatePosition, &ctx->firstTouchedPosition); bool consumed = false; if (swipe != NB_TOUCH_TYPES) { // Swipe detected nbgl_obj_t *swipedObj = getSwipableObject( - nbgl_screenGetTop(), &firstTouchedPosition, &lastTouchedPosition, swipe); + nbgl_screenGetTop(), &ctx->firstTouchedPosition, &ctx->lastTouchedPosition, swipe); // if a swipable object has been found if (swipedObj) { applytouchStatePosition(swipedObj, swipe); consumed = true; } } - if (!consumed && (lastPressedObj != NULL) - && ((foundObj == lastPressedObj) || (nbgl_screenContainsObj(lastPressedObj)))) { + if (!consumed && (ctx->lastPressedObj != NULL) + && ((foundObj == ctx->lastPressedObj) + || (nbgl_screenContainsObj(ctx->lastPressedObj)))) { // very strange if lastPressedObj != foundObj, let's consider that it's a normal release // on lastPressedObj make sure lastPressedObj still belongs to current screen before // "releasing" it - applytouchStatePosition(lastPressedObj, TOUCH_RELEASED); - if (currentTime >= (lastPressedTime + LONG_TOUCH_DURATION)) { - applytouchStatePosition(lastPressedObj, LONG_TOUCHED); + applytouchStatePosition(ctx->lastPressedObj, TOUCH_RELEASED); + if (currentTime >= (ctx->lastPressedTime + LONG_TOUCH_DURATION)) { + applytouchStatePosition(ctx->lastPressedObj, LONG_TOUCHED); } - else if (currentTime >= (lastPressedTime + SHORT_TOUCH_DURATION)) { - applytouchStatePosition(lastPressedObj, TOUCHED); + else if (currentTime >= (ctx->lastPressedTime + SHORT_TOUCH_DURATION)) { + applytouchStatePosition(ctx->lastPressedObj, TOUCHED); } } // Released event has been handled, forget lastPressedObj - lastPressedObj = NULL; + ctx->lastPressedObj = NULL; } else { // PRESSED - if ((lastState == PRESSED) && (lastPressedObj != NULL)) { - if (foundObj != lastPressedObj) { + if ((ctx->lastState == PRESSED) && (ctx->lastPressedObj != NULL)) { + if (foundObj != ctx->lastPressedObj) { // finger has moved out of an object // make sure lastPressedObj still belongs to current screen before warning it - if (nbgl_screenContainsObj(lastPressedObj)) { - applytouchStatePosition(lastPressedObj, OUT_OF_TOUCH); + if (nbgl_screenContainsObj(ctx->lastPressedObj)) { + applytouchStatePosition(ctx->lastPressedObj, OUT_OF_TOUCH); } - lastPressedObj = NULL; + ctx->lastPressedObj = NULL; } else { // warn the concerned object that it is still touched applytouchStatePosition(foundObj, TOUCHING); } } - else if (lastState == RELEASED) { + else if (ctx->lastState == RELEASED) { // newly touched object - lastPressedObj = foundObj; - lastPressedTime = currentTime; + ctx->lastPressedObj = foundObj; + ctx->lastPressedTime = currentTime; applytouchStatePosition(foundObj, TOUCH_PRESSED); applytouchStatePosition(foundObj, TOUCHING); } } - lastState = touchStatePosition->state; + ctx->lastState = touchStatePosition->state; } bool nbgl_touchGetTouchedPosition(nbgl_obj_t *obj, nbgl_touchStatePosition_t **firstPos, nbgl_touchStatePosition_t **lastPos) { - LOG_DEBUG(TOUCH_LOGGER, "nbgl_touchGetTouchedPosition: %p %p\n", obj, lastPressedObj); - if (obj == lastPressedObj) { - *firstPos = &firstTouchedPosition; - *lastPos = &lastTouchedPosition; + nbgl_touchCtx_t *ctx = nbgl_objIsUx(obj) ? &touchCtxs[UX_CTX] : &touchCtxs[APP_CTX]; + LOG_DEBUG(TOUCH_LOGGER, "nbgl_touchGetTouchedPosition: %p %p\n", obj, ctx->lastPressedObj); + if (obj == ctx->lastPressedObj) { + *firstPos = &ctx->firstTouchedPosition; + *lastPos = &ctx->lastTouchedPosition; return true; } return false; @@ -376,8 +400,9 @@ bool nbgl_touchGetTouchedPosition(nbgl_obj_t *obj, uint32_t nbgl_touchGetTouchDuration(nbgl_obj_t *obj) { - if (obj == lastPressedObj) { - return (lastCurrentTime - lastPressedTime); + nbgl_touchCtx_t *ctx = nbgl_objIsUx(obj) ? &touchCtxs[UX_CTX] : &touchCtxs[APP_CTX]; + if (obj == ctx->lastPressedObj) { + return (ctx->lastCurrentTime - ctx->lastPressedTime); } return 0; } diff --git a/lib_ux_nbgl/ux.c b/lib_ux_nbgl/ux.c index d7a807e3c..9d7dbcb45 100644 --- a/lib_ux_nbgl/ux.c +++ b/lib_ux_nbgl/ux.c @@ -75,7 +75,7 @@ void ux_process_finger_event(uint8_t seph_packet[]) #ifdef HAVE_HW_TOUCH_SWIPE pos.swipe = seph_packet[10]; #endif // HAVE_HW_TOUCH_SWIPE - nbgl_touchHandler(&pos, nbTicks * 100); + nbgl_touchHandler(false, &pos, nbTicks * 100); nbgl_refresh(); } } @@ -131,7 +131,7 @@ void ux_process_ticker_event(void) pos.x = touch_info.x; pos.y = touch_info.y; // Send current touch position to nbgl - nbgl_touchHandler(&pos, nbTicks * 100); + nbgl_touchHandler(false, &pos, nbTicks * 100); } #endif // HAVE_SE_TOUCH nbgl_refresh(); diff --git a/unit-tests/lib_nbgl/test_nbgl_obj.c b/unit-tests/lib_nbgl/test_nbgl_obj.c index 54e856dc7..aeb106f9b 100644 --- a/unit-tests/lib_nbgl/test_nbgl_obj.c +++ b/unit-tests/lib_nbgl/test_nbgl_obj.c @@ -188,8 +188,9 @@ void nbgl_screen_reinit(void) { return; } - #ifdef HAVE_SE_TOUCH +void nbgl_touchInit(void) {} + static void test_draw_obj(void **state __attribute__((unused))) { nbgl_image_t *image;