minor clean up

This commit is contained in:
hathach
2026-01-08 11:33:08 +07:00
parent f0a3d44834
commit 07416f704f
4 changed files with 77 additions and 82 deletions

View File

@ -71,18 +71,17 @@ TU_ATTR_ALWAYS_INLINE static inline hw_endpoint_t *hw_endpoint_get_by_addr(uint8
// main processing for dcd_edpt_iso_activate
static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
const uint8_t epnum = tu_edpt_number(ep_addr);
ep->ep_addr = ep_addr;
ep->next_pid = 0u;
ep->wMaxPacketSize = wMaxPacketSize;
ep->transfer_type = transfer_type;
// Clear existing buffer control state
io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep);
io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep);
*buf_ctrl_reg = 0;
// allocated hw buffer
const uint8_t epnum = tu_edpt_number(ep_addr);
if (epnum == 0) {
// Buffer offset is fixed (also double buffered)
ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0];
@ -104,16 +103,9 @@ static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPa
}
}
// Init, allocate buffer and enable endpoint
static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
const uint8_t epnum = tu_edpt_number(ep_addr);
const tusb_dir_t dir = tu_edpt_dir(ep_addr);
hw_endpoint_t *ep = hw_endpoint_get(epnum, dir);
hw_endpoint_init(ep, ep_addr, wMaxPacketSize, transfer_type);
// Set endpoint control register to enable (EP0 has no endpoint control register)
static void hw_endpoint_enable(hw_endpoint_t *ep, uint8_t transfer_type) {
io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep);
// Set endpoint control register to enable (EP0 has no endpoint control register)
if (ctrl_reg != NULL) {
const uint32_t ctrl_value =
EP_CTRL_ENABLE_BITS | ((uint32_t)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf);
@ -121,14 +113,24 @@ static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t
}
}
// Init and enable endpoint
static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
const uint8_t epnum = tu_edpt_number(ep_addr);
const tusb_dir_t dir = tu_edpt_dir(ep_addr);
hw_endpoint_t *ep = hw_endpoint_get(epnum, dir);
hw_endpoint_init(ep, ep_addr, wMaxPacketSize, transfer_type);
hw_endpoint_enable(ep, transfer_type);
}
static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) {
// Abort any pending transfer
// Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1).
// Which means we are not guaranteed to safely abort pending transfer on B0 and B1.
const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr);
const uint8_t epnum = tu_edpt_number(ep->ep_addr);
const uint8_t epnum = tu_edpt_number(ep->ep_addr);
const uint32_t abort_mask = TU_BIT((epnum << 1) | (dir ? 0 : 1));
// Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1).
// Which means we are not guaranteed to safely abort pending transfer on B0 and B1.
if (rp2040_chip_version() >= 2) {
usb_hw_set->abort = abort_mask;
while ((usb_hw->abort_done & abort_mask) != abort_mask) {}
@ -139,8 +141,8 @@ static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) {
buf_ctrl |= USB_BUF_CTRL_DATA1_PID;
}
io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep);
hwep_buf_ctrl_set(buf_ctrl_reg, buf_ctrl);
io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep);
hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl);
hw_endpoint_reset_transfer(ep);
if (rp2040_chip_version() >= 2) {
@ -265,15 +267,12 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) {
#if FORCE_VBUS_DETECT == 0
// Since we force VBUS detect On, device will always think it is connected and
// couldn't distinguish between disconnect and suspend
if (status & USB_INTS_DEV_CONN_DIS_BITS)
{
if (status & USB_INTS_DEV_CONN_DIS_BITS) {
handled |= USB_INTS_DEV_CONN_DIS_BITS;
if ( usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS )
{
if (usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS) {
// Connected: nothing to do
}else
{
} else {
// Disconnected
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true);
}
@ -295,8 +294,10 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) {
#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
// Only run enumeration workaround if pull up is enabled
if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) rp2040_usb_device_enumeration_fix();
#endif
if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) {
rp2040_usb_device_enumeration_fix();
}
#endif
}
/* Note from pico datasheet 4.1.2.6.4 (v1.2)
@ -458,7 +459,6 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* req
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) {
(void) rhport;
const uint8_t xfer_type = desc_edpt->bmAttributes.xfer;
TU_VERIFY(xfer_type != TUSB_XFER_ISOCHRONOUS);
hw_endpoint_open(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), xfer_type);
return true;
}
@ -485,13 +485,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc)
}
ep->wMaxPacketSize = ep_desc->wMaxPacketSize;
// Set control register to enable endpoint
io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep);
if (ctrl_reg != NULL) {
const uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | ((uint32_t)TUSB_XFER_ISOCHRONOUS << EP_CTRL_BUFFER_TYPE_LSB) |
hw_data_offset(ep->hw_data_buf);
*ctrl_reg = ctrl_value;
}
hw_endpoint_enable(ep, TUSB_XFER_ISOCHRONOUS);
return true;
}
@ -522,8 +516,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
}
// stall and clear current pending buffer, may need to use EP_ABORT
io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep);
hwep_buf_ctrl_set(buf_ctrl_reg, USB_BUF_CTRL_STALL);
io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep);
hwbuf_ctrl_set(buf_ctrl_reg, USB_BUF_CTRL_STALL);
}
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
@ -534,8 +528,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
// clear stall also reset toggle to DATA0, ready for next transfer
ep->next_pid = 0;
io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep);
hwep_buf_ctrl_clear_mask(buf_ctrl_reg, USB_BUF_CTRL_STALL);
io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep);
hwbuf_ctrl_clear_mask(buf_ctrl_reg, USB_BUF_CTRL_STALL);
}
}

View File

@ -62,22 +62,23 @@ enum {
USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS
};
static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr)
{
static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) {
uint8_t num = tu_edpt_number(ep_addr);
if ( num == 0 ) return &epx;
if (num == 0) {
return &epx;
}
for ( uint32_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++ )
{
for (uint32_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) {
struct hw_endpoint *ep = &ep_pool[i];
if ( ep->configured && (ep->dev_addr == dev_addr) && (ep->ep_addr == ep_addr) ) return ep;
if (ep->configured && (ep->dev_addr == dev_addr) && (ep->ep_addr == ep_addr)) {
return ep;
}
}
return NULL;
}
TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void)
{
TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void) {
return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB;
}
@ -98,8 +99,7 @@ static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_
hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true);
}
static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep)
{
static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep) {
usb_hw_clear->buf_status = bit;
// EP may have been stalled?
assert(ep->active);
@ -357,8 +357,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
// Finally, enable interrupt that endpoint
usb_hw_set->int_ep_ctrl = 1 << (ep->interrupt_num + 1);
// If it's an interrupt endpoint we need to set up the buffer control
// register
// If it's an interrupt endpoint we need to set up the buffer control register
}
}
@ -456,8 +455,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
// reset epx if it is currently active with unplugged device
if (epx.configured && epx.active && epx.dev_addr == dev_addr) {
epx.configured = false;
*hwep_ctrl_reg_host(&epx) = 0;
*hwep_buf_ctrl_reg_host(&epx) = 0;
*hwep_ctrl_reg_host(&epx) = 0;
*hwbuf_ctrl_reg_host(&epx) = 0;
hw_endpoint_reset_transfer(&epx);
}
@ -472,8 +471,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
// unconfigure the endpoint
ep->configured = false;
*hwep_ctrl_reg_host(ep) = 0;
*hwep_buf_ctrl_reg_host(ep) = 0;
*hwep_ctrl_reg_host(ep) = 0;
*hwbuf_ctrl_reg_host(ep) = 0;
hw_endpoint_reset_transfer(ep);
}
}

View File

@ -88,7 +88,7 @@ void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) {
ep->user_buf = 0;
}
void __tusb_irq_path_func(hwep_buf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask) {
void __tusb_irq_path_func(hwbuf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask) {
const bool is_host = rp2usb_is_host_mode();
uint32_t value = 0;
uint32_t buf_ctrl = *buf_ctrl_reg;
@ -101,7 +101,7 @@ void __tusb_irq_path_func(hwep_buf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t
value |= or_mask;
if (or_mask & USB_BUF_CTRL_AVAIL) {
if (buf_ctrl & USB_BUF_CTRL_AVAIL) {
panic("buf_ctrl @%lX already available", (uintptr_t)buf_ctrl_reg);
panic("buf_ctrl @ 0x%lX already available", (uintptr_t)buf_ctrl_reg);
}
*buf_ctrl_reg = value & ~USB_BUF_CTRL_AVAIL;
@ -162,15 +162,15 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep)
#if CFG_TUH_ENABLED
const bool is_host = rp2usb_is_host_mode();
if (is_host) {
buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep);
ep_ctrl_reg = hwep_ctrl_reg_host(ep);
is_rx = (dir == TUSB_DIR_IN);
buf_ctrl_reg = hwbuf_ctrl_reg_host(ep);
ep_ctrl_reg = hwep_ctrl_reg_host(ep);
is_rx = (dir == TUSB_DIR_IN);
} else
#endif
{
buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep);
ep_ctrl_reg = hwep_ctrl_reg_device(ep);
is_rx = (dir == TUSB_DIR_OUT);
buf_ctrl_reg = hwbuf_ctrl_reg_device(ep);
ep_ctrl_reg = hwep_ctrl_reg_device(ep);
is_rx = (dir == TUSB_DIR_OUT);
}
// always compute and start with buffer 0
@ -209,7 +209,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep)
// Finally, write to buffer_control which will trigger the transfer
// the next time the controller polls this dpram address
hwep_buf_ctrl_set(buf_ctrl_reg, buf_ctrl);
hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl);
}
void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) {
@ -287,13 +287,13 @@ static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) {
#if CFG_TUH_ENABLED
const bool is_host = rp2usb_is_host_mode();
if (is_host) {
buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep);
buf_ctrl_reg = hwbuf_ctrl_reg_host(ep);
ep_ctrl_reg = hwep_ctrl_reg_host(ep);
is_rx = (dir == TUSB_DIR_IN);
} else
#endif
{
buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep);
buf_ctrl_reg = hwbuf_ctrl_reg_device(ep);
ep_ctrl_reg = hwep_ctrl_reg_device(ep);
is_rx = (dir == TUSB_DIR_OUT);
}
@ -327,8 +327,8 @@ static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) {
ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER);
ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER;
io_rw_32 *buf_ctrl_reg = is_host ? hwep_buf_ctrl_reg_host(ep) : hwep_buf_ctrl_reg_device(ep);
hwep_buf_ctrl_set(buf_ctrl_reg, 0);
io_rw_32 *buf_ctrl_reg = is_host ? hwbuf_ctrl_reg_host(ep) : hwbuf_ctrl_reg_device(ep);
hwbuf_ctrl_set(buf_ctrl_reg, 0);
usb_hw->abort &= ~TU_BIT(ep_id);

View File

@ -1,10 +1,6 @@
#ifndef RP2040_COMMON_H_
#define RP2040_COMMON_H_
#if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE)
#error TinyUSB device and host mode not supported at the same time
#endif
#include "common/tusb_common.h"
#include "pico.h"
@ -13,6 +9,10 @@
#include "hardware/resets.h"
#include "hardware/timer.h"
#if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE)
#error TinyUSB device and host mode not supported at the same time
#endif
#if defined(PICO_RP2040_USB_DEVICE_ENUMERATION_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX)
#define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX
#endif
@ -36,6 +36,9 @@
#define __tusb_irq_path_func(x) x
#endif
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
#define usb_hw_set ((usb_hw_t *) hw_set_alias_untyped(usb_hw))
#define usb_hw_clear ((usb_hw_t *) hw_clear_alias_untyped(usb_hw))
@ -56,9 +59,9 @@ typedef struct hw_endpoint
uint16_t wMaxPacketSize;
uint8_t *hw_data_buf; // Buffer pointer in usb dpram
uint8_t *user_buf; // User buffer in main memory
// Current transfer information
uint8_t *user_buf; // User buffer in main memory
uint16_t remaining_len;
uint16_t xferred_len;
@ -108,7 +111,7 @@ TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_device(struct hw_end
return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_ctrl[epnum - 1].in : &usb_dpram->ep_ctrl[epnum - 1].out;
}
TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_device(struct hw_endpoint *ep) {
TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwbuf_ctrl_reg_device(struct hw_endpoint *ep) {
const uint8_t epnum = tu_edpt_number(ep->ep_addr);
const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr);
return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_buf_ctrl[epnum].in : &usb_dpram->ep_buf_ctrl[epnum].out;
@ -123,30 +126,29 @@ TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_host(struct hw_endpo
return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl;
}
TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_host(struct hw_endpoint *ep) {
if (ep->transfer_type == TUSB_XFER_CONTROL) {
TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwbuf_ctrl_reg_host(struct hw_endpoint *ep) {
if (tu_edpt_number(ep->ep_addr) == 0) {
return &usbh_dpram->epx_buf_ctrl;
}
return &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl;
}
#endif
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
void hwep_buf_ctrl_update(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask);
void hwbuf_ctrl_update(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask);
TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set(io_rw_32 *buf_ctrl_reg, uint32_t value) {
hwep_buf_ctrl_update(buf_ctrl_reg, 0, value);
TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_set(io_rw_32 *buf_ctrl_reg, uint32_t value) {
hwbuf_ctrl_update(buf_ctrl_reg, 0, value);
}
TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) {
hwep_buf_ctrl_update(buf_ctrl_reg, ~value, value);
TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_set_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) {
hwbuf_ctrl_update(buf_ctrl_reg, ~value, value);
}
TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_clear_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) {
hwep_buf_ctrl_update(buf_ctrl_reg, ~value, 0);
TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_clear_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) {
hwbuf_ctrl_update(buf_ctrl_reg, ~value, 0);
}
static inline uintptr_t hw_data_offset(uint8_t *buf) {