summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2013-12-09 11:49:34 +0700
committerhathach <[email protected]>2013-12-09 11:49:34 +0700
commit2af9ecbed5cae82c56ccfdb76460c3d998e4b61e (patch)
tree8236effac4aa67b6c91c161769fd602b99706d66
parent055285c55932af1396b92a31248f1df0ead25ffb (diff)
refractor dcd lpc43xx control xfer (with int on complete)
-rw-r--r--tinyusb/device/dcd_lpc43xx.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/tinyusb/device/dcd_lpc43xx.c b/tinyusb/device/dcd_lpc43xx.c
index 296a19a6c..8fa6db13d 100644
--- a/tinyusb/device/dcd_lpc43xx.c
+++ b/tinyusb/device/dcd_lpc43xx.c
@@ -351,20 +351,35 @@ void dcd_pipe_control_stall(uint8_t coreid)
}
// control transfer does not need to use qtd find function
-tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, void * buffer, uint16_t length)
+tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, void * p_buffer, uint16_t length, bool int_on_complete)
{
LPC_USB0_Type* const lpc_usb = LPC_USB[coreid];
- dcd_data_t* p_dcd = dcd_data_ptr[coreid];
+ dcd_data_t* const p_dcd = dcd_data_ptr[coreid];
+
+ // determine Endpoint where Data & Status phase occurred (IN or OUT)
+ uint8_t const ep_data = (dir == TUSB_DIR_DEV_TO_HOST) ? 1 : 0;
+ uint8_t const ep_status = 1 - ep_data;
- uint8_t const ep_id = dir; // IN : 1, OUT = 0
+ ASSERT_FALSE(p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active, TUSB_ERROR_FAILED);
- ASSERT_FALSE(p_dcd->qhd[ep_id].qtd_overlay.active, TUSB_ERROR_FAILED);
+ //------------- Data Phase -------------//
+ if (length)
+ {
+ dcd_qtd_t* p_qtd_data = &p_dcd->qtd[0];
+ qtd_init(p_qtd_data, p_buffer, length);
+ p_dcd->qhd[ep_data].qtd_overlay.next = (uint32_t) p_qtd_data;
- dcd_qtd_t* p_qtd = &p_dcd->qtd[ep_id];
- qtd_init(p_qtd, buffer, length);
- p_dcd->qhd[ep_id].qtd_overlay.next = (uint32_t) p_qtd;
+ lpc_usb->ENDPTPRIME = BIT_( edpt_phy2pos(ep_data) );
+ }
- lpc_usb->ENDPTPRIME = BIT_( edpt_phy2pos(ep_id) );
+ //------------- Status Phase -------------//
+ dcd_qtd_t* p_qtd_status = &p_dcd->qtd[1];
+ qtd_init(p_qtd_status, NULL, 0); // zero length xfer
+ p_qtd_status->int_on_complete = int_on_complete ? 1 : 0;
+
+ p_dcd->qhd[ep_status].qtd_overlay.next = (uint32_t) p_qtd_status;
+
+ LPC_USB0->ENDPTPRIME |= BIT_( edpt_phy2pos(ep_status) );
return TUSB_ERROR_NONE;
}
@@ -565,32 +580,47 @@ void dcd_isr(uint8_t coreid)
if (int_status & INT_MASK_USB)
{
+ uint32_t const edpt_complete = lpc_usb->ENDPTCOMPLETE;
+ lpc_usb->ENDPTCOMPLETE = edpt_complete; // acknowledge
+
+ dcd_data_t* const p_dcd = dcd_data_ptr[coreid];
+
//------------- Set up Received -------------//
if (lpc_usb->ENDPTSETUPSTAT)
{ // 23.10.10.2 Operational model for setup transfers
- dcd_data_t* p_dcd = dcd_data_ptr[coreid];
tusb_control_request_t control_request = p_dcd->qhd[0].setup_request;
lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;
//------------- Flush if previous transfer is not done -------------//
- if (p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active)
- {
- do
- {
- lpc_usb->ENDPTFLUSH = BIT_(0) | BIT_(16);
- while(lpc_usb->ENDPTFLUSH) {} // TODO refractor later
- }while( lpc_usb->ENDPTSTAT & (BIT_(0) | BIT_(16)) );
-
- p_dcd->qhd[0].qtd_overlay.active = p_dcd->qhd[1].qtd_overlay.active = 0;
- }
+// if (p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active)
+// {
+// do
+// {
+// lpc_usb->ENDPTFLUSH = BIT_(0) | BIT_(16);
+// while(lpc_usb->ENDPTFLUSH) {} // TODO refractor later
+// }while( lpc_usb->ENDPTSTAT & (BIT_(0) | BIT_(16)) );
+//
+// p_dcd->qhd[0].qtd_overlay.active = p_dcd->qhd[1].qtd_overlay.active = 0;
+// }
usbd_setup_received_isr(coreid, &control_request);
+ }else if ( edpt_complete & 0x03 )
+ { // only either of Endpoint Control is set with interrupt on complete flag
+ endpoint_handle_t edpt_hdl =
+ {
+ .coreid = coreid,
+ .index = 0,
+ .class_code = 0
+ };
+
+ dcd_qtd_t * const p_qtd = &p_dcd->qhd[ (edpt_complete & BIT_(0)) ? 0 : 1 ].qtd_overlay;
+ tusb_event_t event = ( p_qtd->xact_err || p_qtd->halted || p_qtd->buffer_err ) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_COMPLETE;
+
+ usbd_xfer_isr(edpt_hdl, event, 0); // TODO xferred bytes for control xfer is not needed yet !!!!
}
//------------- Transfer Complete -------------//
- uint32_t edpt_complete = lpc_usb->ENDPTCOMPLETE;
- lpc_usb->ENDPTCOMPLETE = edpt_complete; // acknowledge
if (edpt_complete)
{