summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorhathach <[email protected]>2021-03-10 17:10:49 +0700
committerhathach <[email protected]>2021-03-10 17:10:49 +0700
commit794083b647d1e591fcdba441da56b6f7646ae573 (patch)
tree040c54a46afd2f347fc8a474b17d881de3280eb7 /src/portable
parentde1f36f2b02b00d8012748be304186e1eb78c728 (diff)
parentf9817da397d9e24801bb1b7e2b8ed0ddcef36d62 (diff)
Merge branch 'master' into edpt_ISO_xfer
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/raspberrypi/rp2040/dcd_rp2040.c103
-rw-r--r--src/portable/raspberrypi/rp2040/hcd_rp2040.c21
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.c40
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.h24
4 files changed, 126 insertions, 62 deletions
diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
index 95b0963a3..f844a0c65 100644
--- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
@@ -48,23 +48,24 @@
// Init these in dcd_init
static uint8_t *next_buffer_ptr;
-// Endpoints 0-15, direction 0 for out and 1 for in.
-static struct hw_endpoint hw_endpoints[16][2] = {0};
+// USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in.
+static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2] = {0};
-static inline struct hw_endpoint *hw_endpoint_get_by_num(uint8_t num, uint8_t in)
+static inline struct hw_endpoint *hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir)
{
- return &hw_endpoints[num][in];
+ return &hw_endpoints[num][dir];
}
static struct hw_endpoint *hw_endpoint_get_by_addr(uint8_t ep_addr)
{
uint8_t num = tu_edpt_number(ep_addr);
- uint8_t in = (ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0;
- return hw_endpoint_get_by_num(num, in);
+ tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ return hw_endpoint_get_by_num(num, dir);
}
+
static void _hw_endpoint_alloc(struct hw_endpoint *ep)
{
- uint size = TU_MIN(64, ep->wMaxPacketSize);
+ uint16_t size = tu_min16(64, ep->wMaxPacketSize);
// Assumes single buffered for now
ep->hw_data_buf = next_buffer_ptr;
@@ -99,15 +100,13 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep)
*ep->endpoint_control = reg;
}
-static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t ep_addr, uint wMaxPacketSize, uint8_t transfer_type)
+static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type)
{
- uint8_t num = tu_edpt_number(ep_addr);
- bool in = ep_addr & TUSB_DIR_IN_MASK;
+ const uint8_t num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
ep->ep_addr = ep_addr;
- ep->in = in;
// For device, IN is a tx transfer and OUT is an rx transfer
- ep->rx = in == false;
- ep->num = num;
+ ep->rx = (dir == TUSB_DIR_OUT);
// Response to a setup packet on EP0 starts with pid of 1
ep->next_pid = num == 0 ? 1u : 0u;
@@ -131,7 +130,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t ep_addr, uint wMax
ep->transfer_type = transfer_type;
// Every endpoint has a buffer control register in dpram
- if (ep->in)
+ if (dir == TUSB_DIR_IN)
{
ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in;
}
@@ -143,7 +142,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t ep_addr, uint wMax
// Clear existing buffer control state
*ep->buffer_control = 0;
- if (ep->num == 0)
+ if (num == 0)
{
// EP0 has no endpoint control register because
// the buffer offsets are fixed
@@ -155,7 +154,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t ep_addr, uint wMax
else
{
// Set the endpoint control register (starts at EP1, hence num-1)
- if (in)
+ if (dir == TUSB_DIR_IN)
{
ep->endpoint_control = &usb_dpram->ep_ctrl[num-1].in;
}
@@ -194,7 +193,7 @@ static void hw_endpoint_close(uint8_t ep_addr)
}
#endif
-static void hw_endpoint_init(uint8_t ep_addr, uint wMaxPacketSize, uint8_t bmAttributes)
+static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t bmAttributes)
{
struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr);
_hw_endpoint_init(ep, ep_addr, wMaxPacketSize, bmAttributes);
@@ -259,10 +258,10 @@ static void ep0_0len_status(void)
static void _hw_endpoint_stall(struct hw_endpoint *ep)
{
assert(!ep->stalled);
- if (ep->num == 0)
+ if (tu_edpt_number(ep->ep_addr) == 0)
{
// A stall on EP0 has to be armed so it can be cleared on the next setup packet
- usb_hw_set->ep_stall_arm = ep->in ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS;
+ usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS;
}
_hw_endpoint_buffer_control_set_mask32(ep, USB_BUF_CTRL_STALL);
ep->stalled = true;
@@ -276,10 +275,10 @@ static void hw_endpoint_stall(uint8_t ep_addr)
static void _hw_endpoint_clear_stall(struct hw_endpoint *ep)
{
- if (ep->num == 0)
+ if (tu_edpt_number(ep->ep_addr) == 0)
{
// Probably already been cleared but no harm
- usb_hw_clear->ep_stall_arm = ep->in ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS;
+ usb_hw_clear->ep_stall_arm = (tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS;
}
_hw_endpoint_buffer_control_clear_mask32(ep, USB_BUF_CTRL_STALL);
ep->stalled = false;
@@ -313,18 +312,67 @@ static void dcd_rp2040_irq(void)
hw_handle_buff_status();
}
+ // SE0 for 2 us or more, usually together with Bus Reset
+ 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 )
+ {
+ // Connected: nothing to do
+ }else
+ {
+ // Disconnected
+ dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true);
+ }
+
+ usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS;
+ }
+
+ // SE0 for 2.5 us or more
if (status & USB_INTS_BUS_RESET_BITS)
{
- pico_trace("BUS RESET (addr %d -> %d)\n", assigned_address, 0);
+ pico_trace("BUS RESET\n");
usb_hw->dev_addr_ctrl = 0;
handled |= USB_INTS_BUS_RESET_BITS;
- dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true);
+ dcd_event_bus_reset(0, TUSB_SPEED_FULL, true);
usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS;
+
#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
- rp2040_usb_device_enumeration_fix();
+ // Only run enumeration walk-around if pull up is enabled
+ if ( usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS )
+ {
+ rp2040_usb_device_enumeration_fix();
+ }
#endif
}
+#if 0
+ // TODO Enable SUSPEND & RESUME interrupt and test later on with/without VBUS detection
+
+ /* Note from pico datasheet 4.1.2.6.4 (v1.2)
+ * If you enable the suspend interrupt, it is likely you will see a suspend interrupt when
+ * the device is first connected but the bus is idle. The bus can be idle for a few ms before
+ * the host begins sending start of frame packets. You will also see a suspend interrupt
+ * when the device is disconnected if you do not have a VBUS detect circuit connected. This is
+ * because without VBUS detection, it is impossible to tell the difference between
+ * being disconnected and suspended.
+ */
+ if (status & USB_INTS_DEV_SUSPEND_BITS)
+ {
+ handled |= USB_INTS_DEV_SUSPEND_BITS;
+ dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
+ usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS;
+ }
+
+ if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS)
+ {
+ handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS;
+ dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
+ usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS;
+ }
+#endif
+
if (status ^ handled)
{
panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled));
@@ -365,8 +413,10 @@ void dcd_init (uint8_t rhport)
// Enable individual controller IRQS here. Processor interrupt enable will be used
// for the global interrupt enable...
+ // TODO Enable SUSPEND & RESUME interrupt
usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS;
- usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS;
+ usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS |
+ USB_INTS_DEV_CONN_DIS_BITS /* | USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS */ ;
dcd_connect(rhport);
}
@@ -394,8 +444,9 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
void dcd_remote_wakeup(uint8_t rhport)
{
- pico_info("dcd_remote_wakeup %d is not supported yet\n", rhport);
+ pico_info("dcd_remote_wakeup %d\n", rhport);
assert(rhport == 0);
+ usb_hw_set->sie_ctrl = USB_SIE_CTRL_RESUME_BITS;
}
// disconnect by disabling internal pull-up resistor on D+/D-
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index efb2bd430..224f6ef21 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -291,14 +291,16 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
assert(ep->buffer_control);
assert(ep->hw_data_buf);
- uint8_t num = tu_edpt_number(ep_addr);
+ uint8_t const num = tu_edpt_number(ep_addr);
+ tusb_dir_t const dir = tu_edpt_dir(ep_addr);
+
bool in = ep_addr & TUSB_DIR_IN_MASK;
ep->ep_addr = ep_addr;
ep->dev_addr = dev_addr;
- ep->in = in;
+
// For host, IN to host == RX, anything else rx == false
- ep->rx = in == true;
- ep->num = num;
+ ep->rx = (dir == TUSB_DIR_IN);
+
// Response to a setup packet on EP0 starts with pid of 1
ep->next_pid = num == 0 ? 1u : 0u;
ep->wMaxPacketSize = wMaxPacketSize;
@@ -327,9 +329,9 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
// device address
// endpoint number / direction
// preamble
- uint32_t reg = dev_addr | (ep->num << USB_ADDR_ENDP1_ENDPOINT_LSB);
+ uint32_t reg = dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB);
// Assert the interrupt endpoint is IN_TO_HOST
- assert(ep->in);
+ assert(dir == TUSB_DIR_IN);
if (need_pre(dev_addr))
{
@@ -363,9 +365,10 @@ static void hw_endpoint_init(uint8_t dev_addr, const tusb_desc_endpoint_t *ep_de
//--------------------------------------------------------------------+
// HCD API
//--------------------------------------------------------------------+
-bool hcd_init(void)
+bool hcd_init(uint8_t rhport)
{
- pico_trace("hcd_init\n");
+ pico_trace("hcd_init %d\n", rhport);
+ assert(rhport == 0);
// Reset any previous state
rp2040_usb_init();
@@ -461,7 +464,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
if (ep == &epx) {
// That has set up buffer control, endpoint control etc
// for host we have to initiate the transfer
- usb_hw->dev_addr_ctrl = dev_addr | ep->num << USB_ADDR_ENDP_ENDPOINT_LSB;
+ usb_hw->dev_addr_ctrl = dev_addr | (tu_edpt_number(ep_addr) << USB_ADDR_ENDP_ENDPOINT_LSB);
uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | sie_ctrl_base;
flags |= ep->rx ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS;
// Set pre if we are a low speed device on full speed hub
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c
index 339297ad6..98ffea9a3 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.c
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c
@@ -30,7 +30,6 @@
#include <stdlib.h>
#include "rp2040_usb.h"
-#include "hardware/clocks.h"
// Direction strings for debug
const char *ep_dir_string[] = {
@@ -44,10 +43,12 @@ static inline void _hw_endpoint_lock_update(struct hw_endpoint *ep, int delta) {
// sense to have worker and IRQ on same core, however I think using critsec is about equivalent.
}
+#if TUSB_OPT_HOST_ENABLED
static inline void _hw_endpoint_update_last_buf(struct hw_endpoint *ep)
{
ep->last_buf = ep->len + ep->transfer_size == ep->total_len;
}
+#endif
void rp2040_usb_init(void)
{
@@ -59,8 +60,11 @@ void rp2040_usb_init(void)
memset(usb_hw, 0, sizeof(*usb_hw));
memset(usb_dpram, 0, sizeof(*usb_dpram));
- // Mux to phy
+ // Mux the controller to the onboard usb phy
usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
+
+ // Force VBUS detect so the device thinks it is plugged into a host
+ // TODO support VBUs detect
usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
}
@@ -68,7 +72,9 @@ void hw_endpoint_reset_transfer(struct hw_endpoint *ep)
{
ep->stalled = false;
ep->active = false;
+#if TUSB_OPT_HOST_ENABLED
ep->sent_setup = false;
+#endif
ep->total_len = 0;
ep->len = 0;
ep->transfer_size = 0;
@@ -84,12 +90,12 @@ void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_m
value |= or_mask;
if (or_mask & USB_BUF_CTRL_AVAIL) {
if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) {
- panic("ep %d %s was already available", ep->num, ep_dir_string[ep->in]);
+ panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
}
*ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL;
// 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz)
// Don't need delay in host mode as host is in charge
-#ifndef RP2040_USB_HOST_MODE
+#if !TUSB_OPT_HOST_ENABLED
__asm volatile (
"b 1f\n"
"1: b 1f\n"
@@ -122,6 +128,7 @@ void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
val |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
ep->next_pid ^= 1u;
+#if TUSB_OPT_HOST_ENABLED
// Is this the last buffer? Only really matters for host mode. Will trigger
// the trans complete irq but also stop it polling. We only really care about
// trans complete for setup packets being sent
@@ -130,6 +137,7 @@ void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
pico_trace("Last buf (%d bytes left)\n", ep->transfer_size);
val |= USB_BUF_CTRL_LAST;
}
+#endif
// Finally, write to buffer_control which will trigger the transfer
// the next time the controller polls this dpram address
@@ -141,11 +149,11 @@ void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
void _hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len)
{
_hw_endpoint_lock_update(ep, 1);
- pico_trace("Start transfer of total len %d on ep %d %s\n", total_len, ep->num, ep_dir_string[ep->in]);
+ pico_trace("Start transfer of total len %d on ep %d %s\n", total_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
if (ep->active)
{
// TODO: Is this acceptable for interrupt packets?
- pico_warn("WARN: starting new transfer on already active ep %d %s\n", ep->num, ep_dir_string[ep->in]);
+ pico_warn("WARN: starting new transfer on already active ep %d %s\n", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
hw_endpoint_reset_transfer(ep);
}
@@ -153,12 +161,14 @@ void _hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t t
// Fill in info now that we're kicking off the hw
ep->total_len = total_len;
ep->len = 0;
- ep->transfer_size = tu_min32(total_len, ep->wMaxPacketSize);
+ ep->transfer_size = tu_min16(total_len, ep->wMaxPacketSize);
ep->active = true;
ep->user_buf = buffer;
+#if TUSB_OPT_HOST_ENABLED
// Recalculate if this is the last buffer
_hw_endpoint_update_last_buf(ep);
ep->buf_sel = 0;
+#endif
_hw_endpoint_start_next_buffer(ep);
_hw_endpoint_lock_update(ep, -1);
@@ -172,9 +182,9 @@ void _hw_endpoint_xfer_sync(struct hw_endpoint *ep)
// Get the buffer state and amount of bytes we have
// transferred
uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep);
- uint transferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK;
+ uint16_t transferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK;
-#ifdef RP2040_USB_HOST_MODE
+#if TUSB_OPT_HOST_ENABLED
// tag::host_buf_sel_fix[]
if (ep->buf_sel == 1)
{
@@ -223,16 +233,18 @@ bool _hw_endpoint_xfer_continue(struct hw_endpoint *ep)
// Part way through a transfer
if (!ep->active)
{
- panic("Can't continue xfer on inactive ep %d %s", ep->num, ep_dir_string);
+ panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string);
}
// Update EP struct from hardware state
_hw_endpoint_xfer_sync(ep);
// Now we have synced our state with the hardware. Is there more data to transfer?
- uint remaining_bytes = ep->total_len - ep->len;
- ep->transfer_size = tu_min32(remaining_bytes, ep->wMaxPacketSize);
+ uint16_t remaining_bytes = ep->total_len - ep->len;
+ ep->transfer_size = tu_min16(remaining_bytes, ep->wMaxPacketSize);
+#if TUSB_OPT_HOST_ENABLED
_hw_endpoint_update_last_buf(ep);
+#endif
// Can happen because of programmer error so check for it
if (ep->len > ep->total_len)
@@ -244,7 +256,7 @@ bool _hw_endpoint_xfer_continue(struct hw_endpoint *ep)
if (ep->len == ep->total_len)
{
pico_trace("Completed transfer of %d bytes on ep %d %s\n",
- ep->len, ep->num, ep_dir_string[ep->in]);
+ ep->len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
// Notify caller we are done so it can notify the tinyusb
// stack
_hw_endpoint_lock_update(ep, -1);
@@ -263,7 +275,7 @@ bool _hw_endpoint_xfer_continue(struct hw_endpoint *ep)
void _hw_endpoint_xfer(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len, bool start)
{
// Trace
- pico_trace("hw_endpoint_xfer ep %d %s", ep->num, ep_dir_string[ep->in]);
+ pico_trace("hw_endpoint_xfer ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
pico_trace(" total_len %d, start=%d\n", total_len, start);
assert(ep->configured);
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h
index 7c3234e8d..bb88d977f 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.h
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h
@@ -42,10 +42,6 @@ struct hw_endpoint
{
// Is this a valid struct
bool configured;
- // EP direction
- bool in;
- // EP num (not including direction)
- uint8_t num;
// Transfer direction (i.e. IN is rx for host but tx for device)
// allows us to common up transfer functions
@@ -67,28 +63,30 @@ struct hw_endpoint
// Current transfer information
bool active;
- uint total_len;
- uint len;
+ uint16_t total_len;
+ uint16_t len;
// Amount of data with the hardware
- uint transfer_size;
- // Only needed for host mode
- bool last_buf;
- // HOST BUG. Host will incorrect write status to top half of buffer
- // control register when doing transfers > 1 packet
- uint8_t buf_sel;
+ uint16_t transfer_size;
// User buffer in main memory
uint8_t *user_buf;
// Data needed from EP descriptor
- uint wMaxPacketSize;
+ uint16_t wMaxPacketSize;
// Interrupt, bulk, etc
uint8_t transfer_type;
+#if TUSB_OPT_HOST_ENABLED
+ // Only needed for host mode
+ bool last_buf;
+ // HOST BUG. Host will incorrect write status to top half of buffer
+ // control register when doing transfers > 1 packet
+ uint8_t buf_sel;
// Only needed for host
uint8_t dev_addr;
bool sent_setup;
// If interrupt endpoint
uint8_t interrupt_num;
+#endif
};
void rp2040_usb_init(void);