Skip to content

Commit 94a7c35

Browse files
committed
Use DMA for transfers.
1 parent f66ad06 commit 94a7c35

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

firmware/hackrf_usb/usb_api_transceiver.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "operacake_sctimer.h"
2828

2929
#include <libopencm3/cm3/vector.h>
30+
#include <libopencm3/lpc43xx/gpdma.h>
3031
#include "usb_buffer.h"
3132
#include "usb_api_m0_state.h"
3233

@@ -40,6 +41,7 @@
4041
#include "usb.h"
4142
#include "usb_queue.h"
4243
#include "platform_detect.h"
44+
#include "gpdma.h"
4345

4446
#include <stddef.h>
4547
#include <string.h>
@@ -50,6 +52,8 @@
5052
#define USB_TRANSFER_SIZE 0x4000
5153
#define DMA_TRANSFER_SIZE 0x2000
5254

55+
#define DMA_CHANNEL 1
56+
5357
#define BUF_HALF_MASK (USB_SAMP_BUFFER_SIZE >> 1)
5458

5559
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(
414418

415419
void transceiver_start_dma(void* src, void* dest, size_t size)
416420
{
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);
417447
dma_pending = size;
418-
memcpy(dest, src, size);
419-
dma_isr();
420448
}
421449

422450
void dma_isr(void)
423451
{
452+
gpdma_channel_disable(DMA_CHANNEL);
453+
GPDMA_INTTCCLEAR = (1 << DMA_CHANNEL);
424454
m0_state.m4_count += dma_pending;
425455
dma_pending = 0;
426456
}

0 commit comments

Comments
 (0)