From c04bc07c2926ccc2d3404cd8ebb8c7aee69c04ee Mon Sep 17 00:00:00 2001 From: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Date: Wed, 15 Jan 2020 20:09:50 -0600 Subject: [PATCH] nuc121: enhanced driver and hopefully added readability --- src/portable/nuvoton/nuc121/dcd_nuc121.c | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 237a5fd9a..71211af0c 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -77,8 +77,11 @@ static bool active_ep0_xfer; /* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_in_xfer(), and the ISR */ static struct xfer_ctl_t { - uint8_t *data_ptr; /* collectively, data_ptr and remaining_bytes track progress of endpoint transfers */ - uint16_t remaining_bytes; + uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ + union { + uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ + uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ + }; uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ } xfer_table[PERIPH_MAX_EP]; @@ -139,7 +142,7 @@ static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) /* perform an IN endpoint transfer; this is called by dcd_edpt_xfer() and the ISR */ static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) { - uint16_t bytes_now = tu_min16(xfer->remaining_bytes, xfer->max_packet_size); + uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now); ep->MXPLD = bytes_now; @@ -263,16 +266,21 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to /* store away the information we'll needing now and later */ xfer->data_ptr = buffer; - xfer->remaining_bytes = total_bytes; + xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; /* for the first of one or more EP0_IN packets in a message, the first must be DATA1 */ if ( (0x80 == ep_addr) && !active_ep0_xfer ) ep->CFG |= USBD_CFG_DSQSYNC_Msk; if (TUSB_DIR_IN == dir) + { dcd_in_xfer(xfer, ep); + } else + { + xfer->out_bytes_so_far = 0; ep->MXPLD = xfer->max_packet_size; + } return true; } @@ -392,23 +400,23 @@ void USBD_IRQHandler(void) { /* copy the data from the PC to the previously provided buffer */ memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes); - xfer->remaining_bytes -= available_bytes; + xfer->out_bytes_so_far += available_bytes; xfer->data_ptr += available_bytes; /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ - if ( (0 == xfer->remaining_bytes) || (available_bytes < xfer->max_packet_size) ) - dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); - else if (xfer->remaining_bytes) + if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) + dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); + else ep->MXPLD = xfer->max_packet_size; } else { /* update the bookkeeping to reflect the data that has now been sent to the PC */ - xfer->remaining_bytes -= available_bytes; + xfer->in_remaining_bytes -= available_bytes; xfer->data_ptr += available_bytes; /* if more data to send, send it; otherwise, alert TinyUSB that we've finished */ - if (xfer->remaining_bytes) + if (xfer->in_remaining_bytes) dcd_in_xfer(xfer, ep); else dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true);