diff --git a/gc_bba_test/source/tests.c b/gc_bba_test/source/tests.c index 5e1f8bf..6e99cd9 100644 --- a/gc_bba_test/source/tests.c +++ b/gc_bba_test/source/tests.c @@ -343,20 +343,41 @@ static int t_rx(char *m, size_t n) static int t_dma(char *m, size_t n) { - u8 buf[64]; - u32 dlen; - if (bba_stream(SPRAM_BASE, buf, sizeof(buf)) < 0) { - snprintf(m, n, "stream read failed"); return 1; + u8 buf[64], rp[2], wp[2]; + u32 dlen, page, addr; + if (bba_read(REG_RRP_LO, rp, 2) < 0) { snprintf(m, n, "RRP read failed"); return 1; } + if (bba_read(REG_RWP_LO, wp, 2) < 0) { snprintf(m, n, "RWP read failed"); return 1; } + page = ((u32)rp[1] << 8) | rp[0]; + /* RWP/RRP are PAGE pointers into the 15-page ring, so the next + * unconsumed frame's descriptor is at RRP*256 -- NOT at SPRAM_BASE. + * Reading 0x100 unconditionally only happens to work while nothing has + * been consumed and the ring has not wrapped, which is why this test + * reported "ring empty?" on a board that had just passed the RX test. */ + if (rp[0] == wp[0] && rp[1] == wp[1]) { + snprintf(m, n, "ring empty: RRP==RWP==%u (send it a frame first)", + (unsigned)page); + return 2; + } + if (page < 1 || page > 15) { + snprintf(m, n, "RRP page %u outside ring pages 1-15", (unsigned)page); + return 1; + } + addr = page << 8; + if (bba_stream((u16)addr, buf, sizeof(buf)) < 0) { + snprintf(m, n, "stream read at 0x%04X failed", (unsigned)addr); + return 1; } /* 4-byte ring descriptor; its length field INCLUDES the descriptor. */ dlen = ((u32)buf[2] << 8) | buf[3]; if (dlen > 4 && dlen <= 1518) { - snprintf(m, n, "descriptor len 0x%04X = %u frame bytes, etype %02X%02X", - (unsigned)dlen, (unsigned)(dlen - 4), buf[16], buf[17]); + snprintf(m, n, "p%u len 0x%04X = %u bytes, etype %02X%02X", + (unsigned)page, (unsigned)dlen, (unsigned)(dlen - 4), + buf[16], buf[17]); return 0; } - snprintf(m, n, "descriptor len 0x%04X implausible (ring empty?)", (unsigned)dlen); - return 2; /* skip rather than fail: needs a received frame first */ + snprintf(m, n, "p%u len 0x%04X implausible (RWP=%u)", (unsigned)page, + (unsigned)dlen, (unsigned)(((u32)wp[1] << 8) | wp[0])); + return 1; } static int t_dma_stream_len(char *m, size_t n)