From 16c13bc110fb0959e704b417706dd303afc69981 Mon Sep 17 00:00:00 2001 From: Skyler Mansfield Date: Sun, 17 Apr 2022 01:16:49 +0100 Subject: [PATCH 1/3] tusb_types: Added descriptive strings for edpt_dir and edpt_type --- src/common/tusb_types.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index e2fa17532..7eab396ef 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -513,6 +513,16 @@ static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); } +static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { + static const char *str[] = {"out", "in"}; + return str[dir]; +} + +static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { + static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; + return str[t]; +} + //--------------------------------------------------------------------+ // Descriptor helper //--------------------------------------------------------------------+ From 35668fc523c7c972bf91f32dbb3b50ad8b4f3c74 Mon Sep 17 00:00:00 2001 From: Skyler Mansfield Date: Sun, 17 Apr 2022 01:30:03 +0100 Subject: [PATCH 2/3] hcd_rp2040: Add bulk in/out+interrupt out support. Added support for allocating hw_endpoints for non-interrupt endpoints. Allow endpoints to be used in either direction by updating bit checks. --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 33 +++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 234bea203..0c7a5220d 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -139,16 +139,20 @@ static void hw_handle_buff_status(void) for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) { // EPX is bit 0 - // IEP1 is bit 2 - // IEP2 is bit 4 - // IEP3 is bit 6 + // IEP1 IN is bit 2 + // IEP1 OUT is bit 3 + // IEP2 IN is bit 4 + // IEP2 OUT is bit 5 + // IEP3 IN is bit 6 + // IEP3 OUT is bit 7 // etc - bit = 1 << (i*2); - - if (remaining_buffers & bit) - { - remaining_buffers &= ~bit; - _handle_buff_status_bit(bit, &ep_pool[i]); + for(int j = 0; j < 2; j++){ + bit = 1 << (i*2+j); + if (remaining_buffers & bit) + { + remaining_buffers &= ~bit; + _handle_buff_status_bit(bit, &ep_pool[i]); + } } } @@ -259,10 +263,10 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) { struct hw_endpoint *ep = NULL; - if (transfer_type == TUSB_XFER_INTERRUPT) + if (transfer_type != TUSB_XFER_CONTROL) { 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); 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; @@ -320,8 +324,9 @@ 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); ep->configured = true; - if (bmInterval) + if (ep != &epx) { + // Endpoint has its own addr_endp and interrupt bits to be setup! // This is an interrupt endpoint // so need to set up interrupt endpoint address control register with: // device address @@ -492,6 +497,9 @@ 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 struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); assert(ep); + // Should we maybe be able to check if endpt is busy/active instead? + if(ep->active) + return false; // Control endpoint can change direction 0x00 <-> 0x80 if ( ep_addr != ep->ep_addr ) @@ -535,6 +543,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet // Configure EP0 struct with setup info for the trans complete struct hw_endpoint *ep = _hw_endpoint_allocate(0); + assert(ep == &epx); // EP0 out _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); From d2c9b8bcfba42ebc0023154493383b8bcb892020 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Nov 2022 16:14:35 +0700 Subject: [PATCH 3/3] fix -wconversion-int and add minor comment --- src/common/tusb_types.h | 8 ++++++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index cfa24bd82..e11f08dd1 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -513,15 +513,19 @@ 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); } -static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { +#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]; } -static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { +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 diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 1125d30b6..10237d1f9 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -138,10 +138,10 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) _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++) { - // EPX is bit 0 + // EPX is bit 0 & 1 // IEP1 IN is bit 2 // IEP1 OUT is bit 3 // IEP2 IN is bit 4 @@ -149,7 +149,8 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) // IEP3 IN is bit 6 // IEP3 OUT is bit 7 // etc - for(int j = 0; j < 2; j++){ + for(uint j = 0; j < 2; j++) + { bit = 1 << (i*2+j); if (remaining_buffers & bit) { @@ -279,6 +280,8 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) 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(); pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); assert(ep); @@ -344,11 +347,10 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t if (ep != &epx) { // Endpoint has its own addr_endp and interrupt bits to be setup! - // This is an interrupt endpoint - // so need to set up interrupt endpoint address control register with: - // device address - // endpoint number / direction - // preamble + // This is an interrupt/async endpoint. so need to set up ADDR_ENDP register with: + // - device address + // - endpoint number / direction + // - preamble uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); if (dir == TUSB_DIR_OUT)