diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index 2f9f1097f..465f6419e 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -25,6 +25,7 @@ */ #include "tusb_option.h" +#include "common/tusb_fifo.h" #if CFG_TUSB_MCU == OPT_MCU_SAMG @@ -43,6 +44,7 @@ typedef struct { uint8_t* buffer; + tu_fifo_t* ff; uint16_t total_len; volatile uint16_t actual_len; uint16_t epsize; @@ -293,6 +295,38 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t return true; } +bool dcd_edpt_iso_xfer (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_desc_t* xfer = &_dcd_xfer[epnum]; + xfer->total_len = total_bytes; + xfer->actual_len = 0; + xfer->buffer = NULL; // Indicates a FIFO shall be used + xfer->ff = ff; + + if (dir == TUSB_DIR_OUT) + { + tu_fifo_set_copy_mode_read(ff, TU_FIFO_COPY_CST); + + // Enable interrupt when starting OUT transfer + if (epnum != 0) UDP->UDP_IER |= (1 << epnum); + } + else + { + tu_fifo_set_copy_mode_write(ff, TU_FIFO_COPY_CST); + tu_fifo_read_n(ff, (void *) &UDP->UDP_FDR[epnum], xfer_packet_len(xfer)); + + // TX ready for transfer + csr_set(epnum, UDP_CSR_TXPKTRDY_Msk); + } + + return true; +} + // Stall endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { @@ -402,7 +436,14 @@ void dcd_int_handler(uint8_t rhport) if (xact_len) { // write to EP fifo - xact_ep_write(epnum, xfer->buffer, xact_len); + if (xfer->buffer) + { + xact_ep_write(epnum, xfer->buffer, xact_len); + } + else + { + tu_fifo_read_n(ff, (void *) &UDP->UDP_FDR[epnum], xact_len); + } // TX ready for transfer csr_set(epnum, UDP_CSR_TXPKTRDY_Msk); @@ -428,7 +469,15 @@ void dcd_int_handler(uint8_t rhport) uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos); // Read from EP fifo - xact_ep_read(epnum, xfer->buffer, xact_len); + if (xfer->buffer) + { + xact_ep_read(epnum, xfer->buffer, xact_len); + } + else + { + tu_fifo_write_n(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len); + } + xfer_packet_done(xfer); if ( 0 == xfer_packet_len(xfer) )