Merge pull request #1434 from Skyler84/rp2040-hcd-bulk

Rp2040 hcd bulk
This commit is contained in:
Ha Thach
2022-11-05 15:16:36 +07:00
committed by GitHub
2 changed files with 40 additions and 18 deletions

View File

@@ -513,6 +513,20 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpo
return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0);
} }
#if CFG_TUSB_DEBUG
TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir)
{
static const char *str[] = {"out", "in"};
return str[dir];
}
TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t)
{
static const char *str[] = {"control", "isochronous", "bulk", "interrupt"};
return str[t];
}
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Descriptor helper // Descriptor helper
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@@ -138,20 +138,25 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void)
_handle_buff_status_bit(bit, ep); _handle_buff_status_bit(bit, ep);
} }
// Check interrupt endpoints // Check "interrupt" (asynchronous) endpoints for both IN and OUT
for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++)
{ {
// EPX is bit 0 // EPX is bit 0 & 1
// IEP1 is bit 2 // IEP1 IN is bit 2
// IEP2 is bit 4 // IEP1 OUT is bit 3
// IEP3 is bit 6 // IEP2 IN is bit 4
// IEP2 OUT is bit 5
// IEP3 IN is bit 6
// IEP3 OUT is bit 7
// etc // etc
bit = 1 << (i*2); for(uint j = 0; j < 2; j++)
if (remaining_buffers & bit)
{ {
remaining_buffers &= ~bit; bit = 1 << (i*2+j);
_handle_buff_status_bit(bit, &ep_pool[i]); if (remaining_buffers & bit)
{
remaining_buffers &= ~bit;
_handle_buff_status_bit(bit, &ep_pool[i]);
}
} }
} }
@@ -273,10 +278,12 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type)
{ {
struct hw_endpoint *ep = NULL; struct hw_endpoint *ep = NULL;
if (transfer_type == TUSB_XFER_INTERRUPT) if (transfer_type != TUSB_XFER_CONTROL)
{ {
// Note: even though datasheet name these "Interrupt" endpoints. These are actually
// "Asynchronous" endpoints and can be used for other type such as: Bulk (ISO need confirmation)
ep = _next_free_interrupt_ep(); ep = _next_free_interrupt_ep();
pico_info("Allocate interrupt ep %d\n", ep->interrupt_num); pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num);
assert(ep); assert(ep);
ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl;
ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl;
@@ -337,13 +344,13 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg);
ep->configured = true; ep->configured = true;
if (bmInterval) if (ep != &epx)
{ {
// This is an interrupt endpoint // Endpoint has its own addr_endp and interrupt bits to be setup!
// so need to set up interrupt endpoint address control register with: // This is an interrupt/async endpoint. so need to set up ADDR_ENDP register with:
// device address // - device address
// endpoint number / direction // - endpoint number / direction
// preamble // - preamble
uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB));
if (dir == TUSB_DIR_OUT) if (dir == TUSB_DIR_OUT)
@@ -523,6 +530,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
// Get appropriate ep. Either EPX or interrupt endpoint // Get appropriate ep. Either EPX or interrupt endpoint
struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
TU_ASSERT(ep); TU_ASSERT(ep);
// EP should be inactive // EP should be inactive