Fix touch navbar and touch input on display orientation flip - #1
Conversation
Since ESP-IDF v5.5 (espressif/esp-idf@e73d78ba) i2c_del_master_bus() refuses to delete a bus that still has devices attached and returns ESP_ERR_INVALID_STATE. The touchscreen task registers a panel IO device on the bus but never releases it, so under IDF 5.5.4 the first touchscreen_deinit() fails and aborts via ESP_ERROR_CHECK. On boards that panic with PRINT_HALT, such as the Waveshare S3 Touch LCD 2, this freezes the device on the boot splash screen while gathering camera entropy, and also hangs the QR scanner and the camera exit path, since the touchscreen is restarted around every camera start/stop (see Blockstream#306). Releasing the touch handle and the panel IO device (which removes it from the bus) before deleting the bus restores the deinit/init cycle, and also fixes a heap leak present under IDF 5.4 where both handles leaked on every cycle. Co-authored-by: oroderico <oroderico@users.noreply.github.com>
|
I updated the PR base to a clean branch on my fork: base: oroderico/Jade:touch-flip-orientation-base Now the PR diff is clean again: 4 files changed, based on the current upstream/master. I also tested the Waveshare behavior again. The navbar redraw works, and entering/exiting the QR scanner with flip enabled also worked fine. The remaining issue is mirror_x: with esp_lcd_touch_set_mirror_x(ret_touch, flipped), enabling flip makes the side buttons behave swapped. Tapping the visual right button triggers prev, and tapping the visual left button triggers next. I did a minimal test on top of your branch keeping mirror_y = flipped, but setting mirror_x = false. With that change, prev/OK/next worked correctly in both orientations, including after entering and exiting the QR scanner. So it looks like, at least on the Waveshare, we need to mirror Y to follow the navbar band, but not mirror X. Could you update your branch with that adjustment so I can test it again? |
Since ESP-IDF v5.5 i2c_del_master_bus() refuses to delete a bus that still has devices attached and returns ESP_ERR_INVALID_STATE. On the M5CoreS3, power_init() attaches the axp2101 and aw9523 devices and then deletes the bus without releasing them, so under IDF 5.5.4 the deinit fails, power_init() propagates the error and the JADE_ASSERT in main.c aborts the boot. Same root cause as the touchscreen fix in the previous commit (Blockstream#306). Remove both devices from the bus before deleting it. Not tested on hardware (none available); the change mirrors the touchscreen fix validated on the Waveshare S3 Touch LCD 2.
394dc37 to
5c22b7d
Compare
On boards with a virtual touch navbar (TTGO TWatchS3, M5 CoreS3, Waveshare S3 Touch LCD 2) the prev/OK/next buttons are drawn only once at startup, inside display_init(). Flipping the display orientation remaps the panel scan direction, so the navbar was left stale and upside down at the wrong edge of the panel. Extract the drawing code into display_touch_navbar_redraw() and call it from gui_set_flipped_orientation() whenever the orientation actually changes. Boards without a navbar get an inline no-op stub. The TOUCH_BUTTON_AREA constant moves to display.h so the touch input code can share it. The two 50 ms settle delays stay in display_init(), as flipping does not need them. Co-authored-by: Gustavo Cateim <cateim@gmail.com>
The touch controllers keep reporting physical panel coordinates after the display orientation is flipped, so the virtual navbar buttons stop lining up: taps land on the stale y band and prev/next act swapped left/right (the FIXME removed here described exactly this). Instead of teaching the button handler about orientation, apply esp_lcd_touch_set_mirror_x/_y from the touchscreen task whenever the gui orientation changes. The esp_lcd_touch component mirrors the coordinates in software (x_max - x, y_max - y) for drivers without hardware mirror support, which covers both the CST816S and the FT5X06, so touch input always matches the display coordinate space on every board with a navbar. The M5 Core2 is excluded: its buttons are silk-screened on a fixed capacitive strip below the display and must not follow the flip. For the software mirror to be correct y_max must span the full touch panel, including the navbar area below the main display, so it gains TOUCH_BUTTON_AREA. The navbar band check also replaces the hardcoded touch_y > 200 with the board display height: on displays taller than 200 pixels, such as the Waveshare S3 Touch LCD 2 (280 pixels), the old value made taps on the bottom of the GUI area trigger navigation. Co-authored-by: oroderico <oroderico@users.noreply.github.com>
bc87c1a to
0ed220f
Compare
Description
On touchscreen boards the Display -> Flip Orientation feature left the virtual navbar unusable: the buttons were not redrawn at the new panel edge, and touch input kept using physical coordinates, so the y band was stale and prev/next acted swapped. This PR redraws the navbar on flip and mirrors the touch coordinates to follow the display, fixing the feature on all boards with a virtual navbar. Based on top of Blockstream#307 (touch i2c deinit fix); to be rebased once it lands.
Root Cause / Context
display_init()(main/display.c) and never again;esp_lcd_panel_mirror()remaps the panel on flip (main/display_hw.c:229), leaving the navbar stale at the wrong edge.main/input/touchscreen.incdescribed the problem (y band plus prev/next inversion).esp_lcd_touchcomponent applies mirror flags in software (x_max - x,y_max - y) insideesp_lcd_touch_get_coordinates()when the driver has no hardware support, which is the case for both the CST816S and the FT5X06, soesp_lcd_touch_set_mirror_x/_yworks uniformly here.tp_cfg.y_maxwas set to the display height only, but the touch panel extendsTOUCH_BUTTON_AREA(40 px) below the display; the software mirror needs the real panel span or coordinates underflow.touch_y > 200: correct for 200 px displays (CoreS3, TWatchS3), wrong for the 280 px Waveshare, where taps on the bottom 80 px of the GUI area triggered navigation.Changes
main/display.cdisplay_init()intodisplay_touch_navbar_redraw(); init behavior unchanged (settle delays stay in init).main/display.hdisplay_touch_navbar_redraw()with an inline no-op stub for boards without a navbar; promoteTOUCH_BUTTON_AREAhere so input code can share the constant.main/gui.cgui_set_flipped_orientation()redraws the navbar when the orientation actually changes.main/input/touchscreen.incesp_lcd_touch_set_mirror_x/_ywhenever the gui orientation changes. Applied from the touch task itself (no locking needed) and reapplied automatically after the camera touch restart, since the tracking state is task-local.y_maxnow spans the full touch panel including the navbar area.CONFIG_DISPLAY_HEIGHT + CONFIG_DISPLAY_OFFSET_Yinstead of the hardcoded 200.Testing
Motivation
Makes Display -> Flip Orientation fully functional on the touchscreen boards instead of a per-board workaround, with no orientation logic in the button handler.