nuc121: enhanced driver and hopefully added readability
This commit is contained in:
		| @@ -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 */ | /* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_in_xfer(), and the ISR */ | ||||||
| static struct xfer_ctl_t | static struct xfer_ctl_t | ||||||
| { | { | ||||||
|   uint8_t *data_ptr;         /* collectively, data_ptr and remaining_bytes track progress of endpoint transfers */ |   uint8_t *data_ptr;         /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ | ||||||
|   uint16_t remaining_bytes; |   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 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) */ |   uint16_t total_bytes;      /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ | ||||||
| } xfer_table[PERIPH_MAX_EP]; | } 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  */ | /* 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) | 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); |   memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now); | ||||||
|   ep->MXPLD = 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 */ |   /* store away the information we'll needing now and later */ | ||||||
|   xfer->data_ptr = buffer; |   xfer->data_ptr = buffer; | ||||||
|   xfer->remaining_bytes = total_bytes; |   xfer->in_remaining_bytes = total_bytes; | ||||||
|   xfer->total_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 */ |   /* 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 ( (0x80 == ep_addr) && !active_ep0_xfer ) ep->CFG |= USBD_CFG_DSQSYNC_Msk; | ||||||
|  |  | ||||||
|   if (TUSB_DIR_IN == dir) |   if (TUSB_DIR_IN == dir) | ||||||
|  |   { | ||||||
|     dcd_in_xfer(xfer, ep); |     dcd_in_xfer(xfer, ep); | ||||||
|  |   } | ||||||
|   else |   else | ||||||
|  |   { | ||||||
|  |     xfer->out_bytes_so_far = 0; | ||||||
|     ep->MXPLD = xfer->max_packet_size; |     ep->MXPLD = xfer->max_packet_size; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| @@ -392,23 +400,23 @@ void USBD_IRQHandler(void) | |||||||
|         { |         { | ||||||
|           /* copy the data from the PC to the previously provided buffer */ |           /* copy the data from the PC to the previously provided buffer */ | ||||||
|           memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes); |           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; |           xfer->data_ptr += available_bytes; | ||||||
|  |  | ||||||
|           /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ |           /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ | ||||||
|           if ( (0 == xfer->remaining_bytes) || (available_bytes < xfer->max_packet_size) ) |           if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) | ||||||
|             dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); |             dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); | ||||||
|           else if (xfer->remaining_bytes) |           else | ||||||
|             ep->MXPLD = xfer->max_packet_size; |             ep->MXPLD = xfer->max_packet_size; | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|           /* update the bookkeeping to reflect the data that has now been sent to the PC */ |           /* 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; |           xfer->data_ptr += available_bytes; | ||||||
|  |  | ||||||
|           /* if more data to send, send it; otherwise, alert TinyUSB that we've finished */ |           /* 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); |             dcd_in_xfer(xfer, ep); | ||||||
|           else |           else | ||||||
|             dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); |             dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Peter Lawrence
					Peter Lawrence