From cc816dc9c04762f14468a0b7b1826768e731f53f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 17:41:20 +0700 Subject: change edpt stream api to take hwid from API to reduce memory footprint --- src/class/cdc/cdc_host.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/class/cdc/cdc_host.c') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 133a10f6e..8717970e6 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -341,14 +341,14 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { @@ -362,7 +362,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_available(&p_cdc->stream.tx); + return tu_edpt_stream_write_available(p_cdc->daddr, &p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -373,7 +373,7 @@ uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { @@ -395,7 +395,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -677,10 +677,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // invoke tx complete callback to possibly refill tx fifo if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); - if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) ) { + if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if: // - xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI @@ -698,7 +698,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); // prepare for next transfer if needed - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); }else if ( ep_addr == p_cdc->ep_notif ) { // TODO handle notification endpoint }else { @@ -719,9 +719,9 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); } else { - tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); } desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(desc_ep); @@ -763,7 +763,7 @@ static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t i if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(p_cdc->daddr, itf_num); -- cgit v1.3.1 From 67e92e6688e609098270ba249f15a8dc7f051cbf Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Nov 2024 22:07:28 +0700 Subject: add TUH_EPBUF_DEF for cdc host --- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 14 --------- examples/host/cdc_msc_hid_freertos/src/main.c | 14 --------- hw/bsp/espressif/boards/family.c | 40 ++++++++---------------- src/class/cdc/cdc_host.c | 36 +++++++++++++-------- src/class/cdc/cdc_host.h | 3 +- 5 files changed, 37 insertions(+), 70 deletions(-) (limited to 'src/class/cdc/cdc_host.c') diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c index dfe1418f6..7cbe1e03a 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -28,22 +28,8 @@ #include "bsp/board_api.h" #if TUSB_MCU_VENDOR_ESPRESSIF -// ESP-IDF need "freertos/" prefix in include path. -// CFG_TUSB_OS_INC_PATH should be defined accordingly. - #include "freertos/FreeRTOS.h" - #include "freertos/semphr.h" - #include "freertos/queue.h" - #include "freertos/task.h" - #include "freertos/timers.h" - #define CDC_STACK_SZIE 2048 #else - #include "FreeRTOS.h" - #include "semphr.h" - #include "queue.h" - #include "task.h" - #include "timers.h" - #define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2) #endif diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index fe050d334..10d1b120b 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -31,22 +31,8 @@ #include "tusb.h" #if TUSB_MCU_VENDOR_ESPRESSIF - // ESP-IDF need "freertos/" prefix in include path. - // CFG_TUSB_OS_INC_PATH should be defined accordingly. - #include "freertos/FreeRTOS.h" - #include "freertos/semphr.h" - #include "freertos/queue.h" - #include "freertos/task.h" - #include "freertos/timers.h" - #define USBH_STACK_SIZE 4096 #else - #include "FreeRTOS.h" - #include "semphr.h" - #include "queue.h" - #include "task.h" - #include "timers.h" - // Increase stack size when debug log is enabled #define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 729b3539d..048b431fb 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -35,10 +35,6 @@ #include "driver/uart.h" #include "esp_private/periph_ctrl.h" -// Note; current code use UART0 can cause device to reset while monitoring -#define USE_UART 0 -#define UART_ID UART_NUM_0 - #ifdef NEOPIXEL_PIN #include "led_strip.h" static led_strip_handle_t led_strip; @@ -57,19 +53,6 @@ static bool usb_init(void); // Initialize on-board peripherals : led, button, uart and USB void board_init(void) { -#if USE_UART - // uart init - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE - }; - uart_driver_install(UART_ID, 1024, 0, 0, NULL, 0); - uart_param_config(UART_ID, &uart_config); -#endif - #ifdef NEOPIXEL_PIN #ifdef NEOPIXEL_POWER_PIN gpio_reset_pin(NEOPIXEL_POWER_PIN); @@ -145,23 +128,26 @@ uint32_t board_button_read(void) { // Get characters from UART int board_uart_read(uint8_t* buf, int len) { -#if USE_UART - return uart_read_bytes(UART_ID, buf, len, 0); -#else - return -1; -#endif + for (int i=0; i 0 ? (int) c : (-1); + return getchar(); } //-------------------------------------------------------------------- diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 8717970e6..d92fd875d 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -73,15 +73,17 @@ typedef struct { tu_edpt_stream_t rx; uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; - CFG_TUH_MEM_ALIGN uint8_t tx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; - uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; - CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; } cdch_interface_t; -CFG_TUH_MEM_SECTION +typedef struct { + TUH_EPBUF_DEF(tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + TUH_EPBUF_DEF(rx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); +} cdch_epbuf_t; + static cdch_interface_t cdch_data[CFG_TUH_CDC]; +CFG_TUH_MEM_SECTION static cdch_epbuf_t cdch_epbuf[CFG_TUH_CDC]; //--------------------------------------------------------------------+ // Serial Driver @@ -626,13 +628,14 @@ bool cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t* p_cdc = &cdch_data[i]; + cdch_epbuf_t* epbuf = &cdch_epbuf[i]; tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + epbuf->tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + epbuf->rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } return true; @@ -654,7 +657,9 @@ void cdch_close(uint8_t daddr) { TU_LOG_DRV(" CDCh close addr = %u index = %u\r\n", daddr, idx); // Invoke application callback - if (tuh_cdc_umount_cb) tuh_cdc_umount_cb(idx); + if (tuh_cdc_umount_cb) { + tuh_cdc_umount_cb(idx); + } p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; @@ -675,7 +680,9 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if ( ep_addr == p_cdc->stream.tx.ep_addr ) { // invoke tx complete callback to possibly refill tx fifo - if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); + if (tuh_cdc_tx_complete_cb) { + tuh_cdc_tx_complete_cb(idx); + } if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if: @@ -695,7 +702,9 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } // invoke receive callback - if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); + if (tuh_cdc_rx_cb) { + tuh_cdc_rx_cb(idx); + } // prepare for next transfer if needed tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); @@ -738,9 +747,8 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); - } - else if (SERIAL_DRIVER_COUNT > 1 && - TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { + } else if (SERIAL_DRIVER_COUNT > 1 && + TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); @@ -760,7 +768,9 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { TU_LOG_DRV("CDCh Set Configure complete\r\n"); p_cdc->mounted = true; - if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); + if (tuh_cdc_mount_cb) { + tuh_cdc_mount_cb(idx); + } // Prepare for incoming data tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index b63dd1530..df975b2f0 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -89,8 +89,7 @@ bool tuh_cdc_get_dtr(uint8_t idx); bool tuh_cdc_get_rts(uint8_t idx); // Check if interface is connected (DTR active) -TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) { return tuh_cdc_get_dtr(idx); } -- cgit v1.3.1 From 9e4b855e5309976ead84d6cc65288e0e03f27ba5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Nov 2024 11:35:21 +0700 Subject: minor clean up --- src/class/cdc/cdc_host.c | 8 ++++---- src/class/hid/hid_host.c | 18 +++++++++--------- src/host/usbh.c | 2 -- src/host/usbh.h | 2 -- test/hil/hil_test.py | 2 +- tools/build.py | 2 +- 6 files changed, 15 insertions(+), 19 deletions(-) (limited to 'src/class/cdc/cdc_host.c') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index d92fd875d..e817ebc7e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -78,8 +78,8 @@ typedef struct { } cdch_interface_t; typedef struct { - TUH_EPBUF_DEF(tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); - TUH_EPBUF_DEF(rx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + TUH_EPBUF_DEF(tx, CFG_TUH_CDC_TX_EPSIZE); + TUH_EPBUF_DEF(rx, CFG_TUH_CDC_TX_EPSIZE); } cdch_epbuf_t; static cdch_interface_t cdch_data[CFG_TUH_CDC]; @@ -631,11 +631,11 @@ bool cdch_init(void) { cdch_epbuf_t* epbuf = &cdch_epbuf[i]; tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - epbuf->tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + epbuf->tx, CFG_TUH_CDC_TX_EPSIZE); tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - epbuf->rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + epbuf->rx, CFG_TUH_CDC_RX_EPSIZE); } return true; diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 5ce47606d..eef584d74 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -61,8 +61,8 @@ typedef struct { } hidh_interface_t; typedef struct { - TUH_EPBUF_DEF(epin_buf, CFG_TUH_HID_EPIN_BUFSIZE); - TUH_EPBUF_DEF(epout_buf, CFG_TUH_HID_EPOUT_BUFSIZE); + TUH_EPBUF_DEF(epin, CFG_TUH_HID_EPIN_BUFSIZE); + TUH_EPBUF_DEF(epout, CFG_TUH_HID_EPOUT_BUFSIZE); } hidh_epbuf_t; static hidh_interface_t _hidh_itf[CFG_TUH_HID]; @@ -363,7 +363,7 @@ bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) { // claim endpoint TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_in)); - if (!usbh_edpt_xfer(daddr, p_hid->ep_in, epbuf->epin_buf, p_hid->epin_size)) { + if (!usbh_edpt_xfer(daddr, p_hid->ep_in, epbuf->epin, p_hid->epin_size)) { usbh_edpt_release(daddr, p_hid->ep_in); return false; } @@ -403,16 +403,16 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo if (report_id == 0) { // No report ID in transmission - memcpy(&epbuf->epout_buf[0], report, len); + memcpy(&epbuf->epout[0], report, len); } else { - epbuf->epout_buf[0] = report_id; - memcpy(&epbuf->epout_buf[1], report, len); + epbuf->epout[0] = report_id; + memcpy(&epbuf->epout[1], report, len); ++len; // 1 more byte for report_id } TU_LOG3_MEM(p_hid->epout_buf, len, 2); - if (!usbh_edpt_xfer(daddr, p_hid->ep_out, epbuf->epout_buf, len)) { + if (!usbh_edpt_xfer(daddr, p_hid->ep_out, epbuf->epout, len)) { usbh_edpt_release(daddr, p_hid->ep_out); return false; } @@ -446,10 +446,10 @@ bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t if (dir == TUSB_DIR_IN) { TU_LOG_DRV(" Get Report callback (%u, %u)\r\n", daddr, idx); TU_LOG3_MEM(p_hid->epin_buf, xferred_bytes, 2); - tuh_hid_report_received_cb(daddr, idx, epbuf->epin_buf, (uint16_t) xferred_bytes); + tuh_hid_report_received_cb(daddr, idx, epbuf->epin, (uint16_t) xferred_bytes); } else { if (tuh_hid_report_sent_cb) { - tuh_hid_report_sent_cb(daddr, idx, epbuf->epout_buf, (uint16_t) xferred_bytes); + tuh_hid_report_sent_cb(daddr, idx, epbuf->epout, (uint16_t) xferred_bytes); } } diff --git a/src/host/usbh.c b/src/host/usbh.c index 73753a713..a9a692455 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1477,8 +1477,6 @@ static void process_enumeration(tuh_xfer_t* xfer) { dev->i_product = desc_device->iProduct; dev->i_serial = desc_device->iSerialNumber; - // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_epbuf.ctrl); - // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor (9 bytes)\r\n"); diff --git a/src/host/usbh.h b/src/host/usbh.h index 20fad284e..72c237573 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -96,8 +96,6 @@ typedef union { // APPLICATION CALLBACK //--------------------------------------------------------------------+ -//TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device); - // Invoked when a device is mounted (configured) TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index f125c0d28..a9f5dc1e1 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -549,7 +549,7 @@ def test_board(board): for f1 in flags_on_list: f1_str = "" if f1 != "": - f1_str = '-' + f1.replace(' ', '-') + f1_str = '-f1_' + f1.replace(' ', '_') for test in test_list: fw_dir = f'{TINYUSB_ROOT}/cmake-build/cmake-build-{name}{f1_str}/{test}' if not os.path.exists(fw_dir): diff --git a/tools/build.py b/tools/build.py index 48666adc4..3a9239bc2 100755 --- a/tools/build.py +++ b/tools/build.py @@ -90,7 +90,7 @@ def cmake_board(board, toolchain, build_flags_on): if len(build_flags_on) > 0: build_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on) build_flags = f'-DCFLAGS_CLI="{build_flags}"' - build_dir += '-' + '-'.join(build_flags_on) + build_dir += '-f1_' + '_'.join(build_flags_on) family = find_family(board) if family == 'espressif': -- cgit v1.3.1 From bad6cbe48930c0c5250b8a717a46cc1f6d83de56 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 13 Feb 2025 15:52:30 +0700 Subject: update midi host to use endpoint stream API --- src/class/cdc/cdc_host.c | 4 +- src/class/midi/midi_host.c | 445 +++++++++++++++------------------------------ src/class/midi/midi_host.h | 25 +-- src/common/tusb_private.h | 10 +- src/host/usbh.c | 3 +- src/host/usbh.h | 3 + 6 files changed, 174 insertions(+), 316 deletions(-) (limited to 'src/class/cdc/cdc_host.c') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index e817ebc7e..4058857c5 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -691,10 +691,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI - if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI) { + if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI && xferred_bytes > 2) { // FTDI reserve 2 bytes for status // uint8_t status[2] = {p_cdc->stream.rx.ep_buf[0], p_cdc->stream.rx.ep_buf[1]}; - tu_edpt_stream_read_xfer_complete_offset(&p_cdc->stream.rx, xferred_bytes, 2); + tu_edpt_stream_read_xfer_complete_with_buf(&p_cdc->stream.rx, p_cdc->stream.rx.ep_buf+2, xferred_bytes-2); }else #endif { diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 21fe09143..eb3f0b070 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -45,15 +45,12 @@ typedef struct uint8_t total; }midi_stream_t; -typedef struct -{ +typedef struct { uint8_t dev_addr; uint8_t itf_num; uint8_t ep_in; // IN endpoint address uint8_t ep_out; // OUT endpoint address - uint16_t ep_in_max; // min( CFG_TUH_MIDI_RX_BUFSIZE, wMaxPacketSize of the IN endpoint) - uint16_t ep_out_max; // min( CFG_TUH_MIDI_TX_BUFSIZE, wMaxPacketSize of the OUT endpoint) uint8_t num_cables_rx; // IN endpoint CS descriptor bNumEmbMIDIJack value uint8_t num_cables_tx; // OUT endpoint CS descriptor bNumEmbMIDIJack value @@ -65,22 +62,14 @@ typedef struct midi_stream_t stream_read; /*------------- From this point, data is not cleared by bus reset -------------*/ - // Endpoint FIFOs - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; - - - uint8_t rx_ff_buf[CFG_TUH_MIDI_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUH_MIDI_TX_BUFSIZE]; - - #if CFG_FIFO_MUTEX - osal_mutex_def_t rx_ff_mutex; - osal_mutex_def_t tx_ff_mutex; - #endif + // Endpoint stream + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; - // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUH_MIDI_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUH_MIDI_EP_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUH_MIDI_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUH_MIDI_TX_BUFSIZE]; + } ep_stream; bool configured; @@ -109,15 +98,17 @@ typedef struct #endif }midih_interface_t; -static midih_interface_t _midi_host[CFG_TUH_MIDI]; +typedef struct { + TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MPS); + TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MPS); +} midih_epbuf_t; -//------------- Internal prototypes -------------// -static uint32_t write_flush(uint8_t dev_addr, midih_interface_t* midi); +static midih_interface_t _midi_host[CFG_TUH_MIDI]; +CFG_TUH_MEM_SECTION static midih_epbuf_t _midi_epbuf[CFG_TUH_MIDI]; //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ - TU_ATTR_ALWAYS_INLINE static inline midih_interface_t* find_midi_by_daddr(uint8_t dev_addr) { for (uint8_t i = 0; i < CFG_TUH_MIDI; i++) { if (_midi_host[i].dev_addr == dev_addr) { @@ -131,85 +122,27 @@ TU_ATTR_ALWAYS_INLINE static inline midih_interface_t* find_new_midi(void) { return find_midi_by_daddr(0); } - //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ bool midih_init(void) { tu_memclr(&_midi_host, sizeof(_midi_host)); - // config fifos for (int inst = 0; inst < CFG_TUH_MIDI; inst++) { midih_interface_t *p_midi_host = &_midi_host[inst]; - tu_fifo_config(&p_midi_host->rx_ff, p_midi_host->rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, 1, false);// true, true - tu_fifo_config(&p_midi_host->tx_ff, p_midi_host->tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, 1, false);// OBVS. - - #if CFG_FIFO_MUTEX - tu_fifo_config_mutex(&p_midi_host->rx_ff, NULL, osal_mutex_create(&p_midi_host->rx_ff_mutex)); - tu_fifo_config_mutex(&p_midi_host->tx_ff, osal_mutex_create(&p_midi_host->tx_ff_mutex), NULL); - #endif + tu_edpt_stream_init(&p_midi_host->ep_stream.rx, true, false, false, + p_midi_host->ep_stream.rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, _midi_epbuf->rx, TUH_EPSIZE_BULK_MPS); + tu_edpt_stream_init(&p_midi_host->ep_stream.tx, true, true, false, + p_midi_host->ep_stream.tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, _midi_epbuf->tx, TUH_EPSIZE_BULK_MPS); } return true; } -bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void)result; - midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); - TU_VERIFY(p_midi_host != NULL); - if ( ep_addr == p_midi_host->ep_in) - { - if (0 == xferred_bytes) - { - return true; // No data to handle - } - - // receive new data if available - uint32_t packets_queued = 0; - if (xferred_bytes) - { - // put in the RX FIFO only non-zero MIDI IN 4-byte packets - uint8_t* buf = p_midi_host->epin_buf; - uint32_t npackets = xferred_bytes / 4; - uint32_t packet_num; - for (packet_num = 0; packet_num < npackets; packet_num++) - { - // some devices send back all zero packets even if there is no data ready - uint32_t packet = (uint32_t)((*buf)<<24) | ((uint32_t)(*(buf+1))<<16) | ((uint32_t)(*(buf+2))<<8) | ((uint32_t)(*(buf+3))); - if (packet != 0) - { - tu_fifo_write_n(&p_midi_host->rx_ff, buf, 4); - ++packets_queued; - TU_LOG3("MIDI RX=%08x\r\n", packet); - } - buf += 4; - } - } - // invoke receive callback if available - if (tuh_midi_rx_cb) - { - tuh_midi_rx_cb(dev_addr, packets_queued); - } - } - else if ( ep_addr == p_midi_host->ep_out ) - { - if (0 == write_flush(dev_addr, p_midi_host)) - { - // If there is no data left, a ZLP should be sent if - // xferred_bytes is multiple of EP size and not zero - if ( !tu_fifo_count(&p_midi_host->tx_ff) && xferred_bytes && (0 == (xferred_bytes % p_midi_host->ep_out_max)) ) - { - if ( usbh_edpt_claim(dev_addr, p_midi_host->ep_out) ) - { - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_midi_host->ep_out, XFER_RESULT_SUCCESS, 0)); - } - } - } - if (tuh_midi_tx_cb) - { - tuh_midi_tx_cb(dev_addr); - } +bool midih_deinit(void) { + for (size_t i = 0; i < CFG_TUH_MIDI; i++) { + midih_interface_t* p_midi = &_midi_host[i]; + tu_edpt_stream_deinit(&p_midi->ep_stream.rx); + tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } - return true; } @@ -221,26 +154,67 @@ void midih_close(uint8_t dev_addr) { if (tuh_midi_umount_cb) { tuh_midi_umount_cb(dev_addr, 0); } - tu_fifo_clear(&p_midi_host->rx_ff); - tu_fifo_clear(&p_midi_host->tx_ff); p_midi_host->ep_in = 0; - p_midi_host->ep_in_max = 0; p_midi_host->ep_out = 0; - p_midi_host->ep_out_max = 0; p_midi_host->itf_num = 0; p_midi_host->num_cables_rx = 0; p_midi_host->num_cables_tx = 0; - p_midi_host->dev_addr = 255; // invalid + p_midi_host->dev_addr = 0; p_midi_host->configured = false; tu_memclr(&p_midi_host->stream_read, sizeof(p_midi_host->stream_read)); tu_memclr(&p_midi_host->stream_write, sizeof(p_midi_host->stream_write)); + + tu_edpt_stream_close(&p_midi_host->ep_stream.rx); + tu_edpt_stream_close(&p_midi_host->ep_stream.tx); +} + +bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) result; + midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); + TU_VERIFY(p_midi_host != NULL); + if (ep_addr == p_midi_host->ep_stream.rx.ep_addr) { + // receive new data if available + if (xferred_bytes) { + // put in the RX FIFO only non-zero MIDI IN 4-byte packets + uint32_t packets_queued = 0; + uint8_t *buf = _midi_epbuf->rx; + const uint32_t npackets = xferred_bytes / 4; + for (uint32_t p = 0; p < npackets; p++) { + // some devices send back all zero packets even if there is no data ready + const uint32_t packet = tu_unaligned_read32(buf); + if (packet != 0) { + tu_edpt_stream_read_xfer_complete_with_buf(&p_midi_host->ep_stream.rx, buf, 4); + ++packets_queued; + TU_LOG3("MIDI RX=%08x\r\n", packet); + } + buf += 4; + } + + if (tuh_midi_rx_cb) { + tuh_midi_rx_cb(dev_addr, packets_queued); // invoke receive callback + } + } + + // prepare for next transfer if needed + tu_edpt_stream_read_xfer(dev_addr, &p_midi_host->ep_stream.rx); + } else if (ep_addr == p_midi_host->ep_stream.tx.ep_addr) { + if (tuh_midi_tx_cb) { + tuh_midi_tx_cb(dev_addr); + } + if (0 == tu_edpt_stream_write_xfer(dev_addr, &p_midi_host->ep_stream.tx)) { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP size and not zero + tu_edpt_stream_write_zlp_if_needed(dev_addr, &p_midi_host->ep_stream.tx, xferred_bytes); + } + } + + return true; } //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ -bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { (void) rhport; midih_interface_t *p_midi_host = find_new_midi(); @@ -402,20 +376,12 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d TU_VERIFY(p_midi_host->ep_out == 0); TU_VERIFY(p_midi_host->num_cables_tx == 0); p_midi_host->ep_out = p_ep->bEndpointAddress; - p_midi_host->ep_out_max = p_ep->wMaxPacketSize; - if (p_midi_host->ep_out_max > CFG_TUH_MIDI_TX_BUFSIZE) { - p_midi_host->ep_out_max = CFG_TUH_MIDI_TX_BUFSIZE; - } prev_ep_addr = p_midi_host->ep_out; out_desc = p_ep; } else { TU_VERIFY(p_midi_host->ep_in == 0); TU_VERIFY(p_midi_host->num_cables_rx == 0); p_midi_host->ep_in = p_ep->bEndpointAddress; - p_midi_host->ep_in_max = p_ep->wMaxPacketSize; - if (p_midi_host->ep_in_max > CFG_TUH_MIDI_RX_BUFSIZE) { - p_midi_host->ep_in_max = CFG_TUH_MIDI_RX_BUFSIZE; - } prev_ep_addr = p_midi_host->ep_in; in_desc = p_ep; } @@ -439,36 +405,34 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d } if (in_desc) { TU_ASSERT(tuh_edpt_open(dev_addr, in_desc)); - // Some devices always return exactly the request length so transfers won't complete - // unless you assume every transfer is the last one. - // TODO usbh_edpt_force_last_buffer(dev_addr, p_midi_host->ep_in, true); + tu_edpt_stream_open(&p_midi_host->ep_stream.rx, in_desc); } if (out_desc) { TU_ASSERT(tuh_edpt_open(dev_addr, out_desc)); + tu_edpt_stream_open(&p_midi_host->ep_stream.tx, out_desc); } p_midi_host->dev_addr = dev_addr; - if (tuh_midi_mount_cb) { - tuh_midi_mount_cb(dev_addr, p_midi_host->ep_in, p_midi_host->ep_out, p_midi_host->num_cables_rx, p_midi_host->num_cables_tx); - } return true; } -bool tuh_midi_configured(uint8_t dev_addr) -{ +bool tuh_midi_configured(uint8_t dev_addr) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); return p_midi_host->configured; } -bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) -{ +bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) { (void) itf_num; midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); p_midi_host->configured = true; - // TODO I don't think there are any special config things to do for MIDI + if (tuh_midi_mount_cb) { + tuh_midi_mount_cb(dev_addr, p_midi_host->ep_in, p_midi_host->ep_out, p_midi_host->num_cables_rx, p_midi_host->num_cables_tx); + } + + // No special config things to do for MIDI usbh_driver_set_config_complete(dev_addr, p_midi_host->itf_num); return true; } @@ -476,71 +440,32 @@ bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) //--------------------------------------------------------------------+ // Stream API //--------------------------------------------------------------------+ -static uint32_t write_flush(uint8_t dev_addr, midih_interface_t* midi) { - // No data to send - if ( !tu_fifo_count(&midi->tx_ff) ) { return 0; } - - // skip if previous transfer not complete - TU_VERIFY( usbh_edpt_claim(dev_addr, midi->ep_out) ); - - uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epout_buf, midi->ep_out_max); - - if (count) { - TU_ASSERT(usbh_edpt_xfer(dev_addr, midi->ep_out, midi->epout_buf, count), 0); - return count; - } else { - // Release endpoint since we don't make any transfer - usbh_edpt_release(dev_addr, midi->ep_out); - return 0; - } -} - bool tuh_midi_read_poll(uint8_t dev_addr) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); - bool result = false; - - bool in_edpt_not_busy = !usbh_edpt_busy(dev_addr, p_midi_host->ep_in); - if (in_edpt_not_busy) { - TU_LOG2("Requesting poll IN endpoint %d\r\n", p_midi_host->ep_in); - TU_ASSERT(usbh_edpt_xfer(p_midi_host->dev_addr, p_midi_host->ep_in, p_midi_host->epin_buf, p_midi_host->ep_in_max), 0); - result = true; - } else { - // Maybe the IN endpoint is only busy because the RP2040 host hardware - // is retrying a NAK'd IN transfer forever. Try aborting the NAK'd - // transfer to allow other transfers to happen on the one shared - // epx endpoint. - // TODO for RP2040 USB shared endpoint: usbh_edpt_clear_in_on_nak(p_midi_host->dev_addr, p_midi_host->ep_in); - } - return result; + return tu_edpt_stream_read_xfer(dev_addr, &p_midi_host->ep_stream.rx) > 0; } -uint32_t tuh_midi_stream_write (uint8_t dev_addr, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) -{ +uint32_t tuh_midi_stream_write(uint8_t dev_addr, uint8_t cable_num, uint8_t const *buffer, uint32_t bufsize) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); TU_VERIFY(cable_num < p_midi_host->num_cables_tx); midi_stream_t *stream = &p_midi_host->stream_write; uint32_t i = 0; - while ( (i < bufsize) && (tu_fifo_remaining(&p_midi_host->tx_ff) >= 4) ) - { + while ((i < bufsize) && (tu_edpt_stream_write_available(dev_addr, &p_midi_host->ep_stream.tx) >= 4)) { uint8_t const data = buffer[i]; i++; - if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) - { + if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) { // real-time messages need to be sent right away midi_stream_t streamrt; streamrt.buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; streamrt.buffer[1] = data; streamrt.index = 2; streamrt.total = 2; - uint16_t const count = tu_fifo_write_n(&p_midi_host->tx_ff, streamrt.buffer, 4); - // FIFO overflown, since we already check fifo remaining. It is probably race condition - TU_ASSERT(count == 4, i); - } - else if ( stream->index == 0 ) - { + uint32_t const count = tu_edpt_stream_write(dev_addr, &p_midi_host->ep_stream.tx, streamrt.buffer, 4); + TU_ASSERT(count == 4, i); // Check FIFO overflown, since we already check fifo remaining. It is probably race condition + } else if (stream->index == 0) { //------------- New event packet -------------// uint8_t const msg = data >> 4; @@ -549,56 +474,37 @@ uint32_t tuh_midi_stream_write (uint8_t dev_addr, uint8_t cable_num, uint8_t con stream->buffer[1] = data; // Check to see if we're still in a SysEx transmit. - if ( stream->buffer[0] == MIDI_CIN_SYSEX_START ) - { - if ( data == MIDI_STATUS_SYSEX_END ) - { + if (stream->buffer[0] == MIDI_CIN_SYSEX_START) { + if (data == MIDI_STATUS_SYSEX_END) { stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; stream->total = 2; - } - else - { + } else { stream->total = 4; } - } - else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE ) - { + } else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) { // Channel Voice Messages stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 4; - } - else if ( msg == 0xC || msg == 0xD) - { + } else if (msg == 0xC || msg == 0xD) { // Channel Voice Messages, two-byte variants (Program Change and Channel Pressure) stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 3; - } - else if ( msg == 0xf ) - { + } else if (msg == 0xf) { // System message - if ( data == MIDI_STATUS_SYSEX_START ) - { + if (data == MIDI_STATUS_SYSEX_START) { stream->buffer[0] = MIDI_CIN_SYSEX_START; stream->total = 4; - } - else if ( data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT ) - { + } else if (data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT) { stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE; stream->total = 3; - } - else if ( data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER ) - { + } else if (data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER) { stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE; stream->total = 4; - } - else - { + } else { stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; stream->total = 2; } - } - else - { + } else { // Pack individual bytes if we don't support packing them into words. stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf); stream->buffer[2] = 0; @@ -606,30 +512,25 @@ uint32_t tuh_midi_stream_write (uint8_t dev_addr, uint8_t cable_num, uint8_t con stream->index = 2; stream->total = 2; } - } - else - { + } else { //------------- On-going (buffering) packet -------------// - TU_ASSERT(stream->index < 4, i); stream->buffer[stream->index] = data; stream->index++; // See if this byte ends a SysEx. - if ( stream->buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END ) - { + if (stream->buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { stream->buffer[0] = MIDI_CIN_SYSEX_START + (stream->index - 1); stream->total = stream->index; } } // Send out packet - if ( stream->index >= 2 && stream->index == stream->total ) - { + if (stream->index >= 2 && stream->index == stream->total) { // zeroes unused bytes - for(uint8_t idx = stream->total; idx < 4; idx++) stream->buffer[idx] = 0; + for (uint8_t idx = stream->total; idx < 4; idx++) { stream->buffer[idx] = 0; } TU_LOG3_MEM(stream->buffer, 4, 2); - uint16_t const count = tu_fifo_write_n(&p_midi_host->tx_ff, stream->buffer, 4); + uint32_t const count = tu_edpt_stream_write(dev_addr, &p_midi_host->ep_stream.tx, stream->buffer, 4); // complete current event packet, reset stream stream->index = 0; @@ -642,32 +543,16 @@ uint32_t tuh_midi_stream_write (uint8_t dev_addr, uint8_t cable_num, uint8_t con return i; } -bool tuh_midi_packet_write (uint8_t dev_addr, uint8_t const packet[4]) -{ +bool tuh_midi_packet_write (uint8_t dev_addr, uint8_t const packet[4]) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); - - if (tu_fifo_remaining(&p_midi_host->tx_ff) < 4) - { - return false; - } - - tu_fifo_write_n(&p_midi_host->tx_ff, packet, 4); - - return true; + return 4 == tu_edpt_stream_write(dev_addr, &p_midi_host->ep_stream.tx, packet, 4); } -uint32_t tuh_midi_stream_flush( uint8_t dev_addr ) -{ - midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); - TU_VERIFY(p_midi_host != NULL); - - uint32_t bytes_flushed = 0; - if (!usbh_edpt_busy(p_midi_host->dev_addr, p_midi_host->ep_out)) - { - bytes_flushed = write_flush(dev_addr, p_midi_host); - } - return bytes_flushed; +uint32_t tuh_midi_stream_flush(uint8_t dev_addr) { + midih_interface_t *p_midi = find_midi_by_daddr(dev_addr); + TU_VERIFY(p_midi != NULL); + return tu_edpt_stream_write_xfer(p_midi->dev_addr, &p_midi->ep_stream.tx); } //--------------------------------------------------------------------+ // Helper @@ -692,12 +577,11 @@ bool tuh_midi_packet_read (uint8_t dev_addr, uint8_t packet[4]) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); - TU_VERIFY(tu_fifo_count(&p_midi_host->rx_ff) >= 4); - return tu_fifo_read_n(&p_midi_host->rx_ff, packet, 4) == 4; + TU_VERIFY(tu_edpt_stream_read_available(&p_midi_host->ep_stream.rx) >= 4); + return 4 == tu_edpt_stream_read(dev_addr, &p_midi_host->ep_stream.rx, packet, 4); } -uint32_t tuh_midi_stream_read (uint8_t dev_addr, uint8_t *p_cable_num, uint8_t *p_buffer, uint16_t bufsize) -{ +uint32_t tuh_midi_stream_read(uint8_t dev_addr, uint8_t *p_cable_num, uint8_t *p_buffer, uint16_t bufsize) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); uint32_t bytes_buffered = 0; @@ -705,54 +589,40 @@ uint32_t tuh_midi_stream_read (uint8_t dev_addr, uint8_t *p_cable_num, uint8_t * TU_ASSERT(p_buffer); TU_ASSERT(bufsize); uint8_t one_byte; - if (!tu_fifo_peek(&p_midi_host->rx_ff, &one_byte)) - { + if (!tu_edpt_stream_peek(&p_midi_host->ep_stream.rx, &one_byte)) { return 0; } *p_cable_num = (one_byte >> 4) & 0xf; - uint32_t nread = tu_fifo_read_n(&p_midi_host->rx_ff, p_midi_host->stream_read.buffer, 4); + uint32_t nread = tu_edpt_stream_read(dev_addr, &p_midi_host->ep_stream.rx, p_midi_host->stream_read.buffer, 4); static uint16_t cable_sysex_in_progress; // bit i is set if received MIDI_STATUS_SYSEX_START but not MIDI_STATUS_SYSEX_END - while (nread == 4 && bytes_buffered < bufsize) - { - *p_cable_num=(p_midi_host->stream_read.buffer[0] >> 4) & 0x0f; + while (nread == 4 && bytes_buffered < bufsize) { + *p_cable_num = (p_midi_host->stream_read.buffer[0] >> 4) & 0x0f; uint8_t bytes_to_add_to_stream = 0; - if (*p_cable_num < p_midi_host->num_cables_rx) - { + if (*p_cable_num < p_midi_host->num_cables_rx) { // ignore the CIN field; too many devices out there encode this wrong uint8_t status = p_midi_host->stream_read.buffer[1]; uint16_t cable_mask = (uint16_t) (1 << *p_cable_num); - if (status <= MIDI_MAX_DATA_VAL || status == MIDI_STATUS_SYSEX_START) - { - if (status == MIDI_STATUS_SYSEX_START) - { + if (status <= MIDI_MAX_DATA_VAL || status == MIDI_STATUS_SYSEX_START) { + if (status == MIDI_STATUS_SYSEX_START) { cable_sysex_in_progress |= cable_mask; } // only add the packet if a sysex message is in progress - if (cable_sysex_in_progress & cable_mask) - { + if (cable_sysex_in_progress & cable_mask) { ++bytes_to_add_to_stream; - uint8_t idx; - for (idx = 2; idx < 4; idx++) - { - if (p_midi_host->stream_read.buffer[idx] <= MIDI_MAX_DATA_VAL) - { + for (uint8_t idx = 2; idx < 4; idx++) { + if (p_midi_host->stream_read.buffer[idx] <= MIDI_MAX_DATA_VAL) { ++bytes_to_add_to_stream; - } - else if (p_midi_host->stream_read.buffer[idx] == MIDI_STATUS_SYSEX_END) - { + } else if (p_midi_host->stream_read.buffer[idx] == MIDI_STATUS_SYSEX_END) { ++bytes_to_add_to_stream; cable_sysex_in_progress &= (uint16_t) ~cable_mask; - idx = 4; // force the loop to exit; I hate break statements in loops + idx = 4;// force the loop to exit; I hate break statements in loops } } } - } - else if (status < MIDI_STATUS_SYSEX_START) - { + } else if (status < MIDI_STATUS_SYSEX_START) { // then it is a channel message either three bytes or two uint8_t fake_cin = (status & 0xf0) >> 4; - switch (fake_cin) - { + switch (fake_cin) { case MIDI_CIN_NOTE_OFF: case MIDI_CIN_NOTE_ON: case MIDI_CIN_POLY_KEYPRESS: @@ -765,14 +635,11 @@ uint32_t tuh_midi_stream_read (uint8_t dev_addr, uint8_t *p_cable_num, uint8_t * bytes_to_add_to_stream = 2; break; default: - break; // Should not get this + break;// Should not get this } - cable_sysex_in_progress &= (uint16_t)~cable_mask; - } - else if (status < MIDI_STATUS_SYSREAL_TIMING_CLOCK) - { - switch (status) - { + cable_sysex_in_progress &= (uint16_t) ~cable_mask; + } else if (status < MIDI_STATUS_SYSREAL_TIMING_CLOCK) { + switch (status) { case MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME: case MIDI_STATUS_SYSCOM_SONG_SELECT: bytes_to_add_to_stream = 2; @@ -786,30 +653,24 @@ uint32_t tuh_midi_stream_read (uint8_t dev_addr, uint8_t *p_cable_num, uint8_t * break; default: break; - cable_sysex_in_progress &= (uint16_t)~cable_mask; + cable_sysex_in_progress &= (uint16_t) ~cable_mask; } - } - else - { + } else { // Real-time message: can be inserted into a sysex message, // so do don't clear cable_sysex_in_progress bit bytes_to_add_to_stream = 1; } } - uint8_t idx; - for (idx = 1; idx <= bytes_to_add_to_stream; idx++) - { + for (uint8_t idx = 1; idx <= bytes_to_add_to_stream; idx++) { *p_buffer++ = p_midi_host->stream_read.buffer[idx]; } bytes_buffered += bytes_to_add_to_stream; nread = 0; - if (tu_fifo_peek(&p_midi_host->rx_ff, &one_byte)) - { + if (tu_edpt_stream_peek(&p_midi_host->ep_stream.rx, &one_byte)) { uint8_t new_cable = (one_byte >> 4) & 0xf; - if (new_cable == *p_cable_num) - { + if (new_cable == *p_cable_num) { // still on the same cable. Continue reading the stream - nread = tu_fifo_read_n(&p_midi_host->rx_ff, p_midi_host->stream_read.buffer, 4); + nread = tu_edpt_stream_read(dev_addr, &p_midi_host->ep_stream.rx, p_midi_host->stream_read.buffer, 4); } } } @@ -865,19 +726,14 @@ static uint8_t find_string_index(midih_interface_t *ptr, uint8_t jack_id) #endif #if CFG_MIDI_HOST_DEVSTRINGS -uint8_t tuh_midi_get_rx_cable_istrings(uint8_t dev_addr, uint8_t* istrings, uint8_t max_istrings) -{ - uint8_t nstrings = 0; +uint8_t tuh_midi_get_rx_cable_istrings(uint8_t dev_addr, uint8_t* istrings, uint8_t max_istrings) { midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); - TU_VERIFY(p_midi_host != NULL); - nstrings = p_midi_host->num_cables_rx; - if (nstrings > max_istrings) - { - nstrings = max_istrings; + TU_VERIFY(p_midi_host != NULL, 0); + uint8_t nstrings = p_midi_host->num_cables_rx; + if (nstrings > max_istrings) { + nstrings = max_istrings; } - uint8_t jack; - for (jack=0; jackep_in_associated_jacks[jack]; istrings[jack] = find_string_index(p_midi_host, jack_id); } @@ -886,17 +742,13 @@ uint8_t tuh_midi_get_rx_cable_istrings(uint8_t dev_addr, uint8_t* istrings, uint uint8_t tuh_midi_get_tx_cable_istrings(uint8_t dev_addr, uint8_t* istrings, uint8_t max_istrings) { - uint8_t nstrings = 0; midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); - TU_VERIFY(p_midi_host != NULL); - nstrings = p_midi_host->num_cables_tx; - if (nstrings > max_istrings) - { - nstrings = max_istrings; + TU_VERIFY(p_midi_host != NULL, 0); + uint8_t nstrings = p_midi_host->num_cables_tx; + if (nstrings > max_istrings) { + nstrings = max_istrings; } - uint8_t jack; - for (jack=0; jackep_out_associated_jacks[jack]; istrings[jack] = find_string_index(p_midi_host, jack_id); } @@ -909,8 +761,7 @@ uint8_t tuh_midi_get_all_istrings(uint8_t dev_addr, const uint8_t** istrings) midih_interface_t *p_midi_host = find_midi_by_daddr(dev_addr); TU_VERIFY(p_midi_host != NULL); uint8_t nstrings = p_midi_host->num_string_indices; - if (nstrings) - *istrings = p_midi_host->all_string_indices; + if (nstrings) { *istrings = p_midi_host->all_string_indices; } return nstrings; } #endif diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index bf2378168..6401eb0c3 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -42,15 +42,15 @@ #endif #ifndef CFG_TUH_MIDI_RX_BUFSIZE -#define CFG_TUH_MIDI_RX_BUFSIZE 64 +#define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE -#define CFG_TUH_MIDI_TX_BUFSIZE 64 +#define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE -#define CFG_TUH_MIDI_EP_BUFSIZE 64 +#define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS #endif #ifndef CFG_MIDI_HOST_DEVSTRINGS @@ -113,14 +113,6 @@ uint8_t tuh_midi_get_rx_cable_istrings(uint8_t dev_addr, uint8_t* istrings, uint uint8_t tuh_midi_get_tx_cable_istrings(uint8_t dev_addr, uint8_t* istrings, uint8_t max_istrings); uint8_t tuh_midi_get_all_istrings(uint8_t dev_addr, const uint8_t** istrings); #endif -//--------------------------------------------------------------------+ -// Internal Class Driver API -//--------------------------------------------------------------------+ -bool midih_init (void); -bool midih_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); -bool midih_set_config (uint8_t dev_addr, uint8_t itf_num); -bool midih_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -void midih_close (uint8_t dev_addr); //--------------------------------------------------------------------+ // Callbacks (Weak is optional) @@ -138,6 +130,17 @@ TU_ATTR_WEAK void tuh_midi_umount_cb(uint8_t dev_addr, uint8_t instance); TU_ATTR_WEAK void tuh_midi_rx_cb(uint8_t dev_addr, uint32_t num_packets); TU_ATTR_WEAK void tuh_midi_tx_cb(uint8_t dev_addr); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +bool midih_init (void); +bool midih_deinit (void); +bool midih_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); +bool midih_set_config (uint8_t dev_addr, uint8_t itf_num); +bool midih_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void midih_close (uint8_t dev_addr); + #ifdef __cplusplus } #endif diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index c71775abb..445882243 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -138,7 +138,7 @@ uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, ui // Start an usb transfer if endpoint is not busy uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); -// Must be called in the transfer complete callback +// Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) { if (tu_fifo_depth(&s->ff)) { @@ -146,11 +146,11 @@ void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_byt } } -// Same as tu_edpt_stream_read_xfer_complete but skip the first n bytes +// Complete read transfer with provided buffer TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_read_xfer_complete_offset(tu_edpt_stream_t* s, uint32_t xferred_bytes, uint32_t skip_offset) { - if (tu_fifo_depth(&s->ff) && (skip_offset < xferred_bytes)) { - tu_fifo_write_n(&s->ff, s->ep_buf + skip_offset, (uint16_t) (xferred_bytes - skip_offset)); +void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t* s, const void * buf, uint32_t xferred_bytes) { + if (tu_fifo_depth(&s->ff)) { + tu_fifo_write_n(&s->ff, buf, (uint16_t) xferred_bytes); } } diff --git a/src/host/usbh.c b/src/host/usbh.c index f874121a3..e6b6cd91c 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -192,6 +192,7 @@ static usbh_class_driver_t const usbh_class_drivers[] = { { .name = DRIVER_NAME("MIDI"), .init = midih_init, + .deinit = midih_deinit, .open = midih_open, .set_config = midih_set_config, .xfer_cb = midih_xfer_cb, @@ -1672,7 +1673,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur if ( 0 == tu_desc_len(p_desc) ) { // A zero length descriptor indicates that the device is off spec (e.g. wrong wTotalLength). // Parsed interfaces should still be usable - TU_LOG_USBH("Encountered a zero-length descriptor after %u bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg); + TU_LOG_USBH("Encountered a zero-length descriptor after %" PRIu32 " bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg); break; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 3bcdd3657..7fc8ea826 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -37,6 +37,9 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +// Endpoint Bulk size depending on host mx speed +#define TUH_EPSIZE_BULK_MPS (TUD_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) + // forward declaration struct tuh_xfer_s; typedef struct tuh_xfer_s tuh_xfer_t; -- cgit v1.3.1