summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorhathach <[email protected]>2018-11-23 15:28:32 +0700
committerGitHub <[email protected]>2018-11-23 15:28:32 +0700
commita1c596490aa40863cd5f1e36a821157ffeab2af6 (patch)
treec8246e10d303414f222a5ba15480c04010240c8e /src/portable
parent2edfd5b555388d10a9013eb598c9a73a4ee1afa9 (diff)
parent394a22ecf7760cce630a8186260f1c79901af934 (diff)
Merge pull request #13 from hathach/devlocal
add unplugged event for nrf5x
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/microchip/samd21/dcd_samd21.c4
-rw-r--r--src/portable/microchip/samd51/dcd_samd51.c2
-rw-r--r--src/portable/nordic/nrf5x/dcd_nrf5x.c6
-rw-r--r--src/portable/nordic/nrf5x/hal_nrf5x.c3
-rw-r--r--src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c6
-rw-r--r--src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c2
-rw-r--r--src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c285
-rw-r--r--src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h9
8 files changed, 109 insertions, 208 deletions
diff --git a/src/portable/microchip/samd21/dcd_samd21.c b/src/portable/microchip/samd21/dcd_samd21.c
index b31db547d..c6101f312 100644
--- a/src/portable/microchip/samd21/dcd_samd21.c
+++ b/src/portable/microchip/samd21/dcd_samd21.c
@@ -275,7 +275,7 @@ void maybe_transfer_complete(void) {
total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT;
uint8_t ep_addr = epnum | TUSB_DIR_IN_MASK;
- dcd_event_xfer_complete(0, ep_addr, total_transfer_size, DCD_XFER_SUCCESS, true);
+ dcd_event_xfer_complete(0, ep_addr, total_transfer_size, XFER_RESULT_SUCCESS, true);
}
// Handle OUT completions
@@ -286,7 +286,7 @@ void maybe_transfer_complete(void) {
total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT;
uint8_t ep_addr = epnum;
- dcd_event_xfer_complete(0, ep_addr, total_transfer_size, DCD_XFER_SUCCESS, true);
+ dcd_event_xfer_complete(0, ep_addr, total_transfer_size, XFER_RESULT_SUCCESS, true);
}
// just finished status stage (total size = 0), prepare for next setup packet
diff --git a/src/portable/microchip/samd51/dcd_samd51.c b/src/portable/microchip/samd51/dcd_samd51.c
index 6fff12ba7..6e8053e59 100644
--- a/src/portable/microchip/samd51/dcd_samd51.c
+++ b/src/portable/microchip/samd51/dcd_samd51.c
@@ -304,7 +304,7 @@ void transfer_complete(uint8_t direction) {
if (direction == TUSB_DIR_IN) {
ep_addr |= TUSB_DIR_IN_MASK;
}
- dcd_event_xfer_complete(0, ep_addr, total_transfer_size, DCD_XFER_SUCCESS, true);
+ dcd_event_xfer_complete(0, ep_addr, total_transfer_size, XFER_RESULT_SUCCESS, true);
// just finished status stage (total size = 0), prepare for next setup packet
if (epnum == 0 && total_transfer_size == 0) {
diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c
index 816ff62ae..4fb88689c 100644
--- a/src/portable/nordic/nrf5x/dcd_nrf5x.c
+++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c
@@ -261,7 +261,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
edpt_dma_end();
// The nRF doesn't interrupt on status transmit so we queue up a success response.
- dcd_event_xfer_complete(0, ep_addr, 0, DCD_XFER_SUCCESS, false);
+ dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, false);
}
else if ( dir == TUSB_DIR_OUT )
{
@@ -459,7 +459,7 @@ void USBD_IRQHandler(void)
xfer->total_len = xfer->actual_len;
// BULK/INT OUT complete
- dcd_event_xfer_complete(0, epnum, xfer->actual_len, DCD_XFER_SUCCESS, true);
+ dcd_event_xfer_complete(0, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true);
}
}
@@ -494,7 +494,7 @@ void USBD_IRQHandler(void)
} else
{
// Bulk/Int IN complete
- dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, DCD_XFER_SUCCESS, true);
+ dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true);
}
}
}
diff --git a/src/portable/nordic/nrf5x/hal_nrf5x.c b/src/portable/nordic/nrf5x/hal_nrf5x.c
index 4ce512746..f40e904d7 100644
--- a/src/portable/nordic/nrf5x/hal_nrf5x.c
+++ b/src/portable/nordic/nrf5x/hal_nrf5x.c
@@ -61,6 +61,7 @@ enum {
#endif
#include "tusb_hal.h"
+#include "device/dcd.h"
/*------------------------------------------------------------------*/
/* MACRO TYPEDEF CONSTANT ENUM
@@ -291,6 +292,8 @@ void tusb_hal_nrf_power_event (uint32_t event)
nrf_usbd_disable();
hfclk_disable();
+
+ dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true);
}
break;
diff --git a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c
index 5c64cbb6b..4e514d6e2 100644
--- a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c
+++ b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c
@@ -141,11 +141,11 @@ typedef struct {
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-// CFG_TUSB_ATTR_USBRAM must have ATTR_ALIGNED(64) for lpc11u & lpc13u
+// CFG_TUSB_MEM_SECTION must have ATTR_ALIGNED(64) for lpc11u & lpc13u
#ifdef __ICCARM__
-ATTR_ALIGNED(256) CFG_TUSB_ATTR_USBRAM // for IAR the first ATTR_ALIGNED takes effect
+ATTR_ALIGNED(256) CFG_TUSB_MEM_SECTION // for IAR the first ATTR_ALIGNED takes effect
#else
-CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(256) // GCC & Keil the last ATTR_ALIGNED takes effect
+CFG_TUSB_MEM_SECTION ATTR_ALIGNED(256) // GCC & Keil the last ATTR_ALIGNED takes effect
#endif
STATIC_VAR dcd_11u_13u_data_t dcd_data;
diff --git a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c
index 850e257c6..ce8362546 100644
--- a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c
+++ b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c
@@ -68,7 +68,7 @@ typedef struct {
}dcd_data_t;
-CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(128) STATIC_VAR dcd_data_t dcd_data;
+CFG_TUSB_MEM_SECTION ATTR_ALIGNED(128) STATIC_VAR dcd_data_t dcd_data;
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
diff --git a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c
index 8d53759e6..2f83f4203 100644
--- a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c
+++ b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c
@@ -66,19 +66,30 @@ typedef struct {
dcd_qtd_t qtd[DCD_QTD_MAX] ATTR_ALIGNED(32);
}dcd_data_t;
-extern ATTR_WEAK dcd_data_t dcd_data0;
-extern ATTR_WEAK dcd_data_t dcd_data1;
-
#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE)
-CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(2048) STATIC_VAR dcd_data_t dcd_data0;
+CFG_TUSB_MEM_SECTION ATTR_ALIGNED(2048) static dcd_data_t dcd_data0;
#endif
#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
-CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(2048) STATIC_VAR dcd_data_t dcd_data1;
+CFG_TUSB_MEM_SECTION ATTR_ALIGNED(2048) static dcd_data_t dcd_data1;
#endif
static LPC_USB0_Type * const LPC_USB[2] = { LPC_USB0, ((LPC_USB0_Type*) LPC_USB1_BASE) };
-static dcd_data_t* const dcd_data_ptr[2] = { &dcd_data0, &dcd_data1 };
+
+static dcd_data_t* const dcd_data_ptr[2] =
+{
+#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE)
+ &dcd_data0,
+#else
+ NULL,
+#endif
+
+#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
+ &dcd_data1
+#else
+ NULL
+#endif
+};
//--------------------------------------------------------------------+
// CONTROLLER API
@@ -104,12 +115,11 @@ static void bus_reset(uint8_t rhport)
LPC_USB0_Type* const lpc_usb = LPC_USB[rhport];
// The reset value for all endpoint types is the control endpoint. If one endpoint
- //direction is enabled and the paired endpoint of opposite direction is disabled, then the
- //endpoint type of the unused direction must bechanged from the control type to any other
- //type (e.g. bulk). Leaving an unconfigured endpoint control will cause undefined behavior
- //for the data PID tracking on the active endpoint.
- lpc_usb->ENDPTCTRL1 = lpc_usb->ENDPTCTRL2 = lpc_usb->ENDPTCTRL3 =
- (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18);
+ // direction is enabled and the paired endpoint of opposite direction is disabled, then the
+ // endpoint type of the unused direction must bechanged from the control type to any other
+ // type (e.g. bulk). Leaving an unconfigured endpoint control will cause undefined behavior
+ // for the data PID tracking on the active endpoint.
+ lpc_usb->ENDPTCTRL1 = lpc_usb->ENDPTCTRL2 = lpc_usb->ENDPTCTRL3 = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18);
// USB1 only has 3 non-control endpoints
if ( rhport == 0)
@@ -165,41 +175,18 @@ bool dcd_init(uint8_t rhport)
}
//--------------------------------------------------------------------+
-// PIPE HELPER
+// HELPER
//--------------------------------------------------------------------+
-#if 0
-static inline uint8_t edpt_pos2phy(uint8_t pos)
-{ // 0-5 --> OUT, 16-21 IN
- return (pos < DCD_QHD_MAX/2) ? (2*pos) : (2*(pos-16)+1);
-}
-#endif
-
-static inline uint8_t edpt_phy2pos(uint8_t physical_endpoint)
+// index to bit position in register
+static inline uint8_t ep_idx2bit(uint8_t ep_idx)
{
- return physical_endpoint/2 + ( (physical_endpoint%2) ? 16 : 0);
-}
-
-static inline uint8_t edpt_addr2phy(uint8_t endpoint_addr)
-{
- return 2*(endpoint_addr & 0x0F) + ((endpoint_addr & TUSB_DIR_IN_MASK) ? 1 : 0);
-}
-
-static inline uint8_t edpt_phy2addr(uint8_t ep_idx)
-{
- return (ep_idx/2) | ( ep_idx & 0x01 ? TUSB_DIR_IN_MASK : 0 );
-}
-
-static inline uint8_t edpt_phy2log(uint8_t physical_endpoint)
-{
- return physical_endpoint/2;
+ return ep_idx/2 + ( (ep_idx%2) ? 16 : 0);
}
static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes)
{
tu_memclr(p_qtd, sizeof(dcd_qtd_t));
- p_qtd->used = 1;
-
p_qtd->next = QTD_NEXT_INVALID;
p_qtd->active = 1;
p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes;
@@ -214,81 +201,49 @@ static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes)
}
}
-// retval 0: invalid
-static inline uint8_t qtd_find_free(uint8_t rhport)
+static inline volatile uint32_t * get_endpt_ctrl_reg(uint8_t rhport, uint8_t ep_idx)
{
- // QTD0 is reserved for control transfer
- for(uint8_t i=1; i<DCD_QTD_MAX; i++)
- {
- if ( dcd_data_ptr[rhport]->qtd[i].used == 0) return i;
- }
-
- return 0;
+ return &(LPC_USB[rhport]->ENDPTCTRL0) + ep_idx/2;
}
//--------------------------------------------------------------------+
-// CONTROL PIPE API
+// DCD Endpoint Port
//--------------------------------------------------------------------+
-
-// control transfer does not need to use qtd find function
-// follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism
-bool dcd_control_xfer(uint8_t rhport, uint8_t dir, uint8_t * p_buffer, uint16_t length)
-{
- LPC_USB0_Type* const lpc_usb = LPC_USB[rhport];
- dcd_data_t* const p_dcd = dcd_data_ptr[rhport];
-
- uint8_t const ep_phy = (dir == TUSB_DIR_IN) ? 1 : 0;
-
- dcd_qhd_t* qhd = &p_dcd->qhd[ep_phy];
-
- // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
- while(lpc_usb->ENDPTSETUPSTAT & BIT_(0)) {}
-
- TU_VERIFY( !qhd->qtd_overlay.active );
-
- dcd_qtd_t* qtd = &p_dcd->qtd[0];
- qtd_init(qtd, p_buffer, length);
-
- // skip xfer complete for Status
- qtd->int_on_complete = (length > 0 ? 1 : 0);
-
- qhd->qtd_overlay.next = (uint32_t) qtd;
-
- lpc_usb->ENDPTPRIME = BIT_(edpt_phy2pos(ep_phy));
-
- return true;
-}
-
-//--------------------------------------------------------------------+
-// BULK/INTERRUPT/ISOCHRONOUS PIPE API
-//--------------------------------------------------------------------+
-static inline volatile uint32_t * get_reg_control_addr(uint8_t rhport, uint8_t physical_endpoint)
-{
- return &(LPC_USB[rhport]->ENDPTCTRL0) + edpt_phy2log(physical_endpoint);
-}
-
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
- uint8_t ep_idx = edpt_addr2phy(ep_addr);
- volatile uint32_t * reg_control = get_reg_control_addr(rhport, ep_idx);
+ uint8_t const epnum = edpt_number(ep_addr);
+ uint8_t const dir = edpt_dir(ep_addr);
+ uint8_t const ep_idx = 2*epnum + dir;
- if ( ep_addr == 0)
+ volatile uint32_t * endpt_ctrl = get_endpt_ctrl_reg(rhport, ep_idx);
+
+ if ( epnum == 0)
{
// Stall both Control IN and OUT
- (*reg_control) |= ( (ENDPTCTRL_MASK_STALL << 16) || (ENDPTCTRL_MASK_STALL << 0) );
+ (*endpt_ctrl) |= ( (ENDPTCTRL_MASK_STALL << 16) || (ENDPTCTRL_MASK_STALL << 0) );
}else
{
- (*reg_control) |= ENDPTCTRL_MASK_STALL << (ep_idx & 0x01 ? 16 : 0);
+ (*endpt_ctrl) |= ENDPTCTRL_MASK_STALL << (ep_idx & 0x01 ? 16 : 0);
}
}
+// TOOD implement later
+bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
+{
+ return false;
+}
+
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
- volatile uint32_t * reg_control = get_reg_control_addr(rhport, edpt_addr2phy(ep_addr));
+ uint8_t const epnum = edpt_number(ep_addr);
+ uint8_t const dir = edpt_dir(ep_addr);
+ uint8_t const ep_idx = 2*epnum + dir;
+
+ volatile uint32_t * endpt_ctrl = get_endpt_ctrl_reg(rhport, ep_idx);
// data toggle also need to be reset
- (*reg_control) |= ENDPTCTRL_MASK_TOGGLE_RESET << ((ep_addr & TUSB_DIR_IN_MASK) ? 16 : 0);
- (*reg_control) &= ~(ENDPTCTRL_MASK_STALL << ((ep_addr & TUSB_DIR_IN_MASK) ? 16 : 0));
+ (*endpt_ctrl) |= ENDPTCTRL_MASK_TOGGLE_RESET << ((ep_addr & TUSB_DIR_IN_MASK) ? 16 : 0);
+ (*endpt_ctrl) &= ~(ENDPTCTRL_MASK_STALL << ((ep_addr & TUSB_DIR_IN_MASK) ? 16 : 0));
}
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
@@ -297,12 +252,12 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
// TODO not support ISO yet
TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
- tusb_dir_t dir = (p_endpoint_desc->bEndpointAddress & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+ uint8_t const epnum = edpt_number(p_endpoint_desc->bEndpointAddress);
+ uint8_t const dir = edpt_dir(p_endpoint_desc->bEndpointAddress);
+ uint8_t const ep_idx = 2*epnum + dir;
//------------- Prepare Queue Head -------------//
- uint8_t ep_idx = edpt_addr2phy(p_endpoint_desc->bEndpointAddress);
dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx];
-
tu_memclr(p_qhd, sizeof(dcd_qhd_t));
p_qhd->zero_length_termination = 1;
@@ -310,105 +265,61 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
p_qhd->qtd_overlay.next = QTD_NEXT_INVALID;
//------------- Endpoint Control Register -------------//
- volatile uint32_t * reg_control = get_reg_control_addr(rhport, ep_idx);
+ volatile uint32_t * endpt_ctrl = get_endpt_ctrl_reg(rhport, ep_idx);
// endpoint must not be already enabled
- TU_VERIFY( !( (*reg_control) & (ENDPTCTRL_MASK_ENABLE << (dir ? 16 : 0)) ) );
+ TU_VERIFY( !( (*endpt_ctrl) & (ENDPTCTRL_MASK_ENABLE << (dir ? 16 : 0)) ) );
- (*reg_control) |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0);
+ (*endpt_ctrl) |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0);
return true;
}
bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
{
- uint8_t ep_idx = edpt_addr2phy(ep_addr);
+ uint8_t const epnum = edpt_number(ep_addr);
+ uint8_t const dir = edpt_dir(ep_addr);
+ uint8_t const ep_idx = 2*epnum + dir;
+
dcd_qhd_t const * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx];
+ dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx];
- return p_qhd->list_qtd_idx[0] != 0; // qtd list is not empty
+ return p_qtd->active;
// return !p_qhd->qtd_overlay.halted && p_qhd->qtd_overlay.active;
}
-// add only, controller virtually cannot know
-// TODO remove and merge to dcd_edpt_xfer
-static bool pipe_add_xfer(uint8_t rhport, uint8_t ed_idx, void * buffer, uint16_t total_bytes, bool int_on_complete)
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
{
- uint8_t qtd_idx = qtd_find_free(rhport);
- TU_ASSERT(qtd_idx != 0);
+ uint8_t const epnum = edpt_number(ep_addr);
+ uint8_t const dir = edpt_dir(ep_addr);
+ uint8_t const ep_idx = 2*epnum + dir;
- dcd_data_t* p_dcd = dcd_data_ptr[rhport];
- dcd_qhd_t * p_qhd = &p_dcd->qhd[ed_idx];
- dcd_qtd_t * p_qtd = &p_dcd->qtd[qtd_idx];
-
- //------------- Find free slot in qhd's array list -------------//
- uint8_t free_slot;
- for(free_slot=0; free_slot < DCD_QTD_PER_QHD_MAX; free_slot++)
+ if ( epnum == 0 )
{
- if ( p_qhd->list_qtd_idx[free_slot] == 0 ) break; // found free slot
+ // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism
+ // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
+ while(LPC_USB[rhport]->ENDPTSETUPSTAT & BIT_(0)) {}
}
- TU_ASSERT(free_slot < DCD_QTD_PER_QHD_MAX);
- p_qhd->list_qtd_idx[free_slot] = qtd_idx; // add new qtd to qhd's array list
+ dcd_data_t* p_dcd = dcd_data_ptr[rhport];
+ dcd_qhd_t * p_qhd = &p_dcd->qhd[ep_idx];
+ dcd_qtd_t * p_qtd = &p_dcd->qtd[ep_idx];
//------------- Prepare qtd -------------//
qtd_init(p_qtd, buffer, total_bytes);
- p_qtd->int_on_complete = int_on_complete;
+ p_qtd->int_on_complete = true;
+ p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd
- if ( free_slot > 0 ) p_dcd->qtd[ p_qhd->list_qtd_idx[free_slot-1] ].next = (uint32_t) p_qtd;
+ // start transfer
+ LPC_USB[rhport]->ENDPTPRIME = BIT_( ep_idx2bit(ep_idx) ) ;
return true;
}
-bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
-{
- uint8_t ep_idx = edpt_addr2phy(ep_addr);
-
- TU_VERIFY ( pipe_add_xfer(rhport, ep_idx, buffer, total_bytes, true) );
-
- dcd_qhd_t* p_qhd = &dcd_data_ptr[rhport]->qhd[ ep_idx ];
- dcd_qtd_t* p_qtd = &dcd_data_ptr[rhport]->qtd[ p_qhd->list_qtd_idx[0] ];
-
- p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // attach head QTD to QHD start transferring
-
- LPC_USB[rhport]->ENDPTPRIME = BIT_( edpt_phy2pos(ep_idx) ) ;
-
- return true;
-}
-
-//------------- Device Controller Driver's Interrupt Handler -------------//
-void xfer_complete_isr(uint8_t rhport, uint32_t reg_complete)
-{
- for(uint8_t ep_idx = 2; ep_idx < DCD_QHD_MAX; ep_idx++)
- {
- if ( BIT_TEST_(reg_complete, edpt_phy2pos(ep_idx)) )
- { // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set
- dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx];
-
- // retire all QTDs in array list, up to 1st still-active QTD
- while( p_qhd->list_qtd_idx[0] != 0 )
- {
- dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ p_qhd->list_qtd_idx[0] ];
-
- if (p_qtd->active) break; // stop immediately if found still-active QTD and shift array list
-
- //------------- Free QTD and shift array list -------------//
- p_qtd->used = 0; // free QTD
- memmove( (void*) p_qhd->list_qtd_idx, (void*) (p_qhd->list_qtd_idx+1), DCD_QTD_PER_QHD_MAX-1);
- p_qhd->list_qtd_idx[DCD_QTD_PER_QHD_MAX-1]=0;
-
- if (p_qtd->int_on_complete)
- {
- uint8_t result = p_qtd->halted ? DCD_XFER_STALLED :
- ( p_qtd->xact_err ||p_qtd->buffer_err ) ? DCD_XFER_FAILED : DCD_XFER_SUCCESS;
-
- uint8_t ep_addr = edpt_phy2addr(ep_idx);
- dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd
- }
- }
- }
- }
-}
+//--------------------------------------------------------------------+
+// ISR
+//--------------------------------------------------------------------+
void hal_dcd_isr(uint8_t rhport)
{
LPC_USB0_Type* const lpc_usb = LPC_USB[rhport];
@@ -457,9 +368,9 @@ void hal_dcd_isr(uint8_t rhport)
dcd_data_t* const p_dcd = dcd_data_ptr[rhport];
- //------------- Set up Received -------------//
if (lpc_usb->ENDPTSETUPSTAT)
{
+ //------------- Set up Received -------------//
// 23.10.10.2 Operational model for setup transfers
lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;// acknowledge
@@ -469,28 +380,23 @@ void hal_dcd_isr(uint8_t rhport)
dcd_event_handler(&event, true);
}
- //------------- Control Request Completed -------------//
- else if ( edpt_complete & ( BIT_(0) | BIT_(16)) )
+ if ( edpt_complete )
{
- // determine Control OUT or IN
- uint8_t ep_idx = BIT_TEST_(edpt_complete, 0) ? 0 : 1;
-
- // TODO use the actual QTD instead of the qhd's overlay to get expected bytes for actual byte xferred
- dcd_qtd_t* const p_qtd = (dcd_qtd_t*) p_dcd->qhd[ep_idx].qtd_addr;
-
- if ( p_qtd->int_on_complete )
+ for(uint8_t ep_idx = 0; ep_idx < DCD_QHD_MAX; ep_idx++)
{
- uint8_t result = p_qtd->halted ? DCD_XFER_STALLED :
- ( p_qtd->xact_err ||p_qtd->buffer_err ) ? DCD_XFER_FAILED : DCD_XFER_SUCCESS;
+ if ( BIT_TEST_(edpt_complete, ep_idx2bit(ep_idx)) )
+ {
+ // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set
+ dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx];
+ dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx];
- dcd_event_xfer_complete(rhport, 0, p_qtd->expected_bytes - p_qtd->total_bytes, result, true);
- }
- }
+ uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED :
+ ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
- //------------- Transfer Complete -------------//
- if ( edpt_complete & ~(BIT_(0) | BIT_(16)) )
- {
- xfer_complete_isr(rhport, edpt_complete);
+ uint8_t ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 );
+ dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd
+ }
+ }
}
}
@@ -504,7 +410,4 @@ void hal_dcd_isr(uint8_t rhport)
if (int_status & INT_MASK_ERROR) TU_ASSERT(false, );
}
-//--------------------------------------------------------------------+
-// HELPER
-//--------------------------------------------------------------------+
#endif
diff --git a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h
index 1476c0d30..85334a34d 100644
--- a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h
+++ b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h
@@ -54,7 +54,6 @@
//--------------------------------------------------------------------+
#define DCD_QHD_MAX 12
#define DCD_QTD_MAX 12
-#define DCD_QTD_PER_QHD_MAX 2 // maximum number of qtd that are linked into one queue head at a time
#define QTD_NEXT_INVALID 0x01
@@ -91,7 +90,6 @@ enum {
PORTSC_CURRENT_CONNECT_STATUS_MASK = BIT_(0),
PORTSC_FORCE_PORT_RESUME_MASK = BIT_(6),
PORTSC_SUSPEND_MASK = BIT_(7)
-
};
typedef struct
@@ -118,8 +116,7 @@ typedef struct
//------------- DCD Area -------------//
uint16_t expected_bytes;
- uint8_t used;
- uint8_t reserved;
+ uint8_t reserved[2];
} dcd_qtd_t;
TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct");
@@ -148,9 +145,7 @@ typedef struct
/// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes
/// thus there are 16 bytes padding free that we can make use of.
//--------------------------------------------------------------------+
- volatile uint8_t list_qtd_idx[DCD_QTD_PER_QHD_MAX];
-
- uint8_t reserved[16-DCD_QTD_PER_QHD_MAX];
+ uint8_t reserved[16];
} dcd_qhd_t;
TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct");