From 72c1066ed152916cb99dee5e5749b78916d4ba76 Mon Sep 17 00:00:00 2001 From: Duddie Date: Sun, 28 Feb 2021 22:18:35 +0800 Subject: Fix Endpoint descriptor for MIDI Device Endpoint descriptor should be 9 bytes in length (not 7) and have two extra bytes at the end: bRefresh and bSynchAddress According to MIDI USB specification 1.0 (6.2.1 Standard MS Bulk Data Endpoint Descriptor) --- src/device/usbd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/device') diff --git a/src/device/usbd.h b/src/device/usbd.h index b5f7dceba..8aeb6aff8 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -289,10 +289,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* MS Out Jack (External), connected to In Jack Embedded */\ 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, TUD_MIDI_JACKID_OUT_EXT(_cablenum), 1, TUD_MIDI_JACKID_IN_EMB(_cablenum), 1, 0 -#define TUD_MIDI_DESC_EP_LEN(_numcables) (7 + 4 + (_numcables)) +#define TUD_MIDI_DESC_EP_LEN(_numcables) (9 + 4 + (_numcables)) #define TUD_MIDI_DESC_EP(_epout, _epsize, _numcables) \ /* Endpoint */\ - 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + 9, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, 0, 0, \ /* MS Endpoint (connected to embedded jack) */\ (uint8_t)(4 + (_numcables)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, _numcables -- cgit v1.3.1 From 9d5e3691706f3f17edd701310b967c729240a507 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Mar 2021 23:24:36 +0700 Subject: rp2040 add disconnection detection - also use dcd_event_bus_reset() - Add TODO for suspend, resume later on (need to test with/without vbus detection). --- src/device/usbd.c | 21 ++++++++------ src/portable/raspberrypi/rp2040/dcd_rp2040.c | 43 ++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 11 deletions(-) (limited to 'src/device') diff --git a/src/device/usbd.c b/src/device/usbd.c index 4fc221888..911977eb0 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -992,11 +992,15 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) switch (event->event_id) { case DCD_EVENT_UNPLUGGED: - _usbd_dev.connected = 0; - _usbd_dev.addressed = 0; - _usbd_dev.cfg_num = 0; - _usbd_dev.suspended = 0; - osal_queue_send(_usbd_q, event, in_isr); + // UNPLUGGED event can be bouncing, only processing if we are currently connected + if ( _usbd_dev.connected ) + { + _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; + _usbd_dev.cfg_num = 0; + _usbd_dev.suspended = 0; + osal_queue_send(_usbd_q, event, in_isr); + } break; case DCD_EVENT_SOF: @@ -1004,9 +1008,10 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) break; case DCD_EVENT_SUSPEND: - // NOTE: When plugging/unplugging device, the D+/D- state are unstable and can accidentally meet the - // SUSPEND condition ( Idle for 3ms ). Some MCUs such as SAMD doesn't distinguish suspend vs disconnect as well. - // We will skip handling SUSPEND/RESUME event if not currently connected + // NOTE: When plugging/unplugging device, the D+/D- state are unstable and + // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). + // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish + // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected if ( _usbd_dev.connected ) { _usbd_dev.suspended = 1; diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index d32870439..84dce0248 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -317,13 +317,45 @@ static void dcd_rp2040_irq(void) pico_trace("BUS RESET (addr %d -> %d)\n", assigned_address, 0); 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(); #endif } + 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; + } + +#if 0 // TODO Enable SUSPEND & RESUME interrupt and test later on with/without VBUS detection + 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)); @@ -364,8 +396,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); } @@ -393,8 +427,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- @@ -402,6 +437,7 @@ void dcd_disconnect(uint8_t rhport) { pico_info("dcd_disconnect %d\n", rhport); assert(rhport == 0); + //TU_LOG2("dcd_disconnect\n"); usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } @@ -410,6 +446,7 @@ void dcd_connect(uint8_t rhport) { pico_info("dcd_connect %d\n", rhport); assert(rhport == 0); + //TU_LOG2("dcd_connect\n"); usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } -- cgit v1.3.1 From a655a4169e4a7be4b547f012643a86d198d46b1f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Mar 2021 01:18:49 +0700 Subject: add note for MIDI (audio v1.0) endpoint decriptor use 9 bytes instead of 7 --- src/device/usbd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/device') diff --git a/src/device/usbd.h b/src/device/usbd.h index 8aeb6aff8..56615b081 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -254,6 +254,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval //------------- MIDI -------------// +// MIDI v1.0 is based on Audio v1.0 #define TUD_MIDI_DESC_HEAD_LEN (9 + 9 + 9 + 7) #define TUD_MIDI_DESC_HEAD(_itfnum, _stridx, _numcables) \ @@ -291,7 +292,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb #define TUD_MIDI_DESC_EP_LEN(_numcables) (9 + 4 + (_numcables)) #define TUD_MIDI_DESC_EP(_epout, _epsize, _numcables) \ - /* Endpoint */\ + /* Endpoint: Note Audio v1.0's endpoint has 9 bytes instead of 7 */\ 9, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, 0, 0, \ /* MS Endpoint (connected to embedded jack) */\ (uint8_t)(4 + (_numcables)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, _numcables -- cgit v1.3.1 From eeea19c0ab1c6e66c56eabac49e2c0f190e9a080 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Mar 2021 11:33:03 +0700 Subject: usbd ack SET_INTERFACE if it is not implemented by class driver. --- src/device/usbd.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/device') diff --git a/src/device/usbd.c b/src/device/usbd.c index 911977eb0..ca5a482fc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -699,13 +699,21 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE if ( !invoke_class_control(rhport, driver, p_request) ) { - // For GET_INTERFACE, it is mandatory to respond even if the class - // driver doesn't use alternate settings. - TU_VERIFY( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && - TUSB_REQ_GET_INTERFACE == p_request->bRequest); + // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class + // driver doesn't use alternate settings or implement this + TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type); - uint8_t alternate = 0; - tud_control_xfer(rhport, p_request, &alternate, 1); + if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) + { + uint8_t alternate = 0; + tud_control_xfer(rhport, p_request, &alternate, 1); + }else if (TUSB_REQ_SET_INTERFACE == p_request->bRequest) + { + tud_control_status(rhport, p_request); + } else + { + return false; + } } } break; -- cgit v1.3.1