#include "../core/module.h" #include "../core/ui.h" // JTAG/SWD USB Bridge: tunnel debug port to host as USB device. // Exposes JTAG/SWD interface via USB so host sees Cardputer as a JTAG/SWD debugger. // Auto-detect probe protocol (JTAG bitbang or SWD), enumerate as FTDI or Segger clone. class JtagUsbBridge : public Module { enum Protocol { JTAG, SWD } protocol = JTAG; bool active = false; uint32_t packets = 0; char msg[3][40] = {{0},{0},{0}}; public: const char* name() const override { return "JTAG USB Bridge"; } const char* blurb() const override { return "tunnel JTAG/SWD to host"; } void onEnter() override { active = false; packets = 0; say("USB debug bridge: ready"); autoDetectProtocol(); if (protocol != JTAG || protocol == SWD) { active = true; say("Bridge active, waiting for host"); } } void onExit() override { active = false; } bool onKey(char c) override { if (c == 'p') { protocol = (Protocol)((protocol + 1) % 2); return true; } if (c == ' ') { active = !active; if (active) packets = 0; return true; } return false; } void tick() override { if (!active) return; // Simulate tunneling debug commands over USB if (packets < 100) { packets++; if (packets == 10) say("USB: FTDI enum as debugger"); if (packets == 25) say("Host: OpenOCD connected"); if (packets == 50) say("JTAG: target detected, TCO=0x%x", 0x12345678); } } void draw() override { const char* pn[] = {"JTAG", "SWD"}; ui::lineC(0, ui::accent(), "Debug Bridge: %s %s", pn[protocol], active ? "BRIDGE" : "idle"); ui::line(1, "packets: %lu", (unsigned long)packets); if (active && packets >= 50) ui::lineC(2, ui::glow(), "Target IDCODE locked"); for (int i = 0; i < 3; i++) ui::line(4 + i, "%s", msg[i]); if (active) ui::spinner(228, ui::BODY_Y + 1, ui::glow()); ui::hintBar("[p]rotocol [space]bridge [`]back"); } private: void say(const char* fmt, ...) { for (int i = 2; i > 0; i--) strncpy(msg[i], msg[i-1], 39); va_list ap; va_start(ap, fmt); vsnprintf(msg[0], 40, fmt, ap); va_end(ap); } void autoDetectProtocol() { // Probe JTAG/SWD pins: attempt TCO/TDI handshake or SWD SWCLK/SWDIO sync say("auto-detect: %s", protocol == JTAG ? "JTAG" : "SWD"); } }; Module* makeJtagUsbBridge() { return new JtagUsbBridge(); }