From b63d58515cb29a2d3d1441c5fab9bbf92f1b3f41 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Tue, 20 Apr 2021 10:22:12 +0200 Subject: [PATCH] gint/usb: add a USB communication test (WIP) --- CMakeLists.txt | 4 + assets-fx/img/opt_gint_usb.png | Bin 0 -> 4550 bytes include/gintctl/assets.h | 1 + include/gintctl/gint.h | 3 + include/gintctl/menu.h | 10 +- src/gint/usb.c | 329 +++++++++++++++++++++++++++++++++ src/gintctl.c | 1 + 7 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 assets-fx/img/opt_gint_usb.png create mode 100644 src/gint/usb.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b6cbc9a..5ba7b92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ find_package(LibProf 2.1 REQUIRED) find_package(LibImg 2.1 REQUIRED) find_package(JustUI 1.0 REQUIRED) +set_property(GLOBAL PROPERTY RULE_MESSAGES OFF) + set(SOURCES src/gintctl.c src/menu.c @@ -34,6 +36,7 @@ set(SOURCES src/gint/timer_callbacks.c src/gint/tlb.c src/gint/topti.c + src/gint/usb.c src/libs/justui.c src/libs/libimg.c src/libs/memory.c @@ -76,6 +79,7 @@ set(ASSETS_fx assets-fx/img/opt_gint_timer_callbacks.png assets-fx/img/opt_gint_timers.png assets-fx/img/opt_gint_tlb.png + assets-fx/img/opt_gint_usb.png assets-fx/img/opt_libs_jui.png assets-fx/img/opt_main.png assets-fx/img/opt_mem.png diff --git a/assets-fx/img/opt_gint_usb.png b/assets-fx/img/opt_gint_usb.png new file mode 100644 index 0000000000000000000000000000000000000000..63f43e48abd7782b75275ac1468ea0669237c566 GIT binary patch literal 4550 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 literal 0 HcmV?d00001 diff --git a/include/gintctl/assets.h b/include/gintctl/assets.h index 98466ab..7490967 100644 --- a/include/gintctl/assets.h +++ b/include/gintctl/assets.h @@ -34,6 +34,7 @@ extern bopti_image_t img_opt_gint_timer_callbacks, img_opt_gint_timers, img_opt_gint_tlb, + img_opt_gint_usb, img_opt_libs_jui, img_opt_main, img_opt_mem, diff --git a/include/gintctl/gint.h b/include/gintctl/gint.h index 99c80b1..9c4263f 100644 --- a/include/gintctl/gint.h +++ b/include/gintctl/gint.h @@ -47,6 +47,9 @@ void gintctl_gint_topti(void); /* gintctl_gint_kmalloc(): Dynamic memory allocator */ void gintctl_gint_kmalloc(void); +/* gintctl_gint_usb(): USB communication */ +void gintctl_gint_usb(void); + #ifdef FXCG50 /* gintctl_gint_dma(): Test the Direct Access Memory Controller */ diff --git a/include/gintctl/menu.h b/include/gintctl/menu.h index d9781c8..d4f85ab 100644 --- a/include/gintctl/menu.h +++ b/include/gintctl/menu.h @@ -25,11 +25,11 @@ enum { struct menu { char const *name; - int len; - int offset; - int pos; - int top; - int bottom; + int8_t len; + int8_t offset; + int8_t pos; + int8_t top; + int8_t bottom; struct menuentry entries[]; }; diff --git a/src/gint/usb.c b/src/gint/usb.c new file mode 100644 index 0000000..40b5acf --- /dev/null +++ b/src/gint/usb.c @@ -0,0 +1,329 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define USB SH7305_USB + +/* Copy of the context structure from the driver (edgy style but heck) */ +typedef struct +{ + uint16_t SYSCFG, DVSTCTR, TESTMODE, REG_C2; + uint16_t CFIFOSEL, D0FIFOSEL, D1FIFOSEL; + uint16_t INTENB0, BRDYENB, NRDYENB, BEMPENB, SOFCFG; + uint16_t DCPCFG, DCPMAXP, DCPCTR; + uint16_t PIPECFG[9], PIPEBUF[9], PIPEMAXP[9], PIPEPERI[9]; + uint16_t PIPEnCTR[9], PIPEnTRE[5], PIPEnTRN[5]; +} ctx_t; + +/* USB log buffer */ +#define LOG_SIZE _(1023, 16383) +static char log_buffer[LOG_SIZE+1]; +static int log_pos; +static int volatile log_interrupt = 0; + +static void reset_logger(void) +{ + memset(log_buffer, 0, LOG_SIZE+1); + log_pos = 0; +} + +static void usb_logger(char const *format, va_list args) +{ + if(log_pos >= LOG_SIZE) return; + int length = vsnprintf(log_buffer+log_pos, LOG_SIZE-log_pos, format, args); + log_pos = min(log_pos + length, LOG_SIZE); + /* Interrupt getkey() so that the log can be printed */ + log_interrupt = 1; +} + +static void save_logger(void) +{ + uint16_t const *file = u"\\\\fls0\\usb-log.txt"; + int size = log_pos; + + BFile_Remove(file); + BFile_Create(file, BFile_File, &size); + + int fd = BFile_Open(file, BFile_WriteOnly); + if(fd < 0) return; + + BFile_Write(fd, log_buffer, log_pos); + BFile_Close(fd); +} + +//--- +// Rendering functions +//--- + +static void val(int order, char const *name, uint32_t value,GUNUSED int scroll) +{ + #ifdef FX9860G + order -= 2 * scroll; + if(order < 0 || order > 15) return; + int y = 6 * (order / 2) + 8; + int x = 3 + 64 * (order % 2); + #endif + + #ifdef FXCG50 + int y = 12 * (order / 3) + 20; + int x = 6 + 128 * (order % 3); + #endif + + dprint(x, y, C_BLACK, "%s", name); + dprint(x+_(40,88), y, C_BLACK, "%04X", value); +} + +/* Automatically insert ".word" for most registers */ +#define reg(order, name, value) val(order, name, value.word) +/* Force casts to uint32_t for pointers */ +#define val(order, name, value) val(order, name, (uint32_t)value, scroll) + +static void draw_registers(GUNUSED int scroll) +{ + uint16_t volatile *MSELCRA = (void *)0xa4050180; + uint16_t volatile *MSELCRB = (void *)0xa4050182; + + reg( 0, "SYSCFG", USB.SYSCFG); + reg( 1, "BUSWAIT", USB.BUSWAIT); + reg( 2, "SYSSTS", USB.SYSSTS); + reg( 3, "DVSTCTR", USB.DVSTCTR); + reg( 4, "TESTMODE", USB.TESTMODE); + reg( 5, "CFIFOSEL", USB.CFIFOSEL); + reg( 6, "CFIFOCTR", USB.CFIFOCTR); + reg( 7, "D0FIFOSEL", USB.D0FIFOSEL); + reg( 8, "D0FIFOCTR", USB.D0FIFOCTR); + reg( 9, "D1FIFOSEL", USB.D1FIFOSEL); + reg(10, "D1FIFOCTR", USB.D1FIFOCTR); + reg(11, "INTENB0", USB.INTENB0); + reg(12, "BRDYENB", USB.BRDYENB); + reg(13, "NRDYENB", USB.NRDYENB); + reg(14, "BEMPENB", USB.BEMPENB); + reg(15, "SOFCFG", USB.SOFCFG); + reg(16, "INTSTS0", USB.INTSTS0); + reg(17, "BRDYSTS", USB.BRDYSTS); + reg(18, "NRDYSTS", USB.NRDYSTS); + reg(19, "BEMPSTS", USB.BEMPSTS); + reg(20, "FRMNUM", USB.FRMNUM); + reg(21, "UFRMNUM", USB.UFRMNUM); + reg(22, "USBADDR", USB.USBADDR); + reg(23, "USBREQ", USB.USBREQ); + reg(24, "USBVAL", USB.USBVAL); + reg(25, "USBINDX", USB.USBINDX); + reg(26, "USBLENG", USB.USBLENG); + reg(27, "DCPCFG", USB.DCPCFG); + reg(28, "DCPMAXP", USB.DCPMAXP); + reg(29, "DCPCTR", USB.DCPCTR); + reg(30, "PIPESEL", USB.PIPESEL); + reg(31, "PIPECFG", USB.PIPECFG); + reg(32, "PIPEBUF", USB.PIPEBUF); + reg(33, "PIPEMAXP", USB.PIPEMAXP); + reg(34, "PIPEPERI", USB.PIPEPERI); + reg(35, "PIPE1CTR", USB.PIPECTR[0]); + reg(36, "PIPE1TRE", USB.PIPE1TRE); + reg(37, "PIPE1TRN", USB.PIPE1TRN); + reg(38, "UPONCR", SH7305_USB_UPONCR); + val(39, "REG_C2", USB.REG_C2); + val(40, "MSELCRA", *MSELCRA); + val(41, "MSELCRB", *MSELCRB); + + #ifdef FX9860G + if(scroll >= 14) dprint(3, 50 - 6 * (scroll - 14), C_BLACK, + "USBCLKCR:%08X", SH7305_CPG.USBCLKCR.lword); + if(scroll >= 15) dprint(3, 50 - 6 * (scroll - 15), C_BLACK, + "MSTPCR2: %08X", SH7305_POWER.MSTPCR2.lword); + #endif + + #ifdef FXCG50 + dprint(row_x(1), 188, C_BLACK, "USBCLKCR: %08X MSTPCR2: %08X", + SH7305_CPG.USBCLKCR.lword, SH7305_POWER.MSTPCR2.lword); + #endif +} + +static void draw_context(void) +{ + extern void *driver_ctx(char const *name); + ctx_t *ctx = driver_ctx("USB"); + GUNUSED int scroll = 0; + + val( 0, "SYSCFG", ctx->SYSCFG); + val( 1, "DVSTCTR", ctx->DVSTCTR); + val( 2, "TESTMODE", ctx->TESTMODE); + val( 3, "REG_C2", ctx->REG_C2); + val( 4, "CFIFOSEL", ctx->CFIFOSEL); + val( 5, "D0FIFOSEL", ctx->D0FIFOSEL); + val( 6, "D1FIFOSEL", ctx->D1FIFOSEL); + val( 7, "INTENB0", ctx->INTENB0); + val( 8, "BRDYENB", ctx->BRDYENB); + val( 9, "NRDYENB", ctx->NRDYENB); + val(10, "BEMPENB", ctx->BEMPENB); + val(11, "SOFCFG", ctx->SOFCFG); + val(12, "DCPCFG", ctx->DCPCFG); + val(13, "DCPMAXP", ctx->DCPMAXP); + val(14, "DCPCTR", ctx->DCPCTR); + + // uint16_t PIPECFG[9], PIPEBUF[9], PIPEMAXP[9], PIPEPERI[9]; + // uint16_t PIPEnCTR[9], PIPEnTRE[5], PIPEnTRN[5]; +} + +static int draw_log(int offset) +{ + int const y0=_(8,20), dy=_(6,12), lines=_(8,15); + int const x=_(2,6), w=DWIDTH-_(9,15); + + /* Split log into lines */ + char const *log = log_buffer; + int y = y0 - offset*dy; + int line = 0; + + while(log < log_buffer + log_pos) + { + char const *endscreen = drsize(log, NULL, w, NULL); + char const *endline = strchrnul(log, '\n'); + int end = min(endscreen-log, endline-log); + + if(y >= y0 && y < y0 + lines * dy) + dtext_opt(x, y, C_BLACK, C_NONE, DTEXT_LEFT, DTEXT_TOP, log, end); + y += dy; + line++; + log += end + (log[end] == '\n'); + } + + if(line > lines) + { + scrollbar_px(y0, y0 + lines*dy, 0, line, offset, lines); + return line - lines; + } + + return 0; +} + +static void draw_pipes(void) +{ +#ifdef FXCG50 + char const *PID[4] = { "NAK", "BUF", "STALL0", "STALL1" }; + char const *BSTS[2] = { "Disabled", "Enabled" }; + char const *FRDY[2] = { "NotReady", "Ready" }; + char const *PBUSY[2] = { "Idle", "Busy" }; + + row_print(1, 1, "CFIFOSEL:"); + row_print(1, 11, "%04x", USB.CFIFOSEL.word); + row_print(1, 16, "CFIFOCTR:"); + row_print(1, 26, "%04x %s", USB.CFIFOCTR.word, + FRDY[USB.CFIFOCTR.FRDY]); + row_print(2, 1, "DCPCTR:"); + row_print(2, 11, "%04x %s %s %s %d", USB.DCPCTR.word, + BSTS[USB.DCPCTR.BSTS], PBUSY[USB.DCPCTR.PBUSY], PID[USB.DCPCTR.PID], + USB.DCPCTR.CCPL); + + row_print(3, 1, "D0FIFOCTR:"); + row_print(3, 11, "%04x", USB.D0FIFOCTR.word); + row_print(3, 16, "D0FIFOSEL:"); + row_print(3, 26, "%04x", USB.D0FIFOSEL.word); + + row_print(4, 1, "D1FIFOCTR:"); + row_print(4, 11, "%04x", USB.D1FIFOCTR.word); + row_print(4, 16, "D1FIFOSEL:"); + row_print(4, 26, "%04x", USB.D1FIFOSEL.word); + + for(int i = 0; i < 9; i++) + { + row_print(i+5, 1, "PIPE%dCTR:", i+1); + row_print(i+5, 10, "%04x", USB.PIPECTR[i].word); + } +#endif +} + +static void open_callback(void) +{ + usb_log("Open callback, doing test!\n"); + extern void usb_tests(void); + usb_tests(); +} + +/* gintctl_gint_usb(): USB communication */ +void gintctl_gint_usb(void) +{ + int key=0, tab=0; + bool open=false; + GUNUSED int scroll0=0, scroll2=0, maxscroll2=0; + + reset_logger(); + usb_set_log(usb_logger); + + while(key != KEY_EXIT) + { + dclear(C_WHITE); + + #ifdef FX9860G + row_title("USB 2.0 communication"); + dsubimage(0, 56, &img_opt_gint_usb, 0, open * 9, 128, 9, DIMAGE_NONE); + if(tab == 0) scrollbar_px(8, 52, 0, 22, scroll0, 8); + #endif + + font_t const *old_font = dfont(_(&font_mini, dfont_default())); + + if(tab == 0) draw_registers(scroll0); + if(tab == 1) draw_context(); + if(tab == 2) maxscroll2 = draw_log(scroll2); + if(tab == 3) draw_pipes(); + + #ifdef FXCG50 + row_title("USB 2.0 function module and communication"); + fkey_menu(1, "REGS"); + fkey_menu(2, "CTX"); + fkey_menu(3, "LOG"); + fkey_menu(4, "PIPES"); + if(tab == 2) fkey_button(5, "FILE"); + fkey_action(6, open ? "CLOSE" : "OPEN"); + #endif + +// dprint_opt(DWIDTH - 8, DHEIGHT - 6, C_BLACK, C_NONE, DTEXT_RIGHT, +// DTEXT_BOTTOM, "Interrupts: %d", usb_interrupt_count); + + dfont(old_font); + dupdate(); + + key = getkey_opt(GETKEY_DEFAULT, &log_interrupt).key; + log_interrupt = 0; + + if(key == KEY_F1) tab = 0; + if(key == KEY_F2) tab = 1; + if(key == KEY_F3) tab = 2; + if(key == KEY_F4) tab = 3; + + if(tab == 2 && key == KEY_F5) gint_switch(save_logger); + + if(key == KEY_F6) + { + if(open) usb_close(), open = false; + else + { + usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL }; + int rc = usb_open(interfaces, GINT_CB(open_callback)); + open = (rc == 0); + } + } + + #ifdef FX9860G + if(tab == 0 && key == KEY_UP && scroll0 > 0) scroll0--; + if(tab == 0 && key == KEY_DOWN && scroll0 < 15) scroll0++; + #endif + + if(tab == 2 && key == KEY_UP && scroll2 > 0) scroll2--; + if(tab == 2 && key == KEY_DOWN && scroll2 < maxscroll2) scroll2++; + } +} diff --git a/src/gintctl.c b/src/gintctl.c index 47eceeb..72b2e05 100644 --- a/src/gintctl.c +++ b/src/gintctl.c @@ -44,6 +44,7 @@ struct menu menu_gint = { { "DMA control", gintctl_gint_dma, 0 }, #endif { "Real-time clock", gintctl_gint_rtc, 0 }, + { "USB communication",gintctl_gint_usb, MENU_SH4_ONLY }, { "Image rendering", gintctl_gint_bopti, 0 }, { "Text rendering", gintctl_gint_topti, 0 }, #ifdef FX9860G