summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYixingShen <[email protected]>2026-03-09 22:20:11 +0800
committerYixingShen <[email protected]>2026-03-09 22:20:11 +0800
commit7ca457cc3d244aac813c274a6e9ed80f9a70e68a (patch)
treeb1465c97091555720d2350bd4ef9f56573a4d40f /src
parentce305af6534e098ee98ab2d8bc2229e2300dc2f0 (diff)
parente98d32a304a92418572f5fd65908beeab2183556 (diff)
Merge branch 'master' of https://github.com/YixingShen/tinyusb
Diffstat (limited to 'src')
-rw-r--r--src/common/tusb_fifo.c4
-rw-r--r--src/common/tusb_private.h3
-rw-r--r--src/common/tusb_types.h2
-rw-r--r--src/host/usbh.c116
-rw-r--r--src/portable/chipidea/ci_hs/dcd_ci_hs.c2
-rw-r--r--src/tusb.c3
6 files changed, 61 insertions, 69 deletions
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index 8bd79e56d..991ee18ff 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -280,7 +280,7 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin
const uint32_t odd_mask = data_stride - 1;
uint16_t lin_even = lin_bytes & ~odd_mask;
tu_hwfifo_read(hwfifo, ff_buf, lin_even, access_mode);
- HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_even);
+ HWFIFO_ADDR_NEXT_N(hwfifo, const, (lin_even / data_stride) * CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE);
ff_buf += lin_even;
// There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
@@ -337,7 +337,7 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t
const uint32_t odd_mask = data_stride - 1;
uint16_t lin_even = lin_bytes & ~odd_mask;
tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode);
- HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even);
+ HWFIFO_ADDR_NEXT_N(hwfifo, , (lin_even / data_stride) * CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE);
ff_buf += lin_even;
// There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index 5a51dfc37..17ab267c3 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -81,9 +81,8 @@ typedef struct {
bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed);
#else
TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
- (void)desc_ep;
(void)speed;
- return true;
+ return tu_edpt_packet_size(desc_ep) > 0;
}
#endif
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index 7d26ac74e..8a48a0f04 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -341,12 +341,10 @@ typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< DEVICE Descriptor Type.
uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H).
-
uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF).
uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF).
uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF).
uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64.
-
uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF).
uint16_t idProduct ; ///< Product ID (assigned by the manufacturer).
uint16_t bcdDevice ; ///< Device release number in binary-coded decimal.
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 33d74862f..75df6bf60 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -104,10 +104,9 @@ TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr) {
//--------------------------------------------------------------------+
// Data Structure
//--------------------------------------------------------------------+
-typedef struct {
- tuh_bus_info_t bus_info;
- // Device Descriptor
+// Device Descriptor (without bLength and bDescriptorType header)
+typedef struct TU_ATTR_PACKED {
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
@@ -120,6 +119,13 @@ typedef struct {
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
+} desc_device_noheader_t;
+
+TU_VERIFY_STATIC( sizeof(desc_device_noheader_t) == 16u, "size is not correct");
+
+typedef struct {
+ tuh_bus_info_t bus_info;
+ desc_device_noheader_t desc_device;
// Device State
struct TU_ATTR_PACKED {
@@ -413,10 +419,10 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) {
*vid = *pid = 0;
usbh_device_t const *dev = get_device(dev_addr);
- TU_VERIFY(dev && dev->addressed && dev->idVendor != 0);
+ TU_VERIFY(dev && dev->addressed && dev->desc_device.idVendor != 0);
- *vid = dev->idVendor;
- *pid = dev->idProduct;
+ *vid = dev->desc_device.idVendor;
+ *pid = dev->desc_device.idProduct;
return true;
}
@@ -427,18 +433,7 @@ bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_dev
desc_device->bLength = sizeof(tusb_desc_device_t);
desc_device->bDescriptorType = TUSB_DESC_DEVICE;
- desc_device->bcdUSB = dev->bcdUSB;
- desc_device->bDeviceClass = dev->bDeviceClass;
- desc_device->bDeviceSubClass = dev->bDeviceSubClass;
- desc_device->bDeviceProtocol = dev->bDeviceProtocol;
- desc_device->bMaxPacketSize0 = dev->bMaxPacketSize0;
- desc_device->idVendor = dev->idVendor;
- desc_device->idProduct = dev->idProduct;
- desc_device->bcdDevice = dev->bcdDevice;
- desc_device->iManufacturer = dev->iManufacturer;
- desc_device->iProduct = dev->iProduct;
- desc_device->iSerialNumber = dev->iSerialNumber;
- desc_device->bNumConfigurations = dev->bNumConfigurations;
+ memcpy((uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), &dev->desc_device, sizeof(desc_device_noheader_t));
return true;
}
@@ -1150,7 +1145,7 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) {
}
bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) {
- // HACK: some device incorrectly always report 512 bulk regardless of link speed, overwrite descriptor to force 64
+ // HACK: some device incorrectly always reports 512 bulk regardless of link speed, overwrite descriptor to force 64
if (desc_ep->bmAttributes.xfer == TUSB_XFER_BULK && tu_edpt_packet_size(desc_ep) > 64 &&
tuh_speed_get(dev_addr) == TUSB_SPEED_FULL) {
TU_LOG1(" WARN: EP max packet size is 512 in fullspeed, force to 64\r\n");
@@ -1275,24 +1270,24 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id,
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
usbh_device_t const* dev = get_device(daddr);
- TU_VERIFY(dev && dev->iManufacturer);
- return tuh_descriptor_get_string(daddr, dev->iManufacturer, language_id, buffer, len, complete_cb, user_data);
+ TU_VERIFY(dev && dev->desc_device.iManufacturer);
+ return tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, language_id, buffer, len, complete_cb, user_data);
}
// Get product string descriptor
bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len,
tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
usbh_device_t const* dev = get_device(daddr);
- TU_VERIFY(dev && dev->iProduct);
- return tuh_descriptor_get_string(daddr, dev->iProduct, language_id, buffer, len, complete_cb, user_data);
+ TU_VERIFY(dev && dev->desc_device.iProduct);
+ return tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, language_id, buffer, len, complete_cb, user_data);
}
// Get serial string descriptor
bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len,
tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
usbh_device_t const* dev = get_device(daddr);
- TU_VERIFY(dev && dev->iSerialNumber);
- return tuh_descriptor_get_string(daddr, dev->iSerialNumber, language_id, buffer, len, complete_cb, user_data);
+ TU_VERIFY(dev && dev->desc_device.iSerialNumber);
+ return tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, language_id, buffer, len, complete_cb, user_data);
}
// Get HID report descriptor
@@ -1614,7 +1609,7 @@ static void enum_delay_async(uintptr_t state) {
const uint8_t new_addr = _usbh_data.enumerating_daddr;
usbh_device_t *new_dev = get_device(new_addr);
TU_ASSERT(new_dev, );
- if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) {
+ if (!usbh_edpt_control_open(new_addr, new_dev->desc_device.bMaxPacketSize0)) {
TU_LOG_USBH("Failed to open new device's control endpoint\r\n");
clear_device(new_dev);
enum_full_complete(false);
@@ -1655,6 +1650,7 @@ static void process_enumeration(tuh_xfer_t *xfer) {
TU_ASSERT(dev != NULL,);
}
uint16_t langid = 0x0409; // default is English
+ bool is_enum_failed = false;
switch (state) {
#if CFG_TUH_HUB
@@ -1664,11 +1660,11 @@ static void process_enumeration(tuh_xfer_t *xfer) {
if (0 == port_status.status.connection) {
TU_LOG_USBH("Device unplugged from hub while debouncing\r\n");
- enum_full_complete(false);
- return;
+ is_enum_failed = true;
+ } else {
+ TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration,
+ ENUM_HUB_RESET_COMPLETE), );
}
-
- TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_RESET_COMPLETE), );
break;
}
@@ -1691,7 +1687,7 @@ static void process_enumeration(tuh_xfer_t *xfer) {
usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY_RETRY);
} else {
// retry but still not set --> failed
- enum_full_complete(false);
+ is_enum_failed = true;
}
break;
}
@@ -1702,14 +1698,13 @@ static void process_enumeration(tuh_xfer_t *xfer) {
if (0 == port_status.status.connection) {
TU_LOG_USBH("Device unplugged from hub (not addressed yet)\r\n");
- enum_full_complete(false);
- return;
+ is_enum_failed = true;
+ break;
}
dev0_bus->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH
: (port_status.status.low_speed) ? TUSB_SPEED_LOW
: TUSB_SPEED_FULL;
-
TU_ATTR_FALLTHROUGH;
}
#endif
@@ -1720,13 +1715,19 @@ static void process_enumeration(tuh_xfer_t *xfer) {
case ENUM_SET_ADDR: {
const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl;
+ if (!(desc_device->bDescriptorType == TUSB_DESC_DEVICE && desc_device->bMaxPacketSize0 >= 8)) {
+ TU_LOG_USBH("Invalid Device descriptor\r\n");
+ is_enum_failed = true;
+ break;
+ }
+
const uint8_t new_addr = enum_get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB);
TU_ASSERT(new_addr != 0,);
usbh_device_t* new_dev = get_device(new_addr);
new_dev->bus_info = *dev0_bus;
new_dev->connected = 1;
- new_dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0;
+ new_dev->desc_device.bMaxPacketSize0 = desc_device->bMaxPacketSize0;
TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC), );
break;
@@ -1750,18 +1751,7 @@ static void process_enumeration(tuh_xfer_t *xfer) {
// save the received device descriptor
tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl;
- dev->bcdUSB = desc_device->bcdUSB;
- dev->bDeviceClass = desc_device->bDeviceClass;
- dev->bDeviceSubClass = desc_device->bDeviceSubClass;
- dev->bDeviceProtocol = desc_device->bDeviceProtocol;
- dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0;
- dev->idVendor = desc_device->idVendor;
- dev->idProduct = desc_device->idProduct;
- dev->bcdDevice = desc_device->bcdDevice;
- dev->iManufacturer = desc_device->iManufacturer;
- dev->iProduct = desc_device->iProduct;
- dev->iSerialNumber = desc_device->iSerialNumber;
- dev->bNumConfigurations = desc_device->bNumConfigurations;
+ memcpy(&dev->desc_device, (const uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), sizeof(desc_device_noheader_t));
tuh_enum_descriptor_device_cb(daddr, desc_device); // callback
tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, 2,
@@ -1781,8 +1771,8 @@ static void process_enumeration(tuh_xfer_t *xfer) {
if (desc_langid->bLength >= 4) {
langid = tu_le16toh(desc_langid->utf16le[0]); // previous request is langid
}
- if (dev->iManufacturer != 0) {
- tuh_descriptor_get_string(daddr, dev->iManufacturer, langid, _usbh_epbuf.ctrl, 2,
+ if (dev->desc_device.iManufacturer != 0) {
+ tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, 2,
process_enumeration, ENUM_GET_STRING_MANUFACTURER);
break;
}
@@ -1790,10 +1780,10 @@ static void process_enumeration(tuh_xfer_t *xfer) {
}
case ENUM_GET_STRING_MANUFACTURER: {
- if (dev->iManufacturer != 0) {
+ if (dev->desc_device.iManufacturer != 0) {
langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
const uint8_t str_len = xfer->buffer[0];
- tuh_descriptor_get_string(daddr, dev->iManufacturer, langid, _usbh_epbuf.ctrl, str_len,
+ tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, str_len,
process_enumeration, ENUM_GET_STRING_PRODUCT_LEN);
break;
}
@@ -1801,22 +1791,22 @@ static void process_enumeration(tuh_xfer_t *xfer) {
}
case ENUM_GET_STRING_PRODUCT_LEN: {
- if (dev->iProduct != 0) {
+ if (dev->desc_device.iProduct != 0) {
if (state == ENUM_GET_STRING_PRODUCT_LEN) {
langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through
}
tuh_descriptor_get_string(
- daddr, dev->iProduct, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_PRODUCT);
+ daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_PRODUCT);
break;
}
TU_ATTR_FALLTHROUGH;
}
case ENUM_GET_STRING_PRODUCT: {
- if (dev->iProduct != 0) {
+ if (dev->desc_device.iProduct != 0) {
langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
const uint8_t str_len = xfer->buffer[0];
- tuh_descriptor_get_string(daddr, dev->iProduct, langid, _usbh_epbuf.ctrl, str_len,
+ tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, str_len,
process_enumeration, ENUM_GET_STRING_SERIAL_LEN);
break;
}
@@ -1824,22 +1814,22 @@ static void process_enumeration(tuh_xfer_t *xfer) {
}
case ENUM_GET_STRING_SERIAL_LEN: {
- if (dev->iSerialNumber != 0) {
+ if (dev->desc_device.iSerialNumber != 0) {
if (state == ENUM_GET_STRING_SERIAL_LEN) {
langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through
}
tuh_descriptor_get_string(
- daddr, dev->iSerialNumber, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_SERIAL);
+ daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_SERIAL);
break;
}
TU_ATTR_FALLTHROUGH;
}
case ENUM_GET_STRING_SERIAL: {
- if (dev->iSerialNumber != 0) {
+ if (dev->desc_device.iSerialNumber != 0) {
langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
const uint8_t str_len = xfer->buffer[0];
- tuh_descriptor_get_string(daddr, dev->iSerialNumber, langid, _usbh_epbuf.ctrl, str_len,
+ tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, str_len,
process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC);
break;
}
@@ -1878,7 +1868,7 @@ static void process_enumeration(tuh_xfer_t *xfer) {
TU_ASSERT(tuh_configuration_set(daddr, config_idx+1u, process_enumeration, ENUM_CONFIG_DRIVER),);
} else {
config_idx++;
- TU_ASSERT(config_idx < dev->bNumConfigurations,);
+ TU_ASSERT(config_idx < dev->desc_device.bNumConfigurations,);
TU_LOG_USBH("Get Configuration[%u] Descriptor (9 bytes)\r\n", config_idx);
TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, 9,
process_enumeration, ENUM_GET_FULL_CONFIG_DESC),);
@@ -1910,9 +1900,13 @@ static void process_enumeration(tuh_xfer_t *xfer) {
}
default:
- enum_full_complete(false); // stop enumeration if unknown state
+ is_enum_failed = true;
break;
}
+
+ if (is_enum_failed) {
+ enum_full_complete(false);
+ }
}
static uint8_t enum_get_new_address(bool is_hub) {
diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
index b9f6a8a7b..9ed75ffd9 100644
--- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
@@ -388,7 +388,7 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_mask(volatile uint32_t *epctrl,
uint32_t or_mask) {
uint32_t value = *epctrl;
if (and_mask != 0) {
- value &= (dir == TUSB_DIR_OUT) ? and_mask : (and_mask << 16u);
+ value &= (dir == TUSB_DIR_OUT) ? (and_mask | 0xFFFF0000u) : ((and_mask << 16u) | 0x0000FFFFu);
}
if (or_mask != 0) {
value |= (dir == TUSB_DIR_OUT) ? or_mask : (or_mask << 16u);
diff --git a/src/tusb.c b/src/tusb.c
index 5241fcf3d..4ea396715 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -260,6 +260,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) {
bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
const uint16_t max_packet_size = tu_edpt_packet_size(desc_ep);
TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);
+ TU_ASSERT(max_packet_size > 0);
switch (desc_ep->bmAttributes.xfer) {
case TUSB_XFER_ISOCHRONOUS: {
@@ -279,7 +280,7 @@ bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
break;
case TUSB_XFER_INTERRUPT: {
- uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
+ const uint16_t spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
TU_ASSERT(max_packet_size <= spec_size);
break;
}