diff --git a/README.md b/README.md
index 49d6ea838bd539a05dee1c90ff41ce961a929cc1..6288bc5899c1344854dbb21a547f46d709a30fc6 100644
--- a/README.md
+++ b/README.md
@@ -84,22 +84,72 @@ $ make clean
 ```
 
 3. access micropython repl:
+
 ```
 $ picocom -b 115200 /dev/ttyACM0
+$ # OR
+# screen /dev/ttyACM0
 ```
 
 ## how to modify
 
 ### general info
+
 global + micropython entry point: app_main() in micropython/ports/esp32/main.c (includes badge23/espan.h)
 c entry point, called by^: os_app_main() in badge23/espan.c
 register new c files for compilation: add to set(BADGE23_LIB) in micropython/ports/esp32/main/CMakelists.txt
 change output volume in the set_global_vol_dB(int8_t) call; -90 for mute
 
-to debug c files: printf broken atm, instead use:
-#include "../../py/mphal.h"
-mp_hal_stdout_tx_str("debug output: string literal here\n\r");
+### Debugging
+
+The badge is currently configured to run in HW USB UART/JTAG mode (vs. using TinyUSB and 'software' CDC/whatever using the generic OTG peripheral).
+
+What this means:
+
+1. You can use the MicroPython REPL over a USB console,
+2. The MicroPython REPL will also print ESP-IDF logs, including panics,
+3. You can use OpenOCD/GDB.
+
+#### printf() debugging and logging in C-land
+
+Given the above, you can do the following to get a log. This is part of ESP-IDF's standard logging functionality.
+
+```
+static const char *TAG = "misery";
+// ...
+ESP_LOGI(TAG, "i love C");
+```
+
+However, this will **only work** if you modify `micropython/ports/esp32/boards/sdkconfig.base` to set `CONFIG_LOG_DEFAULT_LEVEL_INFO=y` (which will likely break programs interacting with micropython REPL as many components of the ESP-IDF will suddenly become very chatty). But that's fine for troubleshooting some C-land bugs.
+
+If you want to only log errors or just add temporary logs, use `ESP_LOGE` instead, which will always print to the USB console.
+
+`printf()` also just works. But it should only be used for development debugging, for long-term logging statements please use `ESP_LOG*` instead.
+
+#### Running OpenOCD+GDB
 
-don't expect esp component registry or idf.py menuconfig to work.
-tried adding config items manually to micropython/ports/esp32/boards/sdkconfig.badge23, doesn't work :/
-just put them into header files manually ig;;
+First, make sure your badge is running in application mode (not bootloader mode! that will stay in bootloader mode).
+
+```
+$ make -C micropython/ports/esp32 openocd
+```
+
+Then, in another terminal:
+
+```
+$ make -C micropython/ports/esp32 gdb
+```
+
+Good luck.
+
+### ESP-IDF functionality
+
+Micropython splits up sdkconfig into a bunch of small files. Unfortunately, that doesn't work well with ESP-IDFs menuconfig.
+
+If you want to permanently toggle options, you'll have to do that by modifying `micropython/ports/esp32/boards/sdkconfig.badge23`, or another file referenced by `micropython/ports/esp32/GENERIC_S3_BADGE/mpconfigboard.cmake`. Keep in mind the usual Kconfig shenanigants: disabling an options requires removing its line (not setting it to 'n'!), and that some options might be enabled automatically by other options. After modifying files, you must `make clean` in micropython/ports/esp32. Bummer.
+
+To verify whether your configuration is what you expect it to be, you can still run menuconfig on the effective/calculated sdkconfig that micropython assembles. You can even modify the settings which will affect the build, but will be lost on `make clean` (and on git push, of course). To do so, run:
+
+```
+$ make -C micropython/ports/esp32 menuconfig
+```
\ No newline at end of file
diff --git a/micropython/ports/esp32/Makefile b/micropython/ports/esp32/Makefile
index 47c98292c931889b8420a11d42a2e7100f4e2907..384c9e1a339879e28900cb55fa4b02188ca21342 100644
--- a/micropython/ports/esp32/Makefile
+++ b/micropython/ports/esp32/Makefile
@@ -60,6 +60,18 @@ all:
 
 $(BUILD)/bootloader/bootloader.bin $(BUILD)/partition_table/partition-table.bin $(BUILD)/micropython.bin: FORCE
 
+openocd:
+	OPENOCD_COMMANDS='-f board/esp32s3-builtin.cfg' idf.py $(IDFPY_FLAGS) -p $(PORT) -b $(BAUD) openocd
+
+gdb:
+	OPENOCD_COMMANDS='-f board/esp32s3-builtin.cfg' idf.py $(IDFPY_FLAGS) -p $(PORT) -b $(BAUD) gdb
+
+monitor:
+	idf.py $(IDFPY_FLAGS) -p $(PORT) -b $(BAUD) monitor
+
+menuconfig:
+	idf.py $(IDFPY_FLAGS) menuconfig
+
 clean:
 	idf.py $(IDFPY_FLAGS) fullclean
 
diff --git a/micropython/ports/esp32/boards/GENERIC_S3_BADGE/mpconfigboard.cmake b/micropython/ports/esp32/boards/GENERIC_S3_BADGE/mpconfigboard.cmake
index cb32e3ceeaf2a4e81a843f2bee82e19876626d3a..d5fa78fead4a2e989535e7b03234e343e6847026 100644
--- a/micropython/ports/esp32/boards/GENERIC_S3_BADGE/mpconfigboard.cmake
+++ b/micropython/ports/esp32/boards/GENERIC_S3_BADGE/mpconfigboard.cmake
@@ -3,7 +3,6 @@ set(IDF_TARGET esp32s3)
 set(SDKCONFIG_DEFAULTS
     boards/sdkconfig.base
     boards/sdkconfig.badge23
-    boards/sdkconfig.usb
     boards/sdkconfig.ble
     boards/GENERIC_S3/sdkconfig.board
 )
diff --git a/micropython/ports/esp32/boards/sdkconfig.badge23 b/micropython/ports/esp32/boards/sdkconfig.badge23
index 3025075ce67dcc3dc6064009b84c7d11b7596de5..8bae96ff863557ae61612288dca780d733edf207 100644
--- a/micropython/ports/esp32/boards/sdkconfig.badge23
+++ b/micropython/ports/esp32/boards/sdkconfig.badge23
@@ -75,3 +75,4 @@ CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3
 CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3
 CONFIG_SOC_MCPWM_SWSYNC_CAN_PROPAGATE=y
 
+CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
\ No newline at end of file