summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasterPhi <[email protected]>2021-06-26 23:13:01 +0200
committerMasterPhi <[email protected]>2021-08-31 12:02:19 +0200
commit16b802d50cff6118952767b8fefa33dd0447ea91 (patch)
tree6650315fc00187854edf5dc598b52035f38e4bb8
parent864d8381a7acbd89053b6d478c064872b4871ed9 (diff)
add dcd_edpt_close and iso xfer.
-rw-r--r--src/portable/nxp/transdimension/dcd_transdimension.c75
1 files changed, 49 insertions, 26 deletions
diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c
index 156695fc4..a4d6c5d48 100644
--- a/src/portable/nxp/transdimension/dcd_transdimension.c
+++ b/src/portable/nxp/transdimension/dcd_transdimension.c
@@ -239,8 +239,9 @@ void dcd_init(uint8_t rhport)
dcd_reg->USBMODE = USBMODE_CM_DEVICE;
dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION;
- // TODO Force fullspeed on non-highspeed port
- // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED;
+#if !TUD_OPT_HIGH_SPEED
+ dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED;
+#endif
CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
@@ -329,22 +330,22 @@ static void qtd_init_fifo(dcd_qtd_t* p_qtd, tu_fifo_buffer_info_t *info, uint16_
if (len_lin != 0)
{
p_qtd->buffer[0] = (uint32_t) info->ptr_lin;
-
+
len_lin -= 4096 - ((uint32_t) info->ptr_lin - tu_align4k((uint32_t) info->ptr_lin));
-
+
// Set linear part
uint8_t i = 1;
for(; i<5; i++)
{
if (len_lin <= 0) break;
p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096;
- len_lin -= 4096;
+ len_lin -= 4096;
}
// Set wrapped part
for(uint8_t page = 0; i<5; i++, page++)
{
p_qtd->buffer[i] |= (uint32_t) info->ptr_wrap + 4096 * page;
- }
+ }
}
}
@@ -373,9 +374,6 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
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);
-
uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
uint8_t const ep_idx = 2*epnum + dir;
@@ -387,14 +385,25 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx];
tu_memclr(p_qhd, sizeof(dcd_qhd_t));
- p_qhd->zero_length_termination = 1;
p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size;
p_qhd->qtd_overlay.next = QTD_NEXT_INVALID;
+ if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
+ {
+ p_qhd->iso_mult = 1;
+ } else
+ {
+ p_qhd->zero_length_termination = 1;
+ }
+
CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
// Enable EP Control
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
+
+ // Clear EP type
+ dcd_reg->ENDPTCTRL[epnum] &=~(0x03 << (dir ? 18 : 2));
+
dcd_reg->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0);
return true;
@@ -406,6 +415,22 @@ void dcd_edpt_close_all (uint8_t rhport)
// TODO implement dcd_edpt_close_all()
}
+void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
+
+ // Flush EP
+ uint32_t flush_mask = TU_BIT(epnum) << (dir ? 16 : 0);
+ dcd_reg->ENDPTFLUSH = flush_mask;
+ while(dcd_reg->ENDPTFLUSH & flush_mask);
+
+ // Clear EP enable
+ dcd_reg->ENDPTCTRL[epnum] &=~(ENDPTCTRL_ENABLE << (dir ? 16 : 0));
+}
+
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
@@ -442,7 +467,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
}
// fifo has to be aligned to 4k boundary
-bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
uint8_t const epnum = tu_edpt_number(ep_addr);
@@ -460,34 +485,33 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx];
tu_fifo_buffer_info_t fifo_info;
-
- if(dir == TUSB_DIR_IN)
+
+ if (dir)
{
tu_fifo_get_read_info(ff, &fifo_info);
- }
- else
+ } else
{
tu_fifo_get_write_info(ff, &fifo_info);
}
-
+
if(total_bytes <= fifo_info.len_lin)
{
// Limit transfer length to total_bytes
fifo_info.len_wrap = 0;
fifo_info.len_lin = total_bytes;
- }
- else
+ } else
{
- // Class driver ensure at least total_bytes elements in fifo
+ // Class driver need to ensure at least total_bytes elements in fifo
fifo_info.len_wrap = total_bytes - fifo_info.len_lin;
}
// Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the
// address to 32-byte boundaries.
// void* cast to suppress cast-align warning, buffer must be
CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_lin, 4), fifo_info.len_lin + 31);
- if(fifo_info.len_wrap > 0)
+ if (fifo_info.len_wrap > 0)
+ {
CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_wrap, 4), fifo_info.len_wrap + 31);
-
+ }
//------------- Prepare qtd -------------//
qtd_init_fifo(p_qtd, &fifo_info, total_bytes);
p_qtd->int_on_complete = true;
@@ -576,20 +600,19 @@ void dcd_int_handler(uint8_t rhport)
( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 );
-
+
uint16_t xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes;
if (p_qhd->ff)
{
- if(tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
+ if (tu_edpt_dir(ep_addr))
{
tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes);
- }
- else
+ } else
{
tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes);
}
- }
+ }
dcd_event_xfer_complete(rhport, ep_addr, xferred_bytes, result, true); // only number of bytes in the IOC qtd
}
}