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
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>
5052#define USB_TRANSFER_SIZE 0x4000
5153#define DMA_TRANSFER_SIZE 0x2000
5254
55+ #define DMA_CHANNEL 1
56+
5357uint32_t dma_started , usb_started , usb_completed ;
58+ volatile bool dma_busy ;
5459
5560typedef struct {
5661 uint32_t freq_mhz ;
@@ -320,6 +325,7 @@ void transceiver_shutdown(void)
320325
321326void transceiver_startup (const transceiver_mode_t mode )
322327{
328+ dma_busy = false;
323329 dma_started = 0 ;
324330 usb_started = 0 ;
325331 usb_completed = 0 ;
@@ -409,15 +415,43 @@ usb_request_status_t usb_vendor_request_set_rx_overrun_limit(
409415 return USB_REQUEST_STATUS_OK ;
410416}
411417
412- void transceiver_start_dma (void * src , void * dest , size_t size , void ( * callback )( size_t ) )
418+ void transceiver_start_dma (void * src , void * dest , size_t size )
413419{
414- memcpy (dest , src , size );
415- callback (size );
420+ uint32_t num_transfers = size >> 2 ;
421+ gpdma_controller_enable ();
422+ GPDMA_CSRCADDR (DMA_CHANNEL ) = (uint32_t ) src ;
423+ GPDMA_CDESTADDR (DMA_CHANNEL ) = (uint32_t ) dest ;
424+ GPDMA_CLLI (DMA_CHANNEL ) = 0 ;
425+ GPDMA_CCONTROL (DMA_CHANNEL ) = GPDMA_CCONTROL_TRANSFERSIZE (num_transfers ) |
426+ GPDMA_CCONTROL_SBSIZE (7 ) // 256-transfer src bursts
427+ | GPDMA_CCONTROL_DBSIZE (7 ) // 256-transfer dst bursts
428+ | GPDMA_CCONTROL_SWIDTH (2 ) // 32-bit src transfers
429+ | GPDMA_CCONTROL_DWIDTH (2 ) // 32-bit dst transfers
430+ | GPDMA_CCONTROL_S (0 ) // AHB Master 0
431+ | GPDMA_CCONTROL_D (1 ) // AHB Master 1
432+ | GPDMA_CCONTROL_SI (1 ) // increment source
433+ | GPDMA_CCONTROL_DI (1 ) // increment destination
434+ | GPDMA_CCONTROL_PROT1 (0 ) // user mode
435+ | GPDMA_CCONTROL_PROT2 (0 ) // not bufferable
436+ | GPDMA_CCONTROL_PROT3 (0 ) // not cacheable
437+ | GPDMA_CCONTROL_I (1 ); // interrupt enabled
438+ GPDMA_CCONFIG (DMA_CHANNEL ) = GPDMA_CCONFIG_FLOWCNTRL (0 ) // memory-to-memory
439+ | GPDMA_CCONFIG_IE (0 ) // no error interrupt
440+ | GPDMA_CCONFIG_ITC (1 ) // terminal count interrupt
441+ | GPDMA_CCONFIG_L (0 ) // do not lock
442+ | GPDMA_CCONFIG_H (0 ); // do not halt
443+ GPDMA_INTTCCLEAR = (1 << DMA_CHANNEL );
444+ nvic_enable_irq (NVIC_DMA_IRQ );
445+ gpdma_channel_enable (DMA_CHANNEL );
446+ dma_busy = true;
416447}
417448
418- void transceiver_dma_transfer_complete ( size_t bytes_transferred )
449+ void dma_isr ( )
419450{
420- m0_state .m4_count += bytes_transferred ;
451+ gpdma_channel_disable (DMA_CHANNEL );
452+ GPDMA_INTTCCLEAR = (1 << DMA_CHANNEL );
453+ m0_state .m4_count += DMA_TRANSFER_SIZE ;
454+ dma_busy = false;
421455}
422456
423457void transceiver_bulk_transfer_complete (void * user_data , unsigned int bytes_transferred )
@@ -438,15 +472,14 @@ void rx_mode(uint32_t seq)
438472 uint32_t data_available = data_gathered - dma_started ;
439473 uint32_t space_in_use = usb_completed - dma_completed ;
440474 uint32_t space_available = USB_BULK_BUFFER_SIZE - space_in_use ;
441- if ((data_available >= DMA_TRANSFER_SIZE ) &&
475+ if (! dma_busy && (data_available >= DMA_TRANSFER_SIZE ) &&
442476 (space_available >= DMA_TRANSFER_SIZE )) {
443477 uint32_t samp_offset = dma_started & USB_SAMP_BUFFER_MASK ;
444478 uint32_t bulk_offset = dma_started & USB_BULK_BUFFER_MASK ;
445479 transceiver_start_dma (
446480 & usb_samp_buffer [samp_offset ],
447481 & usb_bulk_buffer [bulk_offset ],
448- DMA_TRANSFER_SIZE ,
449- transceiver_dma_transfer_complete );
482+ DMA_TRANSFER_SIZE );
450483 dma_started += DMA_TRANSFER_SIZE ;
451484 }
452485 if ((m0_state .m4_count - usb_started ) >= USB_TRANSFER_SIZE ) {
@@ -490,15 +523,14 @@ void tx_mode(uint32_t seq)
490523 uint32_t data_available = usb_completed - dma_started ;
491524 uint32_t space_in_use = dma_completed - data_used ;
492525 uint32_t space_available = USB_SAMP_BUFFER_SIZE - space_in_use ;
493- if ((data_available >= DMA_TRANSFER_SIZE ) &&
526+ if (! dma_busy && (data_available >= DMA_TRANSFER_SIZE ) &&
494527 (space_available >= DMA_TRANSFER_SIZE )) {
495528 uint32_t samp_offset = dma_started & USB_SAMP_BUFFER_MASK ;
496529 uint32_t bulk_offset = dma_started & USB_BULK_BUFFER_MASK ;
497530 transceiver_start_dma (
498531 & usb_bulk_buffer [bulk_offset ],
499532 & usb_samp_buffer [samp_offset ],
500- DMA_TRANSFER_SIZE ,
501- transceiver_dma_transfer_complete );
533+ DMA_TRANSFER_SIZE );
502534 dma_started += DMA_TRANSFER_SIZE ;
503535 }
504536 if ((usb_started - m0_state .m4_count ) <= USB_TRANSFER_SIZE ) {
0 commit comments