diff --git a/Makefile.app_params b/Makefile.app_params index be6b3b4a6..7953c3f67 100644 --- a/Makefile.app_params +++ b/Makefile.app_params @@ -17,16 +17,12 @@ # Command to print ICONNAME hexadecimal bitmap on stdout according to the # hardware target. -ifneq ($(TARGET),nanos) -#inverse B&W for non Stax -ifneq ($(TARGET_NAME),TARGET_STAX) +#inverse B&W for Nano +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2)) ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --reverse --hexbitmaponly $(ICONNAME) else ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --hexbitmaponly $(ICONNAME) endif -else -ICONHEX_CMD=python3 $(BOLOS_SDK)/icon3.py --hexbitmaponly $(ICONNAME) -endif ######################################### diff --git a/Makefile.defines b/Makefile.defines index 4eb4cef60..e76bbbd2a 100644 --- a/Makefile.defines +++ b/Makefile.defines @@ -17,7 +17,7 @@ # TARGET should be set as an environment variable otherwise it will be read from a `.target` # file in the SDK root repository -TARGETS := nanos nanox nanos2 stax +TARGETS := nanos nanox nanos2 stax europa ifeq ($(TARGET),) ifeq ("$(wildcard $(BOLOS_SDK)/.target)","") $(error No TARGET specified and no .target file in SDK repository $(BOLOS_SDK)) @@ -31,7 +31,7 @@ $(error TARGET not set to a valid value (possible values: $(TARGETS))) endif # for Stax, NBGL must be used -ifeq ($(TARGET),stax) +ifneq (,$(filter $(TARGET),stax europa)) USE_NBGL ?= 1 endif @@ -181,7 +181,17 @@ DEFINES += HAVE_PIEZO_SOUND DEFINES += HAVE_SE_TOUCH DEFINES += NBGL_PAGE DEFINES += NBGL_USE_CASE -#DEFINES += HAVE_DISPLAY_FAST_MODE +else +ifeq ($(TARGET_NAME),TARGET_EUROPA) +DEFINES += HAVE_BAGL_FONT_INTER_REGULAR_28PX +DEFINES += HAVE_BAGL_FONT_INTER_SEMIBOLD_28PX +DEFINES += HAVE_BAGL_FONT_INTER_MEDIUM_36PX +DEFINES += HAVE_INAPP_BLE_PAIRING +DEFINES += HAVE_NBGL +DEFINES += HAVE_PIEZO_SOUND +DEFINES += HAVE_SE_TOUCH +DEFINES += NBGL_PAGE +DEFINES += NBGL_USE_CASE else DEFINES += BAGL_WIDTH=128 ifdef USE_NBGL @@ -191,9 +201,6 @@ DEFINES += NBGL_USE_CASE else DEFINES += HAVE_BAGL endif -ifeq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += BAGL_HEIGHT=32 -endif ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2)) ifndef USE_NBGL DEFINES += HAVE_UX_FLOW @@ -206,6 +213,7 @@ DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX endif endif endif +endif ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2)) # Screen is directly connected to the SE diff --git a/Makefile.glyphs b/Makefile.glyphs index 6c172fdb7..70ed8bc91 100644 --- a/Makefile.glyphs +++ b/Makefile.glyphs @@ -38,14 +38,14 @@ ifdef USE_NBGL # NBGL glyphs files and generation script # # search icons (glyphs) in lib_nbgl/glyphs(_nano) folder of the SDK -ifeq ($(TARGET_NAME),TARGET_STAX) +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) GLYPH_FILES += $(addprefix $(BOLOS_SDK)/lib_nbgl/glyphs/,$(sort $(notdir $(shell find $(BOLOS_SDK)/lib_nbgl/glyphs/)))) GLYPH_OPT := -else # ($(TARGET_NAME),TARGET_STAX) +else # ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) GLYPH_FILES += $(addprefix $(BOLOS_SDK)/lib_nbgl/glyphs_nano/,$(sort $(notdir $(shell find $(BOLOS_SDK)/lib_nbgl/glyphs_nano/)))) #inverse B&W for non Stax GLYPH_OPT := --reverse -endif # ($(TARGET_NAME),TARGET_STAX) +endif # ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) ifneq (,$(wildcard $(ICONNAME))) # Do not try to generate app icon glyph, if image does not exist diff --git a/Makefile.standard_app b/Makefile.standard_app index 29cd89b8d..916091545 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -19,7 +19,7 @@ # BLUETOOTH # ##################################################################### ifeq ($(ENABLE_BLUETOOTH), 1) -ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX)) +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX TARGET_EUROPA)) HAVE_APPLICATION_FLAG_BOLOS_SETTINGS = 1 DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 HAVE_BLE_APDU DEFINES += BLE_SEGMENT_SIZE=32 @@ -128,20 +128,20 @@ endif # NBGL # ##################################################################### ifeq ($(ENABLE_NBGL_QRCODE), 1) -ifeq ($(TARGET_NAME), TARGET_STAX) +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) DEFINES += NBGL_QRCODE SDK_SOURCE_PATH += qrcode endif endif ifeq ($(ENABLE_NBGL_KEYBOARD), 1) -ifeq ($(TARGET_NAME), TARGET_STAX) +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) DEFINES += NBGL_KEYBOARD endif endif ifeq ($(ENABLE_NBGL_KEYPAD), 1) -ifeq ($(TARGET_NAME), TARGET_STAX) +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) DEFINES += NBGL_KEYPAD endif endif @@ -200,7 +200,7 @@ endif ifeq ($(TARGET_NAME), TARGET_NANOS2) ICONNAME ?= $(ICON_NANOSP) endif -ifeq ($(TARGET_NAME),TARGET_STAX) +ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_EUROPA)) ICONNAME ?= $(ICON_STAX) endif diff --git a/include/cx_trampoline.h b/include/cx_trampoline.h index 715886184..a7d8bfd69 100644 --- a/include/cx_trampoline.h +++ b/include/cx_trampoline.h @@ -10,4 +10,6 @@ #define CX_TRAMPOLINE_ADDR 0x00810001 #elif defined(TARGET_STAX) #define CX_TRAMPOLINE_ADDR 0x00818001 +#elif defined(TARGET_EUROPA) +#define CX_TRAMPOLINE_ADDR 0x00818001 #endif diff --git a/lib_blewbxx_impl/src/ledger_ble.c b/lib_blewbxx_impl/src/ledger_ble.c index 94a2a71c8..5ba682e39 100644 --- a/lib_blewbxx_impl/src/ledger_ble.c +++ b/lib_blewbxx_impl/src/ledger_ble.c @@ -181,7 +181,7 @@ static void check_transfer_mode(uint8_t enable); /* Private variables ---------------------------------------------------------*/ // clang-format off -#ifdef TARGET_STAX +#if defined(TARGET_STAX) || defined(TARGET_EUROPA) const uint8_t service_uuid[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x00,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; const uint8_t charUuidTX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x01,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; const uint8_t charUuidRX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x02,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; @@ -451,7 +451,7 @@ static void init_mngr(uint16_t opcode, const uint8_t *buffer, uint16_t length) case BLE_INIT_STEP_SET_TX_POWER_LEVEL: ledger_ble_data.hci_cmd_opcode = 0xfc0f; aci_hal_set_tx_power_level(1, // High power (ignored) -#ifdef TARGET_STAX +#if defined(TARGET_STAX) || defined(TARGET_EUROPA) 0x19); // 0 dBm #else // !TARGET_STAX 0x07); // -14.1 dBm @@ -771,7 +771,7 @@ static void ask_user_pairing_numeric_comparison(uint32_t code) ledger_ble_data.pairing_in_progress = 1; ux_params.u.pairing_request.pairing_info_len = 6; SPRINTF(ux_params.u.pairing_request.pairing_info, "%06d", (unsigned int) code); -#ifdef TARGET_STAX +#if defined(TARGET_STAX) || defined(TARGET_EUROPA) G_io_asynch_ux_callback.asynchmodal_end_callback = NULL; #else // !TARGET_STAX G_io_asynch_ux_callback.asynchmodal_end_callback = rsp_user_pairing_numeric_comparison; @@ -809,7 +809,7 @@ static void ask_user_pairing_passkey(void) ledger_ble_data.pairing_code = cx_rng_u32_range_func(0, 1000000, cx_rng_u32); ux_params.u.pairing_request.pairing_info_len = 6; SPRINTF(ux_params.u.pairing_request.pairing_info, "%06d", ledger_ble_data.pairing_code); -#ifdef TARGET_STAX +#if defined(TARGET_STAX) || defined(TARGET_EUROPA) G_io_asynch_ux_callback.asynchmodal_end_callback = NULL; #else // !TARGET_STAX G_io_asynch_ux_callback.asynchmodal_end_callback = rsp_user_pairing_passkey; diff --git a/lib_nbgl/include/nbgl_font_rom.inc b/lib_nbgl/include/nbgl_font_rom.inc index 41e7ac913..9bdd5a06b 100644 --- a/lib_nbgl/include/nbgl_font_rom.inc +++ b/lib_nbgl/include/nbgl_font_rom.inc @@ -16,18 +16,27 @@ * limitations under the License. ********************************************************************************/ -#ifdef HAVE_SE_TOUCH +#ifdef SCREEN_SIZE_WALLET +#ifdef TARGET_STAX #include "nbgl_font_inter_regular_24.inc" #include "nbgl_font_inter_semibold_24.inc" #include "nbgl_font_inter_medium_32.inc" #include "nbgl_font_inter_regular_24_1bpp.inc" #include "nbgl_font_inter_semibold_24_1bpp.inc" #include "nbgl_font_inter_medium_32_1bpp.inc" -#else // HAVE_SE_TOUCH +#else // TARGET_STAX +#include "nbgl_font_inter_regular_28.inc" +#include "nbgl_font_inter_semibold_28.inc" +#include "nbgl_font_inter_medium_36.inc" +#include "nbgl_font_inter_regular_28_1bpp.inc" +#include "nbgl_font_inter_semibold_28_1bpp.inc" +#include "nbgl_font_inter_medium_36_1bpp.inc" +#endif // TARGET_STAX +#else // SCREEN_SIZE_WALLET #include "nbgl_font_open_sans_extrabold_11.inc" #include "nbgl_font_open_sans_regular_11.inc" #include "nbgl_font_open_sans_light_16.inc" -#endif // HAVE_SE_TOUCH +#endif // SCREEN_SIZE_WALLET #if (defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP)) #if !defined(HAVE_LANGUAGE_PACK) #if (OS_LANGUAGE==LANG_ENGLISH) diff --git a/lib_nbgl/include/nbgl_fonts.h b/lib_nbgl/include/nbgl_fonts.h index 689fd11d9..eda51aa82 100644 --- a/lib_nbgl/include/nbgl_fonts.h +++ b/lib_nbgl/include/nbgl_fonts.h @@ -26,6 +26,7 @@ extern "C" { * @brief fonts nicknames to be used for various wallet size targets (non-Nano) * */ +#ifdef TARGET_STAX #define SMALL_REGULAR_FONT BAGL_FONT_INTER_REGULAR_24px #define SMALL_BOLD_FONT BAGL_FONT_INTER_SEMIBOLD_24px #define LARGE_MEDIUM_FONT BAGL_FONT_INTER_MEDIUM_32px @@ -33,6 +34,18 @@ extern "C" { #define SMALL_BOLD_1BPP_FONT BAGL_FONT_INTER_SEMIBOLD_24px_1bpp #define LARGE_MEDIUM_1BPP_FONT BAGL_FONT_INTER_MEDIUM_32px_1bpp +#else // TARGET_STAX + +#ifdef TARGET_EUROPA +#define SMALL_REGULAR_FONT BAGL_FONT_INTER_REGULAR_28px +#define SMALL_BOLD_FONT BAGL_FONT_INTER_SEMIBOLD_28px +#define LARGE_MEDIUM_FONT BAGL_FONT_INTER_MEDIUM_36px +#define SMALL_REGULAR_1BPP_FONT BAGL_FONT_INTER_REGULAR_28px_1bpp +#define SMALL_BOLD_1BPP_FONT BAGL_FONT_INTER_SEMIBOLD_28px_1bpp +#define LARGE_MEDIUM_1BPP_FONT BAGL_FONT_INTER_MEDIUM_36px_1bpp +#endif +#endif // TARGET_STAX + /********************** * TYPEDEFS **********************/ diff --git a/lib_nbgl/include/nbgl_layout.h b/lib_nbgl/include/nbgl_layout.h index f0bc5a1ca..b0b7fcbea 100644 --- a/lib_nbgl/include/nbgl_layout.h +++ b/lib_nbgl/include/nbgl_layout.h @@ -503,6 +503,8 @@ int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, bool enableDigits); int nbgl_layoutAddHiddenDigits(nbgl_layout_t *layout, uint8_t nbDigits); int nbgl_layoutUpdateHiddenDigits(nbgl_layout_t *layout, uint8_t index, uint8_t nbActive); +int nbgl_layoutAddSwipe(nbgl_layout_t *layout, uint8_t token, uint16_t swipesMask); + #else // HAVE_SE_TOUCH /* layout objects for pages with keypad (nanos) */ int nbgl_layoutAddKeypad(nbgl_layout_t *layout, diff --git a/lib_nbgl/include/nbgl_obj.h b/lib_nbgl/include/nbgl_obj.h index 02ce9606c..e4992bba1 100644 --- a/lib_nbgl/include/nbgl_obj.h +++ b/lib_nbgl/include/nbgl_obj.h @@ -37,7 +37,11 @@ extern "C" { // for Keypad #ifdef HAVE_SE_TOUCH +#if (SCREEN_HEIGHT == 600) +#define KEYPAD_KEY_HEIGHT 88 +#else #define KEYPAD_KEY_HEIGHT 104 +#endif #else // HAVE_SE_TOUCH #define KEYPAD_WIDTH 114 #define KEYPAD_HEIGHT 18 @@ -168,9 +172,17 @@ typedef enum { ///< been pressed. TOUCH_RELEASED, ///< corresponding to an object that was touched and where the finger has been ///< released. - VALUE_CHANGED ///< corresponding to a change of state of the object (indirect event) + VALUE_CHANGED, ///< corresponding to a change of state of the object (indirect event) + SWIPED_UP, + SWIPED_DOWN, + SWIPED_RIGHT, + SWIPED_LEFT, + NB_TOUCH_TYPES } nbgl_touchType_t; +#define SWIPE_MASK \ + ((1 << SWIPED_UP) | (1 << SWIPED_DOWN) | (1 << SWIPED_LEFT) | (1 << SWIPED_RIGHT)) + /** * @brief The different pressed buttons * @@ -239,9 +251,9 @@ typedef struct PACKED__ nbgl_obj_s { int16_t alignmentMarginX; ///< horizontal margin when aligning int16_t alignmentMarginY; ///< vertical margin when aligning nbgl_obj_type_t type; ///< type of the graphical object, must be explicitly set - uint8_t touchMask; ///< bit mask to tell engine which touch events are handled by this object - uint8_t touchId; ///< a unique identifier (by screen) to be used by external test environment - ///< (TTYT or Screenshots) + uint16_t touchMask; ///< bit mask to tell engine which touch events are handled by this object + uint8_t touchId; ///< a unique identifier (by screen) to be used by external test environment + ///< (TTYT or Screenshots) } nbgl_obj_t; /** diff --git a/lib_nbgl/include/nbgl_screen.h b/lib_nbgl/include/nbgl_screen.h index df76fe83f..99da4c803 100644 --- a/lib_nbgl/include/nbgl_screen.h +++ b/lib_nbgl/include/nbgl_screen.h @@ -80,6 +80,7 @@ void nbgl_screen_config_fast_mode(uint8_t fast_mode_setting); #endif // HAVE_CONFIGURABLE_DISPLAY_FAST_MODE void nbgl_screenRedraw(void); +nbgl_obj_t *nbgl_screenGetAt(uint8_t screenIndex); nbgl_obj_t *nbgl_screenGetTop(void); uint8_t nbgl_screenGetCurrentStackSize(void); bool nbgl_screenContainsObj(nbgl_obj_t *obj); diff --git a/lib_nbgl/include/nbgl_types.h b/lib_nbgl/include/nbgl_types.h index 2f4777bd7..4a60d6f4f 100644 --- a/lib_nbgl/include/nbgl_types.h +++ b/lib_nbgl/include/nbgl_types.h @@ -28,6 +28,8 @@ extern "C" { #ifdef SCREEN_SIZE_WALLET #ifdef TARGET_STAX #define SCREEN_WIDTH 400 +#else // TARGET_STAX +#define SCREEN_WIDTH 480 #endif // TARGET_STAX #else // SCREEN_SIZE_WALLET #define SCREEN_WIDTH 128 @@ -39,6 +41,8 @@ extern "C" { #ifdef SCREEN_SIZE_WALLET #ifdef TARGET_STAX #define SCREEN_HEIGHT 672 +#else // TARGET_STAX +#define SCREEN_HEIGHT 600 #endif // TARGET_STAX #else // SCREEN_SIZE_WALLET #define SCREEN_HEIGHT 64 diff --git a/lib_nbgl/src/nbgl_fonts.c b/lib_nbgl/src/nbgl_fonts.c index af53f9f3a..d32e9179c 100644 --- a/lib_nbgl/src/nbgl_fonts.c +++ b/lib_nbgl/src/nbgl_fonts.c @@ -53,6 +53,13 @@ extern const LANGUAGE_PACK *language_pack; #include "nbgl_font_inter_regular_24_1bpp.inc" #include "nbgl_font_inter_semibold_24_1bpp.inc" #include "nbgl_font_inter_medium_32_1bpp.inc" +#else // TARGET_STAX +#include "nbgl_font_inter_regular_28.inc" +#include "nbgl_font_inter_semibold_28.inc" +#include "nbgl_font_inter_medium_36.inc" +#include "nbgl_font_inter_regular_28_1bpp.inc" +#include "nbgl_font_inter_semibold_28_1bpp.inc" +#include "nbgl_font_inter_medium_36_1bpp.inc" #endif // TARGET_STAX #else // SCREEN_SIZE_WALLET #include "nbgl_font_open_sans_extrabold_11.inc" diff --git a/lib_nbgl/src/nbgl_layout.c b/lib_nbgl/src/nbgl_layout.c index e14964968..7ed436693 100644 --- a/lib_nbgl/src/nbgl_layout.c +++ b/lib_nbgl/src/nbgl_layout.c @@ -76,6 +76,12 @@ typedef struct { uint8_t index; // index within the token tune_index_e tuneId; // if not @ref NBGL_NO_TUNE, a tune will be played } layoutObj_t; + +typedef enum { + SWIPE_USAGE_NAVIGATION, + SWIPE_USAGE_CUSTOM, + NB_SWIPE_USAGE +} nbgl_swipe_usage_t; #endif // HAVE_SE_TOUCH /** @@ -106,7 +112,8 @@ typedef struct nbgl_layoutInternal_s { // number of callback objects used by the whole layout in callbackObjPool uint8_t nbUsedCallbackObjs; - nbgl_container_t *container; + nbgl_container_t *container; + nbgl_swipe_usage_t swipeUsage; #else // HAVE_SE_TOUCH nbgl_layoutButtonCallback_t callback; // user callback for all controls #endif // HAVE_SE_TOUCH @@ -208,7 +215,9 @@ static void touchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType) layoutObj_t *layoutObj; bool needRefresh = false; - UNUSED(eventType); + if (obj == NULL) { + return; + } if (getLayoutAndLayoutObj(obj, &layout, &layoutObj) == false) { // try with parent, if existing @@ -222,6 +231,23 @@ static void touchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType) } } + // case of swipe + if (((eventType == SWIPED_UP) || (eventType == SWIPED_DOWN) || (eventType == SWIPED_LEFT) + || (eventType == SWIPED_RIGHT)) + && (obj->type == CONTAINER)) { + if (layout->swipeUsage == SWIPE_USAGE_CUSTOM) { + layoutObj->index = eventType; + } + else if (layout->swipeUsage == SWIPE_USAGE_NAVIGATION) { + if (nbgl_navigationCallback(obj, eventType, layout->nbPages, &layout->activePage) + == false) { + // navigation was impossible + return; + } + layoutObj->index = layout->activePage; + } + } + // case of navigation bar if ((obj->parent == (nbgl_obj_t *) layout->bottomContainer) && (layout->bottomContainerUsage == PAGE_INDICATOR)) { @@ -701,6 +727,36 @@ nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description) return (nbgl_layout_t *) layout; } +static int nbgl_layoutAddSwipeInternal(nbgl_layout_t *layout, + uint8_t token, + uint16_t swipesMask, + nbgl_swipe_usage_t usage) +{ + if ((swipesMask & SWIPE_MASK) == 0) { + return -1; + } + + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_obj_t *swipeContainer = nbgl_objPoolGet(CONTAINER, layoutInt->layer); + + layoutInt->children[layoutInt->nbChildren] = swipeContainer; + layoutInt->nbChildren++; + addCallbackObj(layoutInt, swipeContainer, token, TUNE_TAP_CASUAL); + swipeContainer->touchMask = swipesMask; + layoutInt->swipeUsage = usage; + + return 0; +} + +/** + * @brief Create a swipe interaction + */ + +int nbgl_layoutAddSwipe(nbgl_layout_t *layout, uint8_t token, uint16_t swipesMask) +{ + return nbgl_layoutAddSwipeInternal(layout, token, swipesMask, SWIPE_USAGE_CUSTOM); +} + /** * @brief Creates a Top-right button in the top right corner of the top panel * @@ -791,6 +847,11 @@ int nbgl_layoutAddNavigationBar(nbgl_layout_t *layout, const nbgl_layoutNavigati layoutInt->container->obj.area.height -= 4; } + nbgl_layoutAddSwipeInternal(layout, + info->token, + ((1 << SWIPED_LEFT) | (1 << SWIPED_RIGHT) | (1 << SWIPED_DOWN)), + SWIPE_USAGE_NAVIGATION); + return 0; } @@ -2764,14 +2825,16 @@ int nbgl_layoutAddKeyboard(nbgl_layout_t *layout, const nbgl_layoutKbd_t *kbdInf // create keyboard keyboard = (nbgl_keyboard_t *) nbgl_objPoolGet(KEYBOARD, layoutInt->layer); +#ifdef TARGET_STAX keyboard->obj.alignmentMarginY = 64; - keyboard->obj.alignment = BOTTOM_MIDDLE; - keyboard->borderColor = LIGHT_GRAY; - keyboard->callback = PIC(kbdInfo->callback); - keyboard->lettersOnly = kbdInfo->lettersOnly; - keyboard->mode = kbdInfo->mode; - keyboard->keyMask = kbdInfo->keyMask; - keyboard->casing = kbdInfo->casing; +#endif // TARGET_STAX + keyboard->obj.alignment = BOTTOM_MIDDLE; + keyboard->borderColor = LIGHT_GRAY; + keyboard->callback = PIC(kbdInfo->callback); + keyboard->lettersOnly = kbdInfo->lettersOnly; + keyboard->mode = kbdInfo->mode; + keyboard->keyMask = kbdInfo->keyMask; + keyboard->casing = kbdInfo->casing; // set this new keyboard as child of the container addObjectToLayout(layoutInt, (nbgl_obj_t *) keyboard); diff --git a/lib_nbgl/src/nbgl_obj_keyboard.c b/lib_nbgl/src/nbgl_obj_keyboard.c index 9332cd127..388c159e4 100644 --- a/lib_nbgl/src/nbgl_obj_keyboard.c +++ b/lib_nbgl/src/nbgl_obj_keyboard.c @@ -27,7 +27,11 @@ #define FIRST_LINE_CHAR_COUNT 10 #define SECOND_LINE_CHAR_COUNT 9 -#define NORMAL_KEY_WIDTH 40 +#if (SCREEN_WIDTH == 400) +#define NORMAL_KEY_WIDTH 40 +#else +#define NORMAL_KEY_WIDTH 48 +#endif #define LETTER_OFFSET_Y (((KEYBOARD_KEY_HEIGHT - 32) / 2) & 0xFFC) #define SHIFT_KEY_WIDTH (NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET) #define SECOND_LINE_OFFSET ((SCREEN_WIDTH - (SECOND_LINE_CHAR_COUNT * NORMAL_KEY_WIDTH)) / 2) diff --git a/lib_nbgl/src/nbgl_screen.c b/lib_nbgl/src/nbgl_screen.c index f1638e8ee..a8780d7f7 100644 --- a/lib_nbgl/src/nbgl_screen.c +++ b/lib_nbgl/src/nbgl_screen.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "nbgl_front.h" #include "nbgl_screen.h" #include "nbgl_debug.h" #include "os_pic.h" @@ -76,6 +77,21 @@ void nbgl_screenRedraw(void) nbgl_redrawObject((nbgl_obj_t *) topOfStack, NULL, true); } +/** + * @brief Returns the screen on the given layer index, as a generic object + * @param screenIndex index of the screen in the stack + * @return the screen on the given layer, or NULL if no screen in stack + */ +nbgl_obj_t *nbgl_screenGetAt(uint8_t screenIndex) +{ + if (screenIndex < nbScreensOnStack) { + return (nbgl_obj_t *) &screenStack[screenIndex]; + } + else { + return NULL; + } +} + /** * @brief Returns the screen on top layer, as a generic object * @return the screen on top layer, or NULL if no screen in stack diff --git a/lib_nbgl/src/nbgl_touch.c b/lib_nbgl/src/nbgl_touch.c index 5a498bdf7..65a6fa4ff 100644 --- a/lib_nbgl/src/nbgl_touch.c +++ b/lib_nbgl/src/nbgl_touch.c @@ -13,6 +13,7 @@ #include "nbgl_touch.h" #include "nbgl_screen.h" #include "os_pic.h" +#include "os_io_seproxyhal.h" /********************* * DEFINES @@ -125,6 +126,60 @@ static nbgl_obj_t *getTouchedObject(nbgl_obj_t *obj, nbgl_touchStatePosition_t * } } +/** + * @brief Find first swipeable container object from screen + * + */ + +static nbgl_obj_t *getSwipableObject(nbgl_obj_t *obj, nbgl_touchType_t detectedSwipe) +{ + if (obj == NULL) { + return NULL; + } + + if ((obj->type == SCREEN) || (obj->type == CONTAINER)) { + nbgl_container_t *container = (nbgl_container_t *) obj; + for (uint8_t i = 0; i < container->nbChildren; i++) { + nbgl_obj_t *current = container->children[i]; + if (current != NULL) { + nbgl_obj_t *child = getSwipableObject(current, detectedSwipe); + if (child) { + return child; + } + } + } + } + if (obj->touchMask & (1 << detectedSwipe)) { + return obj; + } + return NULL; +} + +// Swipe detection + +#define SWIPE_THRESHOLD_X 50 +#define SWIPE_THRESHOLD_Y 200 + +static nbgl_touchType_t nbgl_detectSwipe(nbgl_touchStatePosition_t *last, + nbgl_touchStatePosition_t *first) +{ + nbgl_touchType_t detected_swipe = NB_TOUCH_TYPES; + if ((last->y - first->y) >= SWIPE_THRESHOLD_Y) { + detected_swipe = SWIPED_DOWN; + } + else if ((first->y - last->y) >= SWIPE_THRESHOLD_Y) { + detected_swipe = SWIPED_UP; + } + else if ((last->x - first->x) >= SWIPE_THRESHOLD_X) { + detected_swipe = SWIPED_RIGHT; + } + else if ((first->x - last->x) >= SWIPE_THRESHOLD_X) { + detected_swipe = SWIPED_LEFT; + } + + return detected_swipe; +} + /********************** * GLOBAL FUNCTIONS **********************/ @@ -172,19 +227,24 @@ void nbgl_touchHandler(nbgl_touchStatePosition_t *touchStatePosition, uint32_t c } // Released event has been handled, forget lastPressedObj lastPressedObj = NULL; - lastState = touchStatePosition->state; - return; } // memorize last touched position memcpy(&lastTouchedPosition, touchStatePosition, sizeof(nbgl_touchStatePosition_t)); if (touchStatePosition->state == RELEASED) { - // 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 - if ((lastPressedObj != NULL) - && ((foundObj == lastPressedObj) || (nbgl_screenContainsObj(lastPressedObj)))) { + nbgl_touchType_t swipe = nbgl_detectSwipe(touchStatePosition, &firstTouchedPosition); + + if (swipe != NB_TOUCH_TYPES) { + // Swipe detected + lastPressedObj = getSwipableObject(nbgl_screenGetTop(), swipe); + applytouchStatePosition(lastPressedObj, swipe); + } + else if ((lastPressedObj != NULL) + && ((foundObj == lastPressedObj) || (nbgl_screenContainsObj(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); diff --git a/lib_stusb_impl/usbd_impl.c b/lib_stusb_impl/usbd_impl.c index 7fdfac406..cc734e71b 100644 --- a/lib_stusb_impl/usbd_impl.c +++ b/lib_stusb_impl/usbd_impl.c @@ -225,6 +225,22 @@ static uint8_t const USBD_PRODUCT_FS_STRING[] = { 'a', 0, 'x', 0, }; +#elif defined(TARGET_EUROPA) +#ifndef HAVE_LEGACY_PID +#define USBD_PID 0x6000 +#else // HAVE_LEGACY_PID +#define USBD_PID 0x0006 +#endif // HAVE_LEGACY_PID +static uint8_t const USBD_PRODUCT_FS_STRING[] = { + 6*2+2, + USB_DESC_TYPE_STRING, + 'E', 0, + 'u', 0, + 'r', 0, + 'o', 0, + 'p', 0, + 'a', 0, +}; #else #error unknown TARGET_NAME #endif diff --git a/target/europa/include/bolos_target.h b/target/europa/include/bolos_target.h new file mode 100644 index 000000000..8560fb5d2 --- /dev/null +++ b/target/europa/include/bolos_target.h @@ -0,0 +1,5 @@ +#ifndef ST33K1M5 +#define ST33K1M5 +#endif // ST33K1M5 +#define TARGET_ID 0x33300004 +#define TARGET_EUROPA diff --git a/target/europa/plugin_script.ld b/target/europa/plugin_script.ld new file mode 100644 index 000000000..61bcc010a --- /dev/null +++ b/target/europa/plugin_script.ld @@ -0,0 +1,22 @@ +/******************************************************************************* +* Ledger - Secure firmware +* (c) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Ledger +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +********************************************************************************/ + +/* Reuse the main linker script */ +INCLUDE script.ld + +/* No global variable allowed in plugins */ +ASSERT( (_ebss - _bss) <= 0, ".bss section must be empty for plugins" ) diff --git a/target/europa/script.ld b/target/europa/script.ld new file mode 100644 index 000000000..ae52569cf --- /dev/null +++ b/target/europa/script.ld @@ -0,0 +1,188 @@ +/******************************************************************************* +* Ledger - Secure firmware +* (c) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Ledger +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +********************************************************************************/ + +/** + * Global chip memory layout and constants + * + */ + +MEMORY +{ + DISCARD (rwx) : ORIGIN = 0xd0000000, LENGTH = 1M + + FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K + DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K + SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 44K +} + +PAGE_SIZE = 512; +STACK_MIN_SIZE = DEFINED(stack_min_size) ? stack_min_size : 1500; +END_STACK = ORIGIN(SRAM) + LENGTH(SRAM); + +ENTRY(main); + +SECTIONS +{ + /****************************************************************/ + /* This section locates the code in FLASH */ + /****************************************************************/ + + /** put text in Flash memory, VMA will be equal to LMA */ + .text : + { + /* provide start code symbol, shall be zero */ + _text = .; + _nvram_start = .; + + /* ensure main is always @ 0xC0D00000 */ + *(.boot*) + + /* place the other code and rodata defined BUT nvram variables that are displaced in a r/w area */ + _code = .; + *(.text*) + _ecode = .; + + *(.rodata) + *(.rodata.[^N]*) /*.data.rel.ro* not here to detect invalid PIC usage */ + *(.rodata.N[^_]*) + + . = ALIGN(4); + + /* all code placed */ + _etext = .; + + . = ALIGN(PAGE_SIZE); + + _nvram_data = .; + + /* NVM data (ex-filesystem) */ + *(.bss.N_* .rodata.N_*) + + . = ALIGN(PAGE_SIZE); + _envram_data = .; + + _install_parameters = .; + *(.install_parameters) + KEEP(*(.install_parameters)) + _einstall_parameters = .; + _nvram_end = .; + } > FLASH = 0x00 + + .data (NOLOAD): + { + . = ALIGN(4); + + /** + * Place RAM initialized variables + */ + _data = .; + + *(vtable) + *(.data*) + + _edata = .; + + } > DISCARD /*> SRAM AT>FLASH = 0x00 */ + + ASSERT( (_edata - _data) <= 0, ".data section must be empty" ) + + .bss : + { + /** + * Place RAM uninitialized variables + */ + _bss = .; + *(.bss*) + _ebss = .; + + + /** + * Reserve stack size + */ + . = ALIGN(4); + app_stack_canary = .; + PROVIDE(app_stack_canary = .); + . += 4; + _stack = .; + PROVIDE( _stack = .); + _estack = ABSOLUTE(END_STACK); + PROVIDE( _estack = ABSOLUTE(END_STACK) ); + + } > SRAM = 0x00 + + ASSERT( (_estack - _stack) >= STACK_MIN_SIZE, "stack section too small" ) + + /****************************************************************/ + /* DEBUG */ + /****************************************************************/ + + /* remove the debugging information from the standard libraries */ + DEBUG (NOLOAD) : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > DISCARD + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + ledger.target (INFO): { KEEP(*(ledger.target)) } + ledger.target_name (INFO): { KEEP(*(ledger.target_name)) } + ledger.target_id (INFO): { KEEP(*(ledger.target_id)) } + ledger.app_name (INFO): { KEEP(*(ledger.app_name)) } + ledger.app_version (INFO): { KEEP(*(ledger.app_version)) } + ledger.api_level (INFO): { KEEP(*(ledger.api_level)) } + ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } + ledger.sdk_version (INFO): { KEEP(*(ledger.sdk_version)) } + ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } +} + +PROVIDE(_nvram = ABSOLUTE(_nvram_start)); +PROVIDE(_envram = ABSOLUTE(_nvram_end));