|
27 | 27 | #include "operacake_sctimer.h" |
28 | 28 |
|
29 | 29 | #include <libopencm3/cm3/vector.h> |
| 30 | +#include <libopencm3/lpc43xx/gpdma.h> |
30 | 31 | #include "usb_buffer.h" |
31 | 32 | #include "usb_api_m0_state.h" |
32 | 33 |
|
|
40 | 41 | #include "usb.h" |
41 | 42 | #include "usb_queue.h" |
42 | 43 | #include "platform_detect.h" |
| 44 | +#include "gpdma.h" |
43 | 45 |
|
44 | 46 | #include <stddef.h> |
45 | 47 | #include <string.h> |
|
50 | 52 | #define USB_TRANSFER_SIZE 0x4000 |
51 | 53 | #define DMA_TRANSFER_SIZE 0x2000 |
52 | 54 |
|
| 55 | +#define DMA_CHANNEL 1 |
| 56 | + |
53 | 57 | #define BUF_HALF_MASK (USB_SAMP_BUFFER_SIZE >> 1) |
54 | 58 |
|
55 | 59 | volatile uint32_t dma_started, dma_pending, usb_started, usb_completed; |
@@ -414,13 +418,39 @@ usb_request_status_t usb_vendor_request_set_rx_overrun_limit( |
414 | 418 |
|
415 | 419 | void transceiver_start_dma(void* src, void* dest, size_t size) |
416 | 420 | { |
| 421 | + uint32_t num_transfers = size >> 2; |
| 422 | + gpdma_controller_enable(); |
| 423 | + GPDMA_CSRCADDR(DMA_CHANNEL) = (uint32_t) src; |
| 424 | + GPDMA_CDESTADDR(DMA_CHANNEL) = (uint32_t) dest; |
| 425 | + GPDMA_CLLI(DMA_CHANNEL) = 0; |
| 426 | + GPDMA_CCONTROL(DMA_CHANNEL) = GPDMA_CCONTROL_TRANSFERSIZE(num_transfers) | |
| 427 | + GPDMA_CCONTROL_SBSIZE(7) // 256-transfer src bursts |
| 428 | + | GPDMA_CCONTROL_DBSIZE(7) // 256-transfer dst bursts |
| 429 | + | GPDMA_CCONTROL_SWIDTH(2) // 32-bit src transfers |
| 430 | + | GPDMA_CCONTROL_DWIDTH(2) // 32-bit dst transfers |
| 431 | + | GPDMA_CCONTROL_S(0) // AHB Master 0 |
| 432 | + | GPDMA_CCONTROL_D(1) // AHB Master 1 |
| 433 | + | GPDMA_CCONTROL_SI(1) // increment source |
| 434 | + | GPDMA_CCONTROL_DI(1) // increment destination |
| 435 | + | GPDMA_CCONTROL_PROT1(0) // user mode |
| 436 | + | GPDMA_CCONTROL_PROT2(0) // not bufferable |
| 437 | + | GPDMA_CCONTROL_PROT3(0) // not cacheable |
| 438 | + | GPDMA_CCONTROL_I(1); // interrupt enabled |
| 439 | + GPDMA_CCONFIG(DMA_CHANNEL) = GPDMA_CCONFIG_FLOWCNTRL(0) // memory-to-memory |
| 440 | + | GPDMA_CCONFIG_IE(0) // no error interrupt |
| 441 | + | GPDMA_CCONFIG_ITC(1) // terminal count interrupt |
| 442 | + | GPDMA_CCONFIG_L(0) // do not lock |
| 443 | + | GPDMA_CCONFIG_H(0); // do not halt |
| 444 | + GPDMA_INTTCCLEAR = (1 << DMA_CHANNEL); |
| 445 | + nvic_enable_irq(NVIC_DMA_IRQ); |
| 446 | + gpdma_channel_enable(DMA_CHANNEL); |
417 | 447 | dma_pending = size; |
418 | | - memcpy(dest, src, size); |
419 | | - dma_isr(); |
420 | 448 | } |
421 | 449 |
|
422 | 450 | void dma_isr(void) |
423 | 451 | { |
| 452 | + gpdma_channel_disable(DMA_CHANNEL); |
| 453 | + GPDMA_INTTCCLEAR = (1 << DMA_CHANNEL); |
424 | 454 | m0_state.m4_count += dma_pending; |
425 | 455 | dma_pending = 0; |
426 | 456 | } |
|
0 commit comments