29#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB
32#include "hardware/sync.h"
35#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
36#include "pico/fix/rp2040_usb_device_enumeration.h"
44#define FORCE_VBUS_DETECT 1
85 pico_info(
" Allocated %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->
hw_data_buf);
88 uint32_t
const reg = EP_CTRL_ENABLE_BITS | ((uint)
transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset;
103 bool reclaim_buffers =
true;
104 for (uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++) {
107 reclaim_buffers =
false;
111 if (reclaim_buffers) {
151 ep->
hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0];
171 uint32_t remaining_buffers = usb_hw->buf_status;
172 pico_trace(
"buf_status = 0x%08lx\r\n", remaining_buffers);
174 for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) {
175 if (remaining_buffers & bit) {
177 usb_hw_clear->buf_status = bit;
189 remaining_buffers &= ~bit;
195TU_ATTR_ALWAYS_INLINE
static inline void reset_ep0(
void) {
198 for (uint8_t dir = 0; dir < 2; dir++) {
204 uint32_t
const abort_mask = (dir ? USB_EP_ABORT_EP0_IN_BITS : USB_EP_ABORT_EP0_OUT_BITS);
205 if (rp2040_chip_version() >= 2) {
206 usb_hw_set->abort = abort_mask;
207 while ((usb_hw->abort_done & abort_mask) != abort_mask) {}
213 if (rp2040_chip_version() >= 2) {
214 usb_hw_clear->abort_done = abort_mask;
215 usb_hw_clear->abort = abort_mask;
224 for (uint8_t i = 0; i < USB_MAX_ENDPOINTS - 1; i++) {
225 usb_dpram->ep_ctrl[i].in = 0;
226 usb_dpram->ep_ctrl[i].out = 0;
237 uint32_t
const status = usb_hw->ints;
238 uint32_t handled = 0;
240 if (status & USB_INTF_DEV_SOF_BITS) {
241 bool keep_sof_alive =
false;
243 handled |= USB_INTF_DEV_SOF_BITS;
245#if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX
249 for (uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++) {
254 keep_sof_alive =
true;
270 if (!keep_sof_alive && !
_sof_enable) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS;
277 if (status & USB_INTS_BUFF_STATUS_BITS) {
278 handled |= USB_INTS_BUFF_STATUS_BITS;
282 if (status & USB_INTS_SETUP_REQ_BITS) {
283 handled |= USB_INTS_SETUP_REQ_BITS;
284 uint8_t
const* setup = remove_volatile_cast(uint8_t
const*, &usb_dpram->setup_packet);
291 usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS;
294#if FORCE_VBUS_DETECT == 0
297 if (status & USB_INTS_DEV_CONN_DIS_BITS)
299 handled |= USB_INTS_DEV_CONN_DIS_BITS;
301 if ( usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS )
310 usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS;
315 if (status & USB_INTS_BUS_RESET_BITS) {
316 pico_trace(
"BUS RESET\r\n");
318 handled |= USB_INTS_BUS_RESET_BITS;
320 usb_hw->dev_addr_ctrl = 0;
323 usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS;
325#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
327 if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) rp2040_usb_device_enumeration_fix();
339 if (status & USB_INTS_DEV_SUSPEND_BITS) {
340 handled |= USB_INTS_DEV_SUSPEND_BITS;
342 usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS;
345 if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) {
346 handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS;
348 usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS;
351 if (status ^ handled) {
352 panic(
"Unhandled IRQ 0x%x\n", (uint) (status ^ handled));
356#define USB_INTS_ERROR_BITS ( \
357 USB_INTS_ERROR_DATA_SEQ_BITS | \
358 USB_INTS_ERROR_BIT_STUFF_BITS | \
359 USB_INTS_ERROR_CRC_BITS | \
360 USB_INTS_ERROR_RX_OVERFLOW_BITS | \
361 USB_INTS_ERROR_RX_TIMEOUT_BITS)
368#ifndef PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY
369#define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
376 TU_LOG(2,
"Chip Version B%u\r\n", rp2040_chip_version());
383 usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
386 irq_add_shared_handler(USBCTRL_IRQ,
dcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY);
398 usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS;
403 usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS;
404 usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS |
405 USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS |
406 (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS);
419 reset_block(RESETS_RESET_USBCTRL_BITS);
420 unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
427 irq_set_enabled(USBCTRL_IRQ,
true);
432 irq_set_enabled(USBCTRL_IRQ,
false);
444 pico_info(
"dcd_remote_wakeup %d\n", rhport);
449 usb_hw_set->inte = USB_INTS_DEV_SOF_BITS;
450 usb_hw_set->sie_ctrl = USB_SIE_CTRL_RESUME_BITS;
456 usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
462 usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
471 usb_hw_set->inte = USB_INTS_DEV_SOF_BITS;
473#if !TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX
477 usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS;
521 : USB_EP_STALL_ARM_EP0_OUT_BITS;
545 pico_trace(
"dcd_edpt_close %02x\r\n",
ep_addr);
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_signal(uint8_t rhport, dcd_eventid_t eid, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
bool dcd_edpt_open(__unused uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
static void hw_endpoint_close(uint8_t ep_addr)
static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]
static uint8_t * next_buffer_ptr
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
void dcd_int_enable(__unused uint8_t rhport)
bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
static void __tusb_irq_path_func() hw_handle_buff_status(void)
static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type)
void dcd_edpt_close_all(uint8_t rhport)
static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
void dcd_remote_wakeup(__unused uint8_t rhport)
void dcd_int_disable(__unused uint8_t rhport)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
static TU_ATTR_ALWAYS_INLINE struct hw_endpoint * hw_endpoint_get_by_addr(uint8_t ep_addr)
void dcd_disconnect(__unused uint8_t rhport)
bool dcd_deinit(uint8_t rhport)
static void __tusb_irq_path_func() reset_non_control_endpoints(void)
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request)
void __tusb_irq_path_func() dcd_int_handler(uint8_t rhport)
void dcd_set_address(__unused uint8_t rhport, __unused uint8_t dev_addr)
static TU_ATTR_ALWAYS_INLINE void reset_ep0(void)
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type)
static void _hw_endpoint_close(struct hw_endpoint *ep)
static TU_ATTR_ALWAYS_INLINE struct hw_endpoint * hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir)
void dcd_connect(__unused uint8_t rhport)
static void __tusb_irq_path_func() dcd_rp2040_irq(void)
void dcd_sof_enable(uint8_t rhport, bool en)
void __tusb_irq_path_func() hw_endpoint_reset_transfer(struct hw_endpoint *ep)
void __tusb_irq_path_func() hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
volatile uint32_t e15_last_sof
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 TU_ATTR_ALWAYS_INLINE void _hw_endpoint_buffer_control_set_value32(struct hw_endpoint *ep, uint32_t value)
static uintptr_t hw_data_offset(uint8_t *buf)
static TU_ATTR_ALWAYS_INLINE void hw_endpoint_lock_update(__unused struct hw_endpoint *ep, __unused int delta)
static TU_ATTR_ALWAYS_INLINE void _hw_endpoint_buffer_control_clear_mask32(struct hw_endpoint *ep, uint32_t value)
AUDIO Channel Cluster Descriptor (4.1)
struct TU_ATTR_PACKED::@16::TU_ATTR_PACKED bmRequestType_bit
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
uint8_t bRequest
Request type audio_cs_req_t.
io_rw_32 * endpoint_control
io_rw_32 * buffer_control
static TU_ATTR_ALWAYS_INLINE uint32_t tu_div_ceil(uint32_t v, uint32_t d)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
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)
CFG_TUH_MEM_ALIGN tusb_control_request_t request