30#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB && !CFG_TUH_MAX3421
44#define RHPORT_NATIVE 0
50#ifndef PICO_USB_HOST_INTERRUPT_ENDPOINTS
51#define PICO_USB_HOST_INTERRUPT_ENDPOINTS (USB_MAX_ENDPOINTS - 1)
53static_assert(PICO_USB_HOST_INTERRUPT_ENDPOINTS <= USB_MAX_ENDPOINTS,
"");
57#define epx (ep_pool[0])
61 SIE_CTRL_BASE = USB_SIE_CTRL_SOF_EN_BITS | USB_SIE_CTRL_KEEP_ALIVE_EN_BITS |
62 USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS
68 if ( num == 0 )
return &epx;
70 for ( uint32_t i = 1; i < TU_ARRAY_SIZE(
ep_pool); i++ )
79TU_ATTR_ALWAYS_INLINE
static inline uint8_t
dev_speed(
void)
81 return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB;
103 usb_hw_clear->buf_status = bit;
115 uint32_t remaining_buffers = usb_hw->buf_status;
116 pico_trace(
"buf_status 0x%08lx\n", remaining_buffers);
120 if ( remaining_buffers & bit )
122 remaining_buffers &= ~bit;
126 if ( ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS )
128 TU_LOG(3,
"Double Buffered: ");
132 TU_LOG(3,
"Single Buffered: ");
134 TU_LOG_HEX(3, ep_ctrl);
140 for ( uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++ )
150 for ( uint j = 0; j < 2; j++ )
152 bit = 1 << (i * 2 + j);
153 if ( remaining_buffers & bit )
155 remaining_buffers &= ~bit;
161 if ( remaining_buffers )
163 panic(
"Unhandled buffer %d\n", remaining_buffers);
169 if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS)
171 pico_trace(
"Sent setup packet\n");
187 uint32_t status = usb_hw->ints;
188 uint32_t handled = 0;
190 if ( status & USB_INTS_HOST_CONN_DIS_BITS )
192 handled |= USB_INTS_HOST_CONN_DIS_BITS;
204 usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS;
207 if ( status & USB_INTS_STALL_BITS )
213 pico_trace(
"Stall REC\n");
214 handled |= USB_INTS_STALL_BITS;
215 usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS;
219 if ( status & USB_INTS_BUFF_STATUS_BITS )
221 handled |= USB_INTS_BUFF_STATUS_BITS;
222 TU_LOG(2,
"Buffer complete\r\n");
226 if ( status & USB_INTS_TRANS_COMPLETE_BITS )
228 handled |= USB_INTS_TRANS_COMPLETE_BITS;
229 usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS;
230 TU_LOG(2,
"Transfer complete\r\n");
234 if ( status & USB_INTS_ERROR_RX_TIMEOUT_BITS )
236 handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS;
237 usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS;
240 if ( status & USB_INTS_ERROR_DATA_SEQ_BITS )
242 usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS;
243 TU_LOG(3,
" Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n",
246 panic(
"Data Seq Error \n");
249 if ( status ^ handled )
251 panic(
"Unhandled IRQ 0x%x\n", (uint) (status ^ handled));
264 for ( uint i = 1; i < TU_ARRAY_SIZE(
ep_pool); i++ )
324 ep->
next_pid = (num == 0 ? 1u : 0u);
332 assert(!(dpram_offset & 0b111111));
335 uint32_t ep_reg = EP_CTRL_ENABLE_BITS
336 | EP_CTRL_INTERRUPT_PER_BUFFER
341 ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB);
344 pico_trace(
"endpoint control (0x%p) <- 0x%lx\n", ep->
endpoint_control, ep_reg);
354 uint32_t reg = (uint32_t) (
dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB));
358 reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS;
363 reg |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS;
381 pico_trace(
"hcd_init %d\n", rhport);
388 usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
393 irq_add_shared_handler(USBCTRL_IRQ,
hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY);
399 usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS;
401 usb_hw->inte = USB_INTE_BUFF_STATUS_BITS |
402 USB_INTE_HOST_CONN_DIS_BITS |
403 USB_INTE_HOST_RESUME_BITS |
404 USB_INTE_STALL_BITS |
405 USB_INTE_TRANS_COMPLETE_BITS |
406 USB_INTE_ERROR_RX_TIMEOUT_BITS |
407 USB_INTE_ERROR_DATA_SEQ_BITS ;
416 reset_block(RESETS_RESET_USBCTRL_BITS);
417 unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
425 pico_trace(
"hcd_port_reset\n");
438 pico_trace(
"hcd_port_connect_status\n");
440 return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS;
456 panic(
"Invalid speed\n");
464 pico_trace(
"hcd_device_close %d\n",
dev_addr);
469 for (
size_t i = 1; i < TU_ARRAY_SIZE(
ep_pool); i++)
476 usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1));
477 usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0;
480 ep->configured =
false;
481 *ep->endpoint_control = 0;
482 *ep->buffer_control = 0;
491 return usb_hw->sof_rd;
498 irq_set_enabled(USBCTRL_IRQ,
true);
506 irq_set_enabled(USBCTRL_IRQ,
false);
537 pico_trace(
"hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n",
dev_addr,
ep_addr, buflen);
568 usb_hw->dev_addr_ctrl = (uint32_t) (
dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB));
570 uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS |
SIE_CTRL_BASE |
571 (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS) |
576 usb_hw->sie_ctrl = flags & ~USB_SIE_CTRL_START_TRANS_BITS;
577 busy_wait_at_least_cycles(12);
578 usb_hw->sie_ctrl = flags;
600 for ( uint8_t i = 0; i < 8; i++ )
602 usbh_dpram->setup_packet[i] = setup_packet[i];
623 uint32_t
const flags =
SIE_CTRL_BASE | USB_SIE_CTRL_SEND_SETUP_BITS | USB_SIE_CTRL_START_TRANS_BITS |
629 usb_hw->sie_ctrl = flags & ~USB_SIE_CTRL_START_TRANS_BITS;
630 busy_wait_at_least_cycles(12);
631 usb_hw->sie_ctrl = flags;
641 panic(
"hcd_clear_stall");
static TU_ATTR_ALWAYS_INLINE void hcd_event_device_remove(uint8_t rhport, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void hcd_event_device_attach(uint8_t rhport, bool in_isr)
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
static struct hw_endpoint * get_dev_ep(uint8_t dev_addr, uint8_t ep_addr)
void hcd_int_disable(uint8_t rhport)
void __tusb_irq_path_func() hcd_int_handler(uint8_t rhport, bool in_isr)
static struct hw_endpoint ep_pool[1+PICO_USB_HOST_INTERRUPT_ENDPOINTS]
static TU_ATTR_ALWAYS_INLINE uint8_t dev_speed(void)
static struct hw_endpoint * _next_free_interrupt_ep(void)
static void __tusb_irq_path_func() hw_trans_complete(void)
static struct hw_endpoint * _hw_endpoint_allocate(uint8_t transfer_type)
static void __tusb_irq_path_func() _handle_buff_status_bit(uint bit, struct hw_endpoint *ep)
static TU_ATTR_ALWAYS_INLINE bool need_pre(uint8_t dev_addr)
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
bool hcd_deinit(uint8_t rhport)
static void __tusb_irq_path_func() hw_handle_buff_status(void)
void hcd_int_enable(uint8_t rhport)
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen)
void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
void hcd_port_reset_end(uint8_t rhport)
void hcd_port_reset(uint8_t rhport)
bool hcd_port_connect_status(uint8_t rhport)
uint32_t hcd_frame_number(uint8_t rhport)
static void __tusb_irq_path_func() hcd_rp2040_irq(void)
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc)
static void __tusb_irq_path_func() hw_xfer_complete(struct hw_endpoint *ep, xfer_result_t xfer_result)
static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval)
void __tusb_irq_path_func() hw_endpoint_reset_transfer(struct hw_endpoint *ep)
void rp2040_usb_init(void)
bool __tusb_irq_path_func() hw_endpoint_xfer_continue(struct hw_endpoint *ep)
void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len)
static uintptr_t hw_data_offset(uint8_t *buf)
AUDIO Channel Cluster Descriptor (4.1)
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
io_rw_32 * endpoint_control
io_rw_32 * buffer_control
static TU_ATTR_ALWAYS_INLINE uint16_t tu_u32_low16(uint32_t ui32)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_u32_high16(uint32_t ui32)
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE const char * tu_edpt_type_str(tusb_xfer_type_t t)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
tusb_speed_t tuh_speed_get(uint8_t dev_addr)