From 177879d432ca4082e0a243175e896786225c3bcd Mon Sep 17 00:00:00 2001 From: Lephe Date: Sat, 3 Dec 2022 11:04:43 +0100 Subject: [PATCH] usb: add a USB_TRACE() debugging mechanism --- include/gint/usb.h | 21 +++++++++++---------- src/usb/pipes.c | 6 ++++++ src/usb/usb.c | 19 +++++++++++++++++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/gint/usb.h b/include/gint/usb.h index 95547cd..ab84b07 100644 --- a/include/gint/usb.h +++ b/include/gint/usb.h @@ -269,27 +269,28 @@ int usb_commit_sync_timeout(int pipe, timeout_t const *timeout); int usb_commit_async(int pipe, gint_call_t callback); //--- -// USB debugging log +// USB debugging functions //--- #ifdef GINT_USB_DEBUG #define USB_LOG(...) usb_log(__VA_ARGS__) +#define USB_TRACE(...) usb_trace(__VA_ARGS__) -/* usb_set_log(): Set the logging function for the USB driver - - The USB driver can produce logs, which are mostly useful to troubleshoot - problems and add new protocols. The logging is disabled by default but can - be enabled by specifying this function. - - It is up to you whether to store that in a buffer, rotate logs, send them to - storage memory or a console on the PC. */ +/* usb_set_log(): Set the logging function for the USB driver */ void usb_set_log(void (*logger)(char const *format, va_list args)); - /* usb_log(): Send a message to the USB log */ void usb_log(char const *format, ...); +/* usb_set_trace(): Set the tracing function for the USB driver + The function is called atomically, thus cannot be interrupted, therefore it + is safe to call usb_trace() in interrupt handlers. */ +void usb_set_trace(void (*tracer)(char const *message)); +/* usb_trace(): Trace the current state of the driver */ +void usb_trace(char const *message); + #else #define USB_LOG(...) do {} while(0) +#define USB_TRACE(...) do {} while(0) #endif //--- diff --git a/src/usb/pipes.c b/src/usb/pipes.c index b0799a2..5300056 100644 --- a/src/usb/pipes.c +++ b/src/usb/pipes.c @@ -224,6 +224,8 @@ static void finish_transfer(struct transfer volatile *t, int pipe) if(pipe) USB.BEMPENB.word &= ~(1 << pipe); if(t->callback.function) gint_call(t->callback); + + USB_TRACE("finish_transfer()"); } /* finish_round(): Update transfer logic after a write round completes @@ -252,6 +254,8 @@ static void finish_round(struct transfer volatile *t, int pipe) t->data = NULL; if(t->callback.function) gint_call(t->callback); } + + USB_TRACE("finish_round()"); } /* write_round(): Write up to a FIFO's worth of data to a pipe @@ -304,6 +308,8 @@ static void write_round(struct transfer volatile *t, int pipe) if(t->unit_size == 4) write_32(t->data, size >> 2, FIFO); if(partial) finish_round(t, pipe); } + + USB_TRACE("write_round()"); } int usb_write_async(int pipe, void const *data, int size, int unit_size, diff --git a/src/usb/usb.c b/src/usb/usb.c index 1bf803c..79f84a7 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "usb_private.h" #define USB SH7305_USB @@ -27,10 +28,11 @@ static gint_call_t usb_open_callback = GINT_CALL_NULL; static bool volatile usb_open_status = false; //--- -// Logging system +// Debugging functions //--- static void (*usb_logger)(char const *format, va_list args) = NULL; +static void (*usb_tracer)(char const *message) = NULL; void usb_set_log(void (*logger)(char const *format, va_list args)) { @@ -40,13 +42,26 @@ void usb_set_log(void (*logger)(char const *format, va_list args)) void usb_log(char const *format, ...) { if(!usb_logger) return; - va_list args; va_start(args, format); usb_logger(format, args); va_end(args); } +void usb_set_trace(void (*tracer)(char const *message)) +{ + usb_tracer = tracer; +} + +void usb_trace(char const *message) +{ + if(usb_tracer) { + cpu_atomic_start(); + usb_tracer(message); + cpu_atomic_end(); + } +} + //--- // Module powering and depowering //---