echoplayer: allow enabling system debug in normal builds

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 19af7131e28d35a5afcfa77cb5c1b7e19e000f56
Author: Aidan MacDonald <[email protected]>
Date:   Thu Feb 5 22:11:40 2026 +0000

    echoplayer: allow enabling system debug in normal builds
    
    Allow toggling the system debug state from the debug menu
    in Rockbox, or by holding a button combo at boot, so that
    an SWD/JTAG debugger can be attached to normal non-debug
    builds without too much hassle.
    
    Change-Id: Iee47ef916ade2e5ec1094a63c68e48f1b27b0bbb

diff --git a/bootloader/echoplayer.c b/bootloader/echoplayer.c
index 6f742aec50..97b5ec2749 100644
--- a/bootloader/echoplayer.c
+++ b/bootloader/echoplayer.c
@@ -34,6 +34,7 @@
 #include "rbversion.h"
 #include "system-echoplayer.h"
 #include "gpio-stm32h7.h"
+#include "regs/cortex-m/cm_debug.h"
 
 #define SDRAM_SIZE          (MEMORYSIZE * 1024 * 1024)
 
@@ -136,6 +137,14 @@ static bool is_usbmode_button_pressed(void)
     return button_status() & BUTTON_DOWN;
 }
 
+static bool is_sysdebug_button_pressed(void)
+{
+    const int mask = BUTTON_A | BUTTON_B;
+
+    /* Both buttons must be held */
+    return (button_status() & mask) == mask;
+}
+
 static int send_event_on_tmo(struct timeout *tmo)
 {
     button_queue_post(tmo->data, 0);
@@ -370,6 +379,13 @@ void main(void)
     power_init();
     button_init();
 
+    /* Enable system debugging if button combo held or debugger attached */
+    if (reg_readf(CM_DEBUG_DHCSR, C_DEBUGEN) ||
+        is_sysdebug_button_pressed())
+    {
+        system_debug_enable(true);
+    }
+
     /* Start monitoring power button / usb state */
     monitor_init();
 
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 6c0bec8219..4fa1cfaaf1 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1943,7 +1943,9 @@ target/arm/rk27xx/ihifi2/audio-ihifi800.c
 target/arm/stm32/crt0-stm32h7.S
 target/arm/stm32/vectors-stm32h7.S
 target/arm/stm32/adc-stm32h7.c
+#ifndef BOOTLOADER
 target/arm/stm32/debug-stm32h7.c
+#endif
 target/arm/stm32/gpio-stm32h7.c
 target/arm/stm32/i2c-stm32h7.c
 target/arm/stm32/pcm-stm32h7.c
diff --git a/firmware/reggen/cortex-m.regs b/firmware/reggen/cortex-m.regs
index 4be406b928..cb95bed5cf 100644
--- a/firmware/reggen/cortex-m.regs
+++ b/firmware/reggen/cortex-m.regs
@@ -168,3 +168,10 @@ CM_SYSTICK @ 0xe000e000 : block {
         23 00 TENMS
     }
 }
+
+// Debug
+CM_DEBUG @ 0xe000edf0 : block {
+    DHCSR @ 0x00 : reg {
+        0 C_DEBUGEN
+    }
+}
diff --git a/firmware/target/arm/stm32/debug-stm32h7.c b/firmware/target/arm/stm32/debug-stm32h7.c
index e7ffd1c37a..99a3849b41 100644
--- a/firmware/target/arm/stm32/debug-stm32h7.c
+++ b/firmware/target/arm/stm32/debug-stm32h7.c
@@ -19,10 +19,115 @@
  *
  ****************************************************************************/
 #include "system.h"
+#include "kernel.h"
+#include "button.h"
+#include "lcd.h"
+#include "font.h"
+#include "action.h"
+#include "list.h"
+#include "regs/stm32h743/dbgmcu.h"
+#include "regs/cortex-m/cm_debug.h"
+#include <stdio.h>
+
+enum
+{
+    SWD_MENU_IS_ENABLED,
+    SWD_MENU_IS_ATTACHED,
+    SWD_MENU_NUM_ENTRIES
+};
+
+static int swd_menu_action_cb(int action, struct gui_synclist *lists)
+{
+    int sel = gui_synclist_get_sel_pos(lists);
+
+    if (sel == SWD_MENU_IS_ENABLED && action == ACTION_STD_OK)
+    {
+        if (reg_readf(DBGMCU_CR, DBGSLEEP_D1))
+            system_debug_enable(false);
+        else
+            system_debug_enable(true);
+
+        action = ACTION_REDRAW;
+    }
+
+    if (action == ACTION_NONE)
+        action = ACTION_REDRAW;
+
+    return action;
+}
+
+static const char *swd_menu_get_name(int item, void *data, char *buf, size_t bufsz)
+{
+    (void)data;
+
+    switch (item)
+    {
+    case SWD_MENU_IS_ENABLED:
+        snprintf(buf, bufsz, "System debug enabled: %d",
+                 (int)!!reg_readf(DBGMCU_CR, DBGSLEEP_D1));
+        return buf;
+
+    case SWD_MENU_IS_ATTACHED:
+        snprintf(buf, bufsz, "DHCSR.C_DEBUGEN bit: %d",
+                 (int)!!reg_readf(CM_DEBUG_DHCSR, C_DEBUGEN));
+        return buf;
+
+    default:
+        return "";
+    }
+}
+
+static bool swd_menu(void)
+{
+    struct simplelist_info info;
+    simplelist_info_init(&info, "SWD/JTAG", SWD_MENU_NUM_ENTRIES, NULL);
+    info.action_callback = swd_menu_action_cb;
+    info.get_name = swd_menu_get_name;
+    return simplelist_show_list(&info);
+}
+
+/* Menu definition */
+static const struct {
+    const char *name;
+    bool (*function) (void);
+} menuitems[] = {
+    {"SWD/JTAG", swd_menu},
+};
+
+static int hw_info_menu_action_cb(int btn, struct gui_synclist *lists)
+{
+    if (btn == ACTION_STD_OK)
+    {
+        int sel = gui_synclist_get_sel_pos(lists);
+        FOR_NB_SCREENS(i)
+            viewportmanager_theme_enable(i, false, NULL);
+
+        menuitems[sel].function();
+        btn = ACTION_REDRAW;
+
+        FOR_NB_SCREENS(i)
+            viewportmanager_theme_undo(i, false);
+    }
+
+    return btn;
+}
+
+static const char* hw_info_menu_get_name(int item, void *data, char *buf, size_t bufsz)
+{
+    (void)buf;
+    (void)bufsz;
+    (void)data;
+    return menuitems[item].name;
+}
 
 bool dbg_hw_info(void)
 {
-    return false;
+    struct simplelist_info info;
+    simplelist_info_init(&info, MODEL_NAME " debug menu",
+                         ARRAYLEN(menuitems), NULL);
+    info.action_callback = hw_info_menu_action_cb;
+    info.get_name = hw_info_menu_get_name;
+    return simplelist_show_list(&info);
 }
 
 bool dbg_ports(void)
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.