From 31dcc6fd6c30255c22c6f0f99ab09df86e7de2d2 Mon Sep 17 00:00:00 2001 From: Lephe Date: Fri, 7 May 2021 17:41:36 +0200 Subject: [PATCH] usb: enable writing with DMA Nothing particular to change, simply make sure that the DMA channels have higher priority than the USB module, otherwise the BEMP interrupt might be executed before the DMA frees the channel, resulting in the transfer failing because the channel is still busy. Also reduce BUSWAIT since it works even on high overclock levels, and keeping it high won't help increase performance. --- src/dma/dma.c | 8 ++++---- src/usb/pipes.c | 6 ++---- src/usb/usb.c | 6 +++--- src/usb/usb_private.h | 1 + 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/dma/dma.c b/src/dma/dma.c index 141b05b..391a254 100644 --- a/src/dma/dma.c +++ b/src/dma/dma.c @@ -242,13 +242,13 @@ static void configure(void) extern void inth_dma_ae(void); intc_handler(0xbc0, inth_dma_ae, 32); - /* Set interrupt priority to 3 (IPRE[15..12] for first three channels, - IPRF[11..8] for last two and error gate */ + /* Set interrupt priority to 3, except 11 for the channels that are + used by the USB driver */ intc_priority(INTC_DMA_DEI0, 3); intc_priority(INTC_DMA_DEI1, 3); intc_priority(INTC_DMA_DEI2, 3); - intc_priority(INTC_DMA_DEI3, 3); - intc_priority(INTC_DMA_DEI4, 3); + intc_priority(INTC_DMA_DEI3, 9); + intc_priority(INTC_DMA_DEI4, 9); intc_priority(INTC_DMA_DEI5, 3); intc_priority(INTC_DMA_DADERR, 3); diff --git a/src/usb/pipes.c b/src/usb/pipes.c index 37de6f4..26e32fe 100644 --- a/src/usb/pipes.c +++ b/src/usb/pipes.c @@ -234,8 +234,6 @@ static void finish_round(struct transfer volatile *t, int pipe) t->size -= t->flying; t->flying = 0; - if(pipe) usb_log("%d left\n", t->size); - /* Account for auto-transfers */ if(t->used == pipe_bufsize(pipe)) t->used = 0; @@ -293,9 +291,9 @@ static void write_round(struct transfer volatile *t, int pipe) /* Use DMA channel 3 for D0F and 4 for D1F */ int channel = (ct == D0F) ? 3 : 4; - int rc = dma_transfer_async(channel, block_size, size, + bool ok = dma_transfer_async(channel, block_size, size, t->data, DMA_INC, (void *)FIFO, DMA_FIXED, callback); - usb_log("dma_transfer_async: %d, bs=%d, size=%d, fifo=%d\n", rc, block_size, size, ct); + if(!ok) usb_log("DMA async failed on channel %d!\n", channel); } else { diff --git a/src/usb/usb.c b/src/usb/usb.c index 6a53efc..119930d 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -85,8 +85,8 @@ static void hpoweron_write(void) USB.SYSCFG.SCKE = 1; for(int i = 0; i < 10; i++) __asm__ volatile("nop"); - /* Set BUSWAIT to a safe value, hopefully avoiding overlock problems */ - USB.BUSWAIT.word = 15; + /* Set BUSWAIT to a safe value */ + USB.BUSWAIT.word = 5; } static void hpoweroff(void) @@ -170,7 +170,7 @@ int usb_open(usb_interface_t const **interfaces, gint_call_t callback) USB.BEMPENB.word = 0x0000; intc_handler_function(0xa20, GINT_CALL(usb_interrupt_handler)); - intc_priority(INTC_USB, 15); + intc_priority(INTC_USB, 8); return 0; } diff --git a/src/usb/usb_private.h b/src/usb/usb_private.h index 4590fa1..9b8027a 100644 --- a/src/usb/usb_private.h +++ b/src/usb/usb_private.h @@ -8,6 +8,7 @@ #include #include #include +#include //--- // Configuration of the communication surface between module and host