mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-19 15:40:41 +00:00
Merge remote-tracking branch 'remotes/hathach/master' into max3421_nak_retry
This commit is contained in:
commit
14ce05fea3
16
.github/workflows/build_esp.yml
vendored
16
.github/workflows/build_esp.yml
vendored
@ -86,11 +86,17 @@ jobs:
|
||||
# USB bus on rpi4 is not stable, reset it before testing
|
||||
- name: Reset USB bus
|
||||
run: |
|
||||
for port in $(lspci | grep USB | cut -d' ' -f1); do
|
||||
echo -n "0000:${port}"| sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind;
|
||||
sleep 0.1;
|
||||
echo -n "0000:${port}" | sudo tee /sys/bus/pci/drivers/xhci_hcd/bind;
|
||||
done
|
||||
lsusb
|
||||
lsusb -t
|
||||
# reset VIA Labs 2.0 hub
|
||||
sudo usbreset 001/002
|
||||
|
||||
# legacy code
|
||||
#for port in $(lspci | grep USB | cut -d' ' -f1); do
|
||||
# echo -n "0000:${port}"| sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind;
|
||||
# sleep 0.1;
|
||||
# echo -n "0000:${port}" | sudo tee /sys/bus/pci/drivers/xhci_hcd/bind;
|
||||
#done
|
||||
|
||||
- name: Checkout test/hil
|
||||
uses: actions/checkout@v4
|
||||
|
16
.github/workflows/cmake_arm.yml
vendored
16
.github/workflows/cmake_arm.yml
vendored
@ -141,11 +141,17 @@ jobs:
|
||||
# USB bus on rpi4 is not stable, reset it before testing
|
||||
- name: Reset USB bus
|
||||
run: |
|
||||
for port in $(lspci | grep USB | cut -d' ' -f1); do
|
||||
echo -n "0000:${port}"| sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind;
|
||||
sleep 0.1;
|
||||
echo -n "0000:${port}" | sudo tee /sys/bus/pci/drivers/xhci_hcd/bind;
|
||||
done
|
||||
lsusb
|
||||
lsusb -t
|
||||
# reset VIA Labs 2.0 hub
|
||||
sudo usbreset 001/002
|
||||
|
||||
# legacy code
|
||||
#for port in $(lspci | grep USB | cut -d' ' -f1); do
|
||||
# echo -n "0000:${port}"| sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind;
|
||||
# sleep 0.1;
|
||||
# echo -n "0000:${port}" | sudo tee /sys/bus/pci/drivers/xhci_hcd/bind;
|
||||
#done
|
||||
|
||||
- name: Checkout test/hil
|
||||
uses: actions/checkout@v4
|
||||
|
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
- name: Label New Issue or PR
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
let label = '';
|
||||
let username = '';
|
||||
|
@ -116,6 +116,7 @@ static inline uint32_t board_millis(void) {
|
||||
|
||||
#elif CFG_TUSB_OS == OPT_OS_CUSTOM
|
||||
// Implement your own board_millis() in any of .c file
|
||||
uint32_t board_millis(void);
|
||||
|
||||
#else
|
||||
#error "board_millis() is not implemented for this OS"
|
||||
|
126
src/host/usbh.c
126
src/host/usbh.c
@ -412,9 +412,11 @@ bool tuh_deinit(uint8_t rhport) {
|
||||
// deinit host controller
|
||||
hcd_int_disable(rhport);
|
||||
hcd_deinit(rhport);
|
||||
|
||||
_usbh_controller = TUSB_INDEX_INVALID_8;
|
||||
|
||||
// "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0)
|
||||
process_removing_device(rhport, 0, 0);
|
||||
|
||||
// deinit host stack if no controller is active
|
||||
if (!tuh_inited()) {
|
||||
// Class drivers
|
||||
@ -1138,43 +1140,42 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt,
|
||||
TU_VERIFY(_async_func(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \
|
||||
return (uint8_t) result
|
||||
|
||||
uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get, daddr, type, index, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_device, daddr, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_configuration, daddr, index, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_hid_report, daddr, itf_num, desc_type, index, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_string, daddr, index, language_id, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, daddr, language_id, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_product_string, daddr, language_id, buffer, len);
|
||||
}
|
||||
|
||||
uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len)
|
||||
{
|
||||
uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id,
|
||||
void* buffer, uint16_t len) {
|
||||
_CONTROL_SYNC_API(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len);
|
||||
}
|
||||
|
||||
@ -1210,57 +1211,60 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) {
|
||||
static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) {
|
||||
//------------- find the all devices (star-network) under port that is unplugged -------------//
|
||||
// TODO mark as disconnected in ISR, also handle dev0
|
||||
uint32_t removing_hubs = 0;
|
||||
do {
|
||||
for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) {
|
||||
usbh_device_t* dev = &_usbh_devices[dev_id];
|
||||
uint8_t const daddr = dev_id + 1;
|
||||
|
||||
#if 0
|
||||
// index as hub addr, value is hub port (0xFF for invalid)
|
||||
uint8_t removing_hubs[CFG_TUH_HUB];
|
||||
memset(removing_hubs, TUSB_INDEX_INVALID_8, sizeof(removing_hubs));
|
||||
// hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub
|
||||
if (dev->rhport == rhport && dev->connected &&
|
||||
(hub_addr == 0 || dev->hub_addr == hub_addr) &&
|
||||
(hub_port == 0 || dev->hub_port == hub_port)) {
|
||||
TU_LOG_USBH("[%u:%u:%u] unplugged address = %u\r\n", rhport, hub_addr, hub_port, daddr);
|
||||
|
||||
removing_hubs[hub_addr-CFG_TUH_DEVICE_MAX] = hub_port;
|
||||
if (is_hub_addr(daddr)) {
|
||||
TU_LOG_USBH(" is a HUB device %u\r\n", daddr);
|
||||
removing_hubs |= TU_BIT(dev_id - CFG_TUH_DEVICE_MAX);
|
||||
} else {
|
||||
// Invoke callback before closing driver (maybe call it later ?)
|
||||
if (tuh_umount_cb) tuh_umount_cb(daddr);
|
||||
}
|
||||
|
||||
// consecutive non-removing hub
|
||||
uint8_t nop_count = 0;
|
||||
#endif
|
||||
// Close class driver
|
||||
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
|
||||
usbh_class_driver_t const* driver = get_driver(drv_id);
|
||||
if (driver) driver->close(daddr);
|
||||
}
|
||||
|
||||
for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) {
|
||||
usbh_device_t *dev = &_usbh_devices[dev_id];
|
||||
uint8_t const daddr = dev_id + 1;
|
||||
hcd_device_close(rhport, daddr);
|
||||
clear_device(dev);
|
||||
|
||||
// hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub
|
||||
if (dev->rhport == rhport && dev->connected &&
|
||||
(hub_addr == 0 || dev->hub_addr == hub_addr) &&
|
||||
(hub_port == 0 || dev->hub_port == hub_port)) {
|
||||
TU_LOG_USBH("Device unplugged address = %u\r\n", daddr);
|
||||
|
||||
if (is_hub_addr(daddr)) {
|
||||
TU_LOG_USBH(" is a HUB device %u\r\n", daddr);
|
||||
|
||||
// Submit removed event If the device itself is a hub (un-rolled recursive)
|
||||
// TODO a better to unroll recursrive is using array of removing_hubs and mark it here
|
||||
hcd_event_t event;
|
||||
event.rhport = rhport;
|
||||
event.event_id = HCD_EVENT_DEVICE_REMOVE;
|
||||
event.connection.hub_addr = daddr;
|
||||
event.connection.hub_port = 0;
|
||||
|
||||
hcd_event_handler(&event, false);
|
||||
} else {
|
||||
// Invoke callback before closing driver (maybe call it later ?)
|
||||
if (tuh_umount_cb) tuh_umount_cb(daddr);
|
||||
// abort on-going control xfer on this device if any
|
||||
if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE);
|
||||
}
|
||||
|
||||
// Close class driver
|
||||
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
|
||||
usbh_class_driver_t const * driver = get_driver(drv_id);
|
||||
if ( driver ) driver->close(daddr);
|
||||
}
|
||||
|
||||
hcd_device_close(rhport, daddr);
|
||||
clear_device(dev);
|
||||
// abort on-going control xfer if any
|
||||
if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
// if removing a hub, we need to remove its downstream devices
|
||||
#if CFG_TUH_HUB
|
||||
if (removing_hubs == 0) break;
|
||||
|
||||
// find a marked hub to process
|
||||
for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) {
|
||||
if (tu_bit_test(removing_hubs, h_id)) {
|
||||
removing_hubs &= ~TU_BIT(h_id);
|
||||
|
||||
// update hub_addr and hub_port for next loop
|
||||
hub_addr = h_id + 1 + CFG_TUH_DEVICE_MAX;
|
||||
hub_port = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) removing_hubs;
|
||||
break;
|
||||
#endif
|
||||
} while(1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -113,7 +113,7 @@ static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_en
|
||||
static void __tusb_irq_path_func(hw_handle_buff_status)(void)
|
||||
{
|
||||
uint32_t remaining_buffers = usb_hw->buf_status;
|
||||
pico_trace("buf_status 0x%08x\n", remaining_buffers);
|
||||
pico_trace("buf_status 0x%08lx\n", remaining_buffers);
|
||||
|
||||
// Check EPX first
|
||||
uint bit = 0b1;
|
||||
@ -325,10 +325,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
|
||||
ep->wMaxPacketSize = wMaxPacketSize;
|
||||
ep->transfer_type = transfer_type;
|
||||
|
||||
pico_trace("hw_endpoint_init dev %d ep %d %s xfer %d\n", ep->dev_addr, tu_edpt_number(ep->ep_addr),
|
||||
ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->transfer_type);
|
||||
pico_trace("dev %d ep %d %s setup buffer @ 0x%p\n", ep->dev_addr, tu_edpt_number(ep->ep_addr),
|
||||
ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->hw_data_buf);
|
||||
pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, ep->transfer_type);
|
||||
pico_trace("dev %d ep %02X setup buffer @ 0x%p\n", ep->dev_addr, ep->ep_addr, ep->hw_data_buf);
|
||||
uint dpram_offset = hw_data_offset(ep->hw_data_buf);
|
||||
// Bits 0-5 should be 0
|
||||
assert(!(dpram_offset & 0b111111));
|
||||
@ -343,7 +341,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t
|
||||
ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB);
|
||||
}
|
||||
*ep->endpoint_control = ep_reg;
|
||||
pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg);
|
||||
pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg);
|
||||
ep->configured = true;
|
||||
|
||||
if ( ep != &epx )
|
||||
|
Loading…
x
Reference in New Issue
Block a user