From 78121a8d3f273420f8a2798364c2dd2fb9bb700f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Sep 2025 14:58:08 +0200 Subject: Update UAC2 naming Signed-off-by: HiFiPhile --- src/class/midi/midi_host.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index e6ace316c..46b8284ee 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -93,6 +93,8 @@ typedef struct { static midih_interface_t _midi_host[CFG_TUH_MIDI]; CFG_TUH_MEM_SECTION static midih_epbuf_t _midi_epbuf[CFG_TUH_MIDI]; +typedef audio10_desc_cs_ac_interface_n_t(1) midi10_desc_cs_ac_interface_t; + //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ @@ -220,7 +222,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d // driver after parsing the audio control interface and then resume parsing // the streaming audio interface. if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) { - TU_VERIFY(max_len > 2*sizeof(tusb_desc_interface_t) + sizeof(audio_desc_cs_ac_interface_t)); + TU_VERIFY(max_len > 2*sizeof(tusb_desc_interface_t) + sizeof(midi10_desc_cs_ac_interface_t)); p_desc = tu_desc_next(p_desc); TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && -- cgit v1.3.1 From 9637a2006bdfa77911cd274f0b9cff7de7ae54e9 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Sep 2025 17:17:10 +0200 Subject: More descriptors working Signed-off-by: HiFiPhile --- .../device/audio_4_channel_mic/src/tusb_config.h | 2 +- .../audio_4_channel_mic/src/usb_descriptors.c | 4 +- .../audio_4_channel_mic_freertos/src/tusb_config.h | 2 +- .../src/usb_descriptors.c | 4 +- examples/device/audio_test/src/tusb_config.h | 2 +- examples/device/audio_test/src/usb_descriptors.c | 4 +- .../device/audio_test_freertos/src/tusb_config.h | 2 +- .../audio_test_freertos/src/usb_descriptors.c | 4 +- .../device/audio_test_multi_rate/src/tusb_config.h | 2 +- .../audio_test_multi_rate/src/usb_descriptors.c | 4 +- .../audio_test_multi_rate/src/usb_descriptors.h | 74 +- examples/device/cdc_uac2/src/usb_descriptors.h | 124 +- examples/device/uac2_headset/src/main.c | 8 +- examples/device/uac2_headset/src/usb_descriptors.h | 128 +- examples/device/uac2_speaker_fb/src/tusb_config.h | 2 +- .../device/uac2_speaker_fb/src/usb_descriptors.c | 8 +- .../device/uac2_speaker_fb/src/usb_descriptors.h | 111 +- src/class/audio/audio.h | 1837 ++++++++++---------- src/class/audio/audio_device.c | 4 +- src/class/midi/midi_host.c | 4 +- src/common/tusb_common.h | 7 + src/common/tusb_compiler.h | 12 + src/device/usbd.h | 397 +++-- 23 files changed, 1439 insertions(+), 1307 deletions(-) (limited to 'src/class/midi') diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index 0ee3ba2d0..718486941 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -105,7 +105,7 @@ extern "C" { // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 diff --git a/examples/device/audio_4_channel_mic/src/usb_descriptors.c b/examples/device/audio_4_channel_mic/src/usb_descriptors.c index 728a5f9ce..4caa4343b 100644 --- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c @@ -80,7 +80,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN) #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number @@ -101,7 +101,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) + TUD_AUDIO20_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h index d973be2af..7a9a40c49 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h @@ -111,7 +111,7 @@ extern "C" { // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c index 728a5f9ce..4caa4343b 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c @@ -80,7 +80,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN) #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number @@ -101,7 +101,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) + TUD_AUDIO20_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 10bf53809..8a63cc521 100644 --- a/examples/device/audio_test/src/tusb_config.h +++ b/examples/device/audio_test/src/tusb_config.h @@ -108,7 +108,7 @@ extern "C" { // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO20_MIC_ONE_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c index 9864377f6..af9b7f1dc 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -80,7 +80,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_ONE_CH_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number @@ -101,7 +101,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) + TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h index c9dc50082..21b6a6f76 100644 --- a/examples/device/audio_test_freertos/src/tusb_config.h +++ b/examples/device/audio_test_freertos/src/tusb_config.h @@ -114,7 +114,7 @@ extern "C" { // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO20_MIC_ONE_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c index 9864377f6..af9b7f1dc 100644 --- a/examples/device/audio_test_freertos/src/usb_descriptors.c +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -80,7 +80,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_ONE_CH_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number @@ -101,7 +101,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) + TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/audio_test_multi_rate/src/tusb_config.h b/examples/device/audio_test_multi_rate/src/tusb_config.h index b48c0a0be..e92d20c49 100644 --- a/examples/device/audio_test_multi_rate/src/tusb_config.h +++ b/examples/device/audio_test_multi_rate/src/tusb_config.h @@ -122,7 +122,7 @@ extern "C" { // Have a look into audio_device.h for all configurations -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_2_FORMAT_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 diff --git a/examples/device/audio_test_multi_rate/src/usb_descriptors.c b/examples/device/audio_test_multi_rate/src/usb_descriptors.c index f50e70a25..afdf95b79 100644 --- a/examples/device/audio_test_multi_rate/src/usb_descriptors.c +++ b/examples/device/audio_test_multi_rate/src/usb_descriptors.c @@ -82,7 +82,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_2_FORMAT_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number @@ -103,7 +103,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_ONE_CH_2_FORMAT_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_epin*/ 0x80 | EPNUM_AUDIO) + TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_epin*/ 0x80 | EPNUM_AUDIO) }; TU_VERIFY_STATIC(sizeof(desc_configuration) == CONFIG_TOTAL_LEN, "Incorrect size"); diff --git a/examples/device/audio_test_multi_rate/src/usb_descriptors.h b/examples/device/audio_test_multi_rate/src/usb_descriptors.h index 277b22d7b..adf3305d2 100644 --- a/examples/device/audio_test_multi_rate/src/usb_descriptors.h +++ b/examples/device/audio_test_multi_rate/src/usb_descriptors.h @@ -35,68 +35,68 @@ #define UAC2_ENTITY_FEATURE_UNIT 0x02 -#define TUD_AUDIO_MIC_ONE_CH_2_FORMAT_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN\ +#define TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1)\ /* Interface 1, Alternate 0 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 1, Alternate 1 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 1, Alternate 2 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) -#define TUD_AUDIO_MIC_ONE_CH_2_FORMAT_DESCRIPTOR(_itfnum, _stridx, _epin) \ +#define TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESCRIPTOR(_itfnum, _stridx, _epin) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS | AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS, /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS | AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS, /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC2_ENTITY_INPUT_TERMINAL, /*_srcid*/ UAC2_ENTITY_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC2_ENTITY_INPUT_TERMINAL, /*_srcid*/ UAC2_ENTITY_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ UAC2_ENTITY_FEATURE_UNIT, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ UAC2_ENTITY_FEATURE_UNIT, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN, /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) #endif diff --git a/examples/device/cdc_uac2/src/usb_descriptors.h b/examples/device/cdc_uac2/src/usb_descriptors.h index efffbc0bb..afb74d5b5 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.h +++ b/examples/device/cdc_uac2/src/usb_descriptors.h @@ -49,110 +49,110 @@ enum ITF_NUM_TOTAL }; -#define TUD_AUDIO_HEADSET_STEREO_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ +#define TUD_AUDIO_HEADSET_STEREO_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 1, Alternate 0 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 1, Alternate 2 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 0 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 2, Alternate 1 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 2 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ 3, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ 3, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS)),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 2, Alternate 2 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) #endif diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 602225df5..6cfab946b 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -387,14 +387,14 @@ void audio_control_task(void) { } // 6.1 Interrupt Data Message - const audio20_interrupt_data_t data = { + const audio_interrupt_data_t data = {.v2 = { .bInfo = 0, // Class-specific interrupt, originated from an interface - .bAttribute = AUDIO20_CS_REQ_CUR, // Caused by current settings + .bAttribute = AUDIO20_CS_REQ_CUR, // Caused by current settings .wValue_cn_or_mcn = 0, // CH0: master volume - .wValue_cs = AUDIO20_FU_CTRL_VOLUME, // Volume change + .wValue_cs = AUDIO20_FU_CTRL_VOLUME, // Volume change .wIndex_ep_or_int = 0, // From the interface itself .wIndex_entity_id = UAC2_ENTITY_SPK_FEATURE_UNIT,// From feature unit - }; + }}; tud_audio_int_write(&data); } diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index 4138b5654..68d15a857 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -46,113 +46,113 @@ enum ITF_NUM_TOTAL }; -#define TUD_AUDIO_HEADSET_STEREO_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_STD_AC_INT_EP_LEN\ +#define TUD_AUDIO_HEADSET_STEREO_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_STD_AC_INT_EP_LEN\ /* Interface 1, Alternate 0 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 1, Alternate 1 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 1, Alternate 2 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 0 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 2, Alternate 1 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 2 */\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin, _epint) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitf*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS)),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */\ - TUD_AUDIO_DESC_STD_AC_INT_EP(/*_ep*/ _epint, /*_interval*/ 0x01), \ + TUD_AUDIO20_DESC_STD_AC_INT_EP(/*_ep*/ _epint, /*_interval*/ 0x01), \ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 2, Alternate 2 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) #endif diff --git a/examples/device/uac2_speaker_fb/src/tusb_config.h b/examples/device/uac2_speaker_fb/src/tusb_config.h index 18ab2ff96..284feff55 100644 --- a/examples/device/uac2_speaker_fb/src/tusb_config.h +++ b/examples/device/uac2_speaker_fb/src/tusb_config.h @@ -128,7 +128,7 @@ extern "C" { // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN // Can be enabled with Full-Speed device on OSX, which forces feedback EP size to 3, in this case CFG_QUIRK_OS_GUESSING can be disabled #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c index ee1b92225..9e12c88b4 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -113,9 +113,9 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) //--------------------------------------------------------------------+ #if CFG_AUDIO_DEBUG - #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN + TUD_HID_DESC_LEN) + #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN + TUD_HID_DESC_LEN) #else - #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN) + #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN) #endif #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX @@ -150,7 +150,7 @@ uint8_t const desc_configuration_default[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size, - TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 4), + TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 4), #if CFG_AUDIO_DEBUG // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval @@ -166,7 +166,7 @@ uint8_t const desc_configuration_osx_fs[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size, - TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 3), + TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 3), #if CFG_AUDIO_DEBUG // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.h b/examples/device/uac2_speaker_fb/src/usb_descriptors.h index 005aebeef..f71411dcf 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.h +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.h @@ -26,57 +26,108 @@ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ -// Defined in TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR +// Defined in TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR #define UAC2_ENTITY_CLOCK 0x04 #define UAC2_ENTITY_INPUT_TERMINAL 0x01 #define UAC2_ENTITY_FEATURE_UNIT 0x02 #define UAC2_ENTITY_OUTPUT_TERMINAL 0x03 -#define TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN) +#define TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN) -#define TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ +#define TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO20_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS,/*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1)\ + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1) + +//--------------------------------------------------------------------+ +// UAC1 DESCRIPTOR TEMPLATES +//--------------------------------------------------------------------+ + +// Defined in TUD_AUDIO10_SPEAKER_STEREO_FB_DESCRIPTOR +#define UAC1_ENTITY_INPUT_TERMINAL 0x01 +#define UAC1_ENTITY_FEATURE_UNIT 0x02 +#define UAC1_ENTITY_OUTPUT_TERMINAL 0x03 + +#define TUD_AUDIO10_SPEAKER_STEREO_FB_DESC_LEN(_nfreqs) (\ + + TUD_AUDIO_DESC_STD_AC_LEN\ + + TUD_AUDIO10_DESC_CS_AC_LEN(1)\ + + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO10_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs)\ + + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP_LEN) + +#define TUD_AUDIO10_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, ...) \ + /* Standard AC Interface Descriptor(4.3.1) */\ + TUD_AUDIO10_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Class-Specific AC Interface Header Descriptor(4.3.2) */\ + TUD_AUDIO10_DESC_CS_AC(/*_bcdADC*/ 0x0100, /*_totallen*/ (TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)), /*_itf*/ ((_itfnum)+1)),\ + /* Input Terminal Descriptor(4.3.2.1) */\ + TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_nchannels*/ 0x02, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_LEFT_FRONT | AUDIO10_CHANNEL_CONFIG_RIGHT_FRONT, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ + /* Output Terminal Descriptor(4.3.2.2) */\ + TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x00, /*_srcid*/ 0x02, /*_stridx*/ 0x00),\ + /* Feature Unit Descriptor(4.3.2.5) */\ + TUD_AUDIO10_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlmaster*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch1*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch2*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME)),\ + /* Standard AS Interface Descriptor(4.5.1) */\ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.5.1) */\ + /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ + /* Class-Specific AS Interface Descriptor(4.5.2) */\ + TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_delay*/ 0x00, /*_formattype*/ AUDIO10_DATA_FORMAT_TYPE_I_PCM),\ + /* Type I Format Type Descriptor(2.2.5) */\ + TUD_AUDIO10_DESC_TYPE_I_FORMAT(/*_nrchannels*/ 0x02, /*_subframesize*/ _nBytesPerSample, /*_bitresolution*/ _nBitsUsedPerSample, /*_freqs*/ __VA_ARGS__),\ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.6.1.1) */\ + TUD_AUDIO10_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01, /*_sync_ep*/ _epfb),\ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.6.1.2) */\ + TUD_AUDIO10_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ, /*_lockdelayunits*/ AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + /* Standard AS Isochronous Synch Endpoint Descriptor (4.6.2.1) */\ + TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP(/*_ep*/ _epfb, /*_bRefresh*/ 4) #endif diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 7c4c85306..ecc7b9427 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -44,425 +44,472 @@ extern "C" { //--------------------------------------------------------------------+ /// A.2 - Audio Function Subclass Codes -typedef enum -{ +typedef enum { AUDIO_FUNCTION_SUBCLASS_UNDEFINED = 0x00, } audio_function_subclass_type_t; /// A.3 - Audio Function Protocol Codes -typedef enum -{ - AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00, - AUDIO_FUNC_PROTOCOL_CODE_V1 = 0x00, ///< Version 1.0 - same as undefined for backward compatibility - AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0 +typedef enum { + AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00, + AUDIO_FUNC_PROTOCOL_CODE_V1 = 0x00,///< Version 1.0 - same as undefined for backward compatibility + AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20,///< Version 2.0 } audio_function_protocol_code_t; /// A.5 - Audio Interface Subclass Codes -typedef enum -{ +typedef enum { AUDIO_SUBCLASS_UNDEFINED = 0x00, - AUDIO_SUBCLASS_CONTROL , ///< Audio Control - AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming - AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming + AUDIO_SUBCLASS_CONTROL, ///< Audio Control + AUDIO_SUBCLASS_STREAMING, ///< Audio Streaming + AUDIO_SUBCLASS_MIDI_STREAMING,///< MIDI Streaming } audio_subclass_type_t; /// A.6 - Audio Interface Protocol Codes -typedef enum -{ - AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00, - AUDIO_INT_PROTOCOL_CODE_V1 = 0x00, ///< Version 1.0 - same as undefined for backward compatibility - AUDIO_INT_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0 +typedef enum { + AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00, + AUDIO_INT_PROTOCOL_CODE_V1 = 0x00,///< Version 1.0 - same as undefined for backward compatibility + AUDIO_INT_PROTOCOL_CODE_V2 = 0x20,///< Version 2.0 } audio_interface_protocol_code_t; +/// Terminal Types + +/// 2.1 - Audio Class-Terminal Types +typedef enum { + AUDIO_TERM_TYPE_USB_UNDEFINED = 0x0100, + AUDIO_TERM_TYPE_USB_STREAMING = 0x0101, + AUDIO_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF, +} audio_terminal_type_t; + +/// 2.2 - Audio Class-Input Terminal Types +typedef enum { + AUDIO_TERM_TYPE_IN_UNDEFINED = 0x0200, + AUDIO_TERM_TYPE_IN_GENERIC_MIC = 0x0201, + AUDIO_TERM_TYPE_IN_DESKTOP_MIC = 0x0202, + AUDIO_TERM_TYPE_IN_PERSONAL_MIC = 0x0203, + AUDIO_TERM_TYPE_IN_OMNI_MIC = 0x0204, + AUDIO_TERM_TYPE_IN_ARRAY_MIC = 0x0205, + AUDIO_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206, +} audio_terminal_input_type_t; + +/// 2.3 - Audio Class-Output Terminal Types +typedef enum { + AUDIO_TERM_TYPE_OUT_UNDEFINED = 0x0300, + AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301, + AUDIO_TERM_TYPE_OUT_HEADPHONES = 0x0302, + AUDIO_TERM_TYPE_OUT_HEAD_MNT_DISP_AUIDO = 0x0303, + AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER = 0x0304, + AUDIO_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305, + AUDIO_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306, + AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307, +} audio_terminal_output_type_t; + +/// Rest is yet to be implemented + //--------------------------------------------------------------------+ // USB AUDIO CLASS 1.0 (UAC1) DEFINITIONS //--------------------------------------------------------------------+ -/// A.4 - Audio Class-Specific AC Interface Descriptor Subtypes UAC1 -typedef enum -{ +/// A.5 - Audio Class-Specific AC Interface Descriptor Subtypes UAC1 +typedef enum { AUDIO10_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, - AUDIO10_CS_AC_INTERFACE_HEADER = 0x01, - AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, - AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, - AUDIO10_CS_AC_INTERFACE_MIXER_UNIT = 0x04, - AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, - AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, - AUDIO10_CS_AC_INTERFACE_PROCESSING_UNIT = 0x07, - AUDIO10_CS_AC_INTERFACE_EXTENSION_UNIT = 0x08, + AUDIO10_CS_AC_INTERFACE_HEADER = 0x01, + AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, + AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, + AUDIO10_CS_AC_INTERFACE_MIXER_UNIT = 0x04, + AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, + AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, + AUDIO10_CS_AC_INTERFACE_PROCESSING_UNIT = 0x07, + AUDIO10_CS_AC_INTERFACE_EXTENSION_UNIT = 0x08, } audio10_cs_ac_interface_subtype_t; -/// A.5 - Audio Class-Specific AS Interface Descriptor Subtypes UAC1 -typedef enum -{ +/// A.6 - Audio Class-Specific AS Interface Descriptor Subtypes UAC1 +typedef enum { AUDIO10_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, - AUDIO10_CS_AS_INTERFACE_AS_GENERAL = 0x01, - AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, + AUDIO10_CS_AS_INTERFACE_AS_GENERAL = 0x01, + AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, } audio10_cs_as_interface_subtype_t; -/// A.6 - Audio Class-Specific EP Descriptor Subtypes UAC1 -typedef enum -{ - AUDIO10_CS_EP_SUBTYPE_UNDEF = 0x00, - AUDIO10_CS_EP_SUBTYPE_GENERAL = 0x01, +/// A.8 - Audio Class-Specific EP Descriptor Subtypes UAC1 +typedef enum { + AUDIO10_CS_EP_SUBTYPE_UNDEF = 0x00, + AUDIO10_CS_EP_SUBTYPE_GENERAL = 0x01, } audio10_cs_ep_subtype_t; -/// A.7 - Audio Class-Specific Request Codes UAC1 -typedef enum -{ - AUDIO10_CS_REQ_UNDEF = 0x00, - AUDIO10_CS_REQ_SET_CUR = 0x01, - AUDIO10_CS_REQ_GET_CUR = 0x81, - AUDIO10_CS_REQ_SET_MIN = 0x02, - AUDIO10_CS_REQ_GET_MIN = 0x82, - AUDIO10_CS_REQ_SET_MAX = 0x03, - AUDIO10_CS_REQ_GET_MAX = 0x83, - AUDIO10_CS_REQ_SET_RES = 0x04, - AUDIO10_CS_REQ_GET_RES = 0x84, - AUDIO10_CS_REQ_SET_MEM = 0x05, - AUDIO10_CS_REQ_GET_MEM = 0x85, - AUDIO10_CS_REQ_GET_STAT = 0xFF, +/// A.9 - Audio Class-Specific Request Codes UAC1 +typedef enum { + AUDIO10_CS_REQ_UNDEF = 0x00, + AUDIO10_CS_REQ_SET_CUR = 0x01, + AUDIO10_CS_REQ_GET_CUR = 0x81, + AUDIO10_CS_REQ_SET_MIN = 0x02, + AUDIO10_CS_REQ_GET_MIN = 0x82, + AUDIO10_CS_REQ_SET_MAX = 0x03, + AUDIO10_CS_REQ_GET_MAX = 0x83, + AUDIO10_CS_REQ_SET_RES = 0x04, + AUDIO10_CS_REQ_GET_RES = 0x84, + AUDIO10_CS_REQ_SET_MEM = 0x05, + AUDIO10_CS_REQ_GET_MEM = 0x85, + AUDIO10_CS_REQ_GET_STAT = 0xFF, } audio10_cs_req_t; -/// A.9.1 - Terminal Control Selectors UAC1 -typedef enum -{ - AUDIO10_TE_CTRL_UNDEF = 0x00, - AUDIO10_TE_CTRL_COPY_PROTECT = 0x01, +/// A.10.1 - Terminal Control Selectors UAC1 +typedef enum { + AUDIO10_TE_CTRL_UNDEF = 0x00, + AUDIO10_TE_CTRL_COPY_PROTECT = 0x01, } audio10_terminal_control_selector_t; -/// A.9.2 - Feature Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_FU_CTRL_UNDEF = 0x00, - AUDIO10_FU_CTRL_MUTE = 0x01, - AUDIO10_FU_CTRL_VOLUME = 0x02, - AUDIO10_FU_CTRL_BASS = 0x03, - AUDIO10_FU_CTRL_MID = 0x04, - AUDIO10_FU_CTRL_TREBLE = 0x05, - AUDIO10_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, - AUDIO10_FU_CTRL_AGC = 0x07, - AUDIO10_FU_CTRL_DELAY = 0x08, - AUDIO10_FU_CTRL_BASS_BOOST = 0x09, - AUDIO10_FU_CTRL_LOUDNESS = 0x0A, +/// A.10.2 - Feature Unit Control Selectors UAC1 +typedef enum { + AUDIO10_FU_CTRL_UNDEF = 0x00, + AUDIO10_FU_CTRL_MUTE = 0x01, + AUDIO10_FU_CTRL_VOLUME = 0x02, + AUDIO10_FU_CTRL_BASS = 0x03, + AUDIO10_FU_CTRL_MID = 0x04, + AUDIO10_FU_CTRL_TREBLE = 0x05, + AUDIO10_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, + AUDIO10_FU_CTRL_AGC = 0x07, + AUDIO10_FU_CTRL_DELAY = 0x08, + AUDIO10_FU_CTRL_BASS_BOOST = 0x09, + AUDIO10_FU_CTRL_LOUDNESS = 0x0A, } audio10_feature_unit_control_selector_t; -/// A.9.3 - Up/Down-mix Processing Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_UD_CTRL_UNDEF = 0x00, - AUDIO10_UD_CTRL_ENABLE = 0x01, - AUDIO10_UD_CTRL_MODE_SELECT = 0x02, +/// A.10.3.1 - Up/Down-mix Processing Unit Control Selectors UAC1 +typedef enum { + AUDIO10_UD_CTRL_UNDEF = 0x00, + AUDIO10_UD_CTRL_ENABLE = 0x01, + AUDIO10_UD_CTRL_MODE_SELECT = 0x02, } audio10_up_down_mix_control_selector_t; -/// A.9.4 - Dolby Prologic Processing Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_DP_CTRL_UNDEF = 0x00, - AUDIO10_DP_CTRL_ENABLE = 0x01, - AUDIO10_DP_CTRL_MODE_SELECT = 0x02, +/// A.10.3.2 - Dolby Prologic Processing Unit Control Selectors UAC1 +typedef enum { + AUDIO10_DP_CTRL_UNDEF = 0x00, + AUDIO10_DP_CTRL_ENABLE = 0x01, + AUDIO10_DP_CTRL_MODE_SELECT = 0x02, } audio10_dolby_prologic_control_selector_t; -/// A.9.5 - 3D Stereo Extender Processing Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_3D_CTRL_UNDEF = 0x00, - AUDIO10_3D_CTRL_ENABLE = 0x01, - AUDIO10_3D_CTRL_SPACIOUSNESS = 0x02, +/// A.10.3.3 - 3D Stereo Extender Processing Unit Control Selectors UAC1 +typedef enum { + AUDIO10_3D_CTRL_UNDEF = 0x00, + AUDIO10_3D_CTRL_ENABLE = 0x01, + AUDIO10_3D_CTRL_SPACIOUSNESS = 0x02, } audio10_3d_stereo_extender_control_selector_t; -/// A.9.6 - Reverberation Processing Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_RV_CTRL_UNDEF = 0x00, - AUDIO10_RV_CTRL_ENABLE = 0x01, - AUDIO10_RV_CTRL_REVERB_LEVEL = 0x02, - AUDIO10_RV_CTRL_REVERB_TIME = 0x03, - AUDIO10_RV_CTRL_REVERB_FEEDBACK = 0x04, +/// A.10.3.4 - Reverberation Processing Unit Control Selectors UAC1 +typedef enum { + AUDIO10_RV_CTRL_UNDEF = 0x00, + AUDIO10_RV_CTRL_ENABLE = 0x01, + AUDIO10_RV_CTRL_REVERB_LEVEL = 0x02, + AUDIO10_RV_CTRL_REVERB_TIME = 0x03, + AUDIO10_RV_CTRL_REVERB_FEEDBACK = 0x04, } audio10_reverberation_control_selector_t; -/// A.9.7 - Chorus Processing Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_CH_CTRL_UNDEF = 0x00, - AUDIO10_CH_CTRL_ENABLE = 0x01, - AUDIO10_CH_CTRL_CHORUS_LEVEL = 0x02, - AUDIO10_CH_CTRL_CHORUS_RATE = 0x03, - AUDIO10_CH_CTRL_CHORUS_DEPTH = 0x04, +/// A.10.3.5 - Chorus Processing Unit Control Selectors UAC1 +typedef enum { + AUDIO10_CH_CTRL_UNDEF = 0x00, + AUDIO10_CH_CTRL_ENABLE = 0x01, + AUDIO10_CH_CTRL_CHORUS_LEVEL = 0x02, + AUDIO10_CH_CTRL_CHORUS_RATE = 0x03, + AUDIO10_CH_CTRL_CHORUS_DEPTH = 0x04, } audio10_chorus_control_selector_t; -/// A.9.8 - Dynamic Range Compressor Processing Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_DR_CTRL_UNDEF = 0x00, - AUDIO10_DR_CTRL_ENABLE = 0x01, - AUDIO10_DR_CTRL_COMPRESSION_RATE = 0x02, - AUDIO10_DR_CTRL_MAXAMPL = 0x03, - AUDIO10_DR_CTRL_THRESHOLD = 0x04, - AUDIO10_DR_CTRL_ATTACK_TIME = 0x05, - AUDIO10_DR_CTRL_RELEASE_TIME = 0x06, +/// A.10.3.6 - Dynamic Range Compressor Processing Unit Control Selectors UAC1 +typedef enum { + AUDIO10_DR_CTRL_UNDEF = 0x00, + AUDIO10_DR_CTRL_ENABLE = 0x01, + AUDIO10_DR_CTRL_COMPRESSION_RATE = 0x02, + AUDIO10_DR_CTRL_MAXAMPL = 0x03, + AUDIO10_DR_CTRL_THRESHOLD = 0x04, + AUDIO10_DR_CTRL_ATTACK_TIME = 0x05, + AUDIO10_DR_CTRL_RELEASE_TIME = 0x06, } audio10_dynamic_range_compression_control_selector_t; -/// A.9.9 - Extension Unit Control Selectors UAC1 -typedef enum -{ - AUDIO10_XU_CTRL_UNDEF = 0x00, - AUDIO10_XU_CTRL_ENABLE = 0x01, +/// A.10.4 - Extension Unit Control Selectors UAC1 +typedef enum { + AUDIO10_XU_CTRL_UNDEF = 0x00, + AUDIO10_XU_CTRL_ENABLE = 0x01, } audio10_extension_unit_control_selector_t; -/// A.9.10 - Endpoint Control Selectors UAC1 -typedef enum -{ - AUDIO10_EP_CTRL_UNDEF = 0x00, - AUDIO10_EP_CTRL_SAMPLING_FREQ = 0x01, - AUDIO10_EP_CTRL_PITCH = 0x02, +/// A.10.5 - Endpoint Control Selectors UAC1 +typedef enum { + AUDIO10_EP_CTRL_UNDEF = 0x00, + AUDIO10_EP_CTRL_SAMPLING_FREQ = 0x01, + AUDIO10_EP_CTRL_PITCH = 0x02, } audio10_ep_control_selector_t; +/// Audio Class-Specific AS Isochronous Data EP Attributes UAC1 +typedef enum { + AUDIO10_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, + AUDIO10_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00, + AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ = 0x01, + AUDIO10_CS_AS_ISO_DATA_EP_ATT_PITCH = 0x02, +} audio10_cs_as_iso_data_ep_attribute_t; + +/// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC1 +typedef enum { + AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, + AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01, + AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, +} audio10_cs_as_iso_data_ep_lock_delay_unit_t; + +/// Audio Class-Feature Unit Controls UAC1 +typedef enum { + AUDIO10_FU_CONTROL_BM_MUTE = 1 << 0, + AUDIO10_FU_CONTROL_BM_VOLUME = 1 << 1, + AUDIO10_FU_CONTROL_BM_BASS = 1 << 2, + AUDIO10_FU_CONTROL_BM_MID = 1 << 3, + AUDIO10_FU_CONTROL_BM_TREBLE = 1 << 4, + AUDIO10_FU_CONTROL_BM_GRAPHIC_EQUALIZER = 1 << 5, + AUDIO10_FU_CONTROL_BM_AGC = 1 << 6, + AUDIO10_FU_CONTROL_BM_DELAY = 1 << 7, + AUDIO10_FU_CONTROL_BM_BASS_BOOST = 1 << 8, + AUDIO10_FU_CONTROL_BM_LOUDNESS = 1 << 9, +} audio10_feature_unit_control_bitmap_t; + /// A.1 - Audio Class-Format Type Codes UAC1 -typedef enum -{ - AUDIO10_FORMAT_TYPE_UNDEFINED = 0x00, - AUDIO10_FORMAT_TYPE_I = 0x01, - AUDIO10_FORMAT_TYPE_II = 0x02, - AUDIO10_FORMAT_TYPE_III = 0x03, +typedef enum { + AUDIO10_FORMAT_TYPE_UNDEFINED = 0x00, + AUDIO10_FORMAT_TYPE_I = 0x01, + AUDIO10_FORMAT_TYPE_II = 0x02, + AUDIO10_FORMAT_TYPE_III = 0x03, } audio10_format_type_t; // A.1.1 - Audio Class-Audio Data Format Type I UAC1 -typedef enum -{ - AUDIO10_DATA_FORMAT_TYPE_I_PCM = 0x0001, - AUDIO10_DATA_FORMAT_TYPE_I_PCM8 = 0x0002, - AUDIO10_DATA_FORMAT_TYPE_I_IEEE_FLOAT = 0x0003, - AUDIO10_DATA_FORMAT_TYPE_I_ALAW = 0x0004, - AUDIO10_DATA_FORMAT_TYPE_I_MULAW = 0x0005, +typedef enum { + AUDIO10_DATA_FORMAT_TYPE_I_PCM = 0x0001, + AUDIO10_DATA_FORMAT_TYPE_I_PCM8 = 0x0002, + AUDIO10_DATA_FORMAT_TYPE_I_IEEE_FLOAT = 0x0003, + AUDIO10_DATA_FORMAT_TYPE_I_ALAW = 0x0004, + AUDIO10_DATA_FORMAT_TYPE_I_MULAW = 0x0005, } audio10_data_format_type_I_t; // A.1.2 - Audio Class-Audio Data Format Type II UAC1 -typedef enum -{ - AUDIO10_DATA_FORMAT_TYPE_II_MPEG = 0x1001, - AUDIO10_DATA_FORMAT_TYPE_II_AC3 = 0x1002, +typedef enum { + AUDIO10_DATA_FORMAT_TYPE_II_MPEG = 0x1001, + AUDIO10_DATA_FORMAT_TYPE_II_AC3 = 0x1002, } audio10_data_format_type_II_t; // A.1.3 - Audio Class-Audio Data Format Type III UAC1 -typedef enum -{ - AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_AC3_1 = 0x2001, - AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG1_L1_1 = 0x2002, - AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG1_L23_1 = 0x2003, - AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_EXT_1 = 0x2004, +typedef enum { + AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_AC3_1 = 0x2001, + AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG1_L1_1 = 0x2002, + AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG1_L23_1 = 0x2003, + AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_EXT_1 = 0x2004, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_L1_LS_1 = 0x2005, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_L23_LS_1 = 0x2006, } audio10_data_format_type_III_t; /// Audio Class-Audio Channel Configuration UAC1 (Table A-7) -typedef enum -{ - AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED = 0x0000, - AUDIO10_CHANNEL_CONFIG_LEFT_FRONT = 0x0001, - AUDIO10_CHANNEL_CONFIG_RIGHT_FRONT = 0x0002, - AUDIO10_CHANNEL_CONFIG_CENTER_FRONT = 0x0004, - AUDIO10_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x0008, - AUDIO10_CHANNEL_CONFIG_LEFT_SURROUND = 0x0010, - AUDIO10_CHANNEL_CONFIG_RIGHT_SURROUND = 0x0020, - AUDIO10_CHANNEL_CONFIG_LEFT_OF_CENTER = 0x0040, - AUDIO10_CHANNEL_CONFIG_RIGHT_OF_CENTER = 0x0080, - AUDIO10_CHANNEL_CONFIG_SURROUND = 0x0100, - AUDIO10_CHANNEL_CONFIG_SIDE_LEFT = 0x0200, - AUDIO10_CHANNEL_CONFIG_SIDE_RIGHT = 0x0400, - AUDIO10_CHANNEL_CONFIG_TOP = 0x0800, +typedef enum { + AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED = 0x0000, + AUDIO10_CHANNEL_CONFIG_LEFT_FRONT = 0x0001, + AUDIO10_CHANNEL_CONFIG_RIGHT_FRONT = 0x0002, + AUDIO10_CHANNEL_CONFIG_CENTER_FRONT = 0x0004, + AUDIO10_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x0008, + AUDIO10_CHANNEL_CONFIG_LEFT_SURROUND = 0x0010, + AUDIO10_CHANNEL_CONFIG_RIGHT_SURROUND = 0x0020, + AUDIO10_CHANNEL_CONFIG_LEFT_OF_CENTER = 0x0040, + AUDIO10_CHANNEL_CONFIG_RIGHT_OF_CENTER = 0x0080, + AUDIO10_CHANNEL_CONFIG_SURROUND = 0x0100, + AUDIO10_CHANNEL_CONFIG_SIDE_LEFT = 0x0200, + AUDIO10_CHANNEL_CONFIG_SIDE_RIGHT = 0x0400, + AUDIO10_CHANNEL_CONFIG_TOP = 0x0800, } audio10_channel_config_t; -//--------------------------------------------------------------------+ -// USB AUDIO CLASS 1.0 (UAC1) DESCRIPTORS -//--------------------------------------------------------------------+ + //--------------------------------------------------------------------+ + // USB AUDIO CLASS 1.0 (UAC1) DESCRIPTORS + //--------------------------------------------------------------------+ -/// AUDIO Class-Specific AC Interface Header Descriptor UAC1 (4.3.2) -#define audio10_desc_cs_ac_interface_n_t(numInterfaces) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 8+n. */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_HEADER. */\ - uint16_t bcdADC ; /* Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: 0x0100 for UAC1. */\ - uint16_t wTotalLength ; /* Total number of bytes returned for the class-specific AudioControl interface descriptor. */\ - uint8_t bInCollection ; /* The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface Collection. */\ - uint8_t baInterfaceNr[numInterfaces]; /* Interface number of the AudioStreaming or MIDIStreaming interface in the Collection. */\ -} + /// AUDIO Class-Specific AC Interface Header Descriptor UAC1 (4.3.2) + #define audio10_desc_cs_ac_interface_n_t(numInterfaces) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 8+n. */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_HEADER. */ \ + uint16_t bcdADC; /* Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: 0x0100 for UAC1. */ \ + uint16_t wTotalLength; /* Total number of bytes returned for the class-specific AudioControl interface descriptor. */ \ + uint8_t bInCollection; /* The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface Collection. */ \ + uint8_t baInterfaceNr[numInterfaces]; /* Interface number of the AudioStreaming or MIDIStreaming interface in the Collection. */ \ + } /// AUDIO Input Terminal Descriptor UAC1 (4.3.2.1) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor in bytes: 12. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL. - uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. - uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. - uint8_t bAssocTerminal ; ///< ID of the Output Terminal to which this Input Terminal is associated. - uint8_t bNrChannels ; ///< Number of logical output channels in the Terminal's output audio channel cluster. - uint16_t wChannelConfig ; ///< Describes the spatial location of the logical channels. - uint8_t iChannelNames ; ///< Index of a string descriptor, describing the name of the first logical channel. - uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 12. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL. + uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. + uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. + uint8_t bAssocTerminal; ///< ID of the Output Terminal to which this Input Terminal is associated. + uint8_t bNrChannels; ///< Number of logical output channels in the Terminal's output audio channel cluster. + uint16_t wChannelConfig; ///< Describes the spatial location of the logical channels. + uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first logical channel. + uint8_t iTerminal; ///< Index of a string descriptor, describing the Input Terminal. } audio10_desc_input_terminal_t; /// AUDIO Output Terminal Descriptor UAC1 (4.3.2.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor in bytes: 9. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL. - uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. - uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. - uint8_t bAssocTerminal ; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. - uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Terminal is connected. - uint8_t iTerminal ; ///< Index of a string descriptor, describing the Output Terminal. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 9. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL. + uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. + uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. + uint8_t bAssocTerminal; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. + uint8_t bSourceID; ///< ID of the Unit or Terminal to which this Terminal is connected. + uint8_t iTerminal; ///< Index of a string descriptor, describing the Output Terminal. } audio10_desc_output_terminal_t; /// AUDIO Mixer Unit Descriptor UAC1 (4.3.2.3) -#define audio10_desc_mixer_unit_n_t(numInputPins, numControlBytes) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 10+p+n. */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_MIXER_UNIT. */\ - uint8_t bUnitID ; /* Constant uniquely identifying the Unit within the audio function. */\ - uint8_t bNrInPins ; /* Number of Input Pins of this Unit: p. */\ - uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Mixer Unit are connected. */\ - uint8_t bNrChannels ; /* Number of logical output channels in the Mixer Unit's output audio channel cluster. */\ - uint16_t wChannelConfig ; /* Describes the spatial location of the logical channels. */\ - uint8_t iChannelNames ; /* Index of a string descriptor, describing the name of the first logical channel. */\ - uint8_t bmControls[numControlBytes]; /* Mixer Unit Controls bitmap. */\ - uint8_t iMixer ; /* Index of a string descriptor, describing the Mixer Unit. */\ -} +#define audio10_desc_mixer_unit_n_t(numInputPins, numControlBytes) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 10+p+n. */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_MIXER_UNIT. */ \ + uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ + uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ + uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Mixer Unit are connected. */ \ + uint8_t bNrChannels; /* Number of logical output channels in the Mixer Unit's output audio channel cluster. */ \ + uint16_t wChannelConfig; /* Describes the spatial location of the logical channels. */ \ + uint8_t iChannelNames; /* Index of a string descriptor, describing the name of the first logical channel. */ \ + uint8_t bmControls[numControlBytes]; /* Mixer Unit Controls bitmap. */ \ + uint8_t iMixer; /* Index of a string descriptor, describing the Mixer Unit. */ \ + } /// AUDIO Selector Unit Descriptor UAC1 (4.3.2.4) -#define audio10_desc_selector_unit_n_t(numInputPins) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 6+p. */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT. */\ - uint8_t bUnitID ; /* Constant uniquely identifying the Unit within the audio function. */\ - uint8_t bNrInPins ; /* Number of Input Pins of this Unit: p. */\ - uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Selector Unit are connected. */\ - uint8_t iSelector ; /* Index of a string descriptor, describing the Selector Unit. */\ -} +#define audio10_desc_selector_unit_n_t(numInputPins) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 6+p. */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT. */ \ + uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ + uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ + uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Selector Unit are connected. */ \ + uint8_t iSelector; /* Index of a string descriptor, describing the Selector Unit. */ \ + } /// AUDIO Feature Unit Descriptor UAC1 (4.3.2.5) -#define audio10_desc_feature_unit_n_t(numChannels, controlSize) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 7+(ch+1)*n. */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT. */\ - uint8_t bUnitID ; /* Constant uniquely identifying the Unit within the audio function. */\ - uint8_t bSourceID ; /* ID of the Unit or Terminal to which this Feature Unit is connected. */\ - uint8_t bControlSize ; /* Size in bytes of an element of the bmaControls() array. */\ - uint8_t bmaControls[(numChannels+1)*controlSize]; /* Control bitmaps for master + logical channels. */\ - uint8_t iFeature ; /* Index of a string descriptor, describing this Feature Unit. */\ -} +#define audio10_desc_feature_unit_n_t(numChannels, controlSize) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 7+(ch+1)*n. */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT. */ \ + uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ + uint8_t bSourceID; /* ID of the Unit or Terminal to which this Feature Unit is connected. */ \ + uint8_t bControlSize; /* Size in bytes of an element of the bmaControls() array. */ \ + uint8_t bmaControls[(numChannels + 1) * controlSize]; /* Control bitmaps for master + logical channels. */ \ + uint8_t iFeature; /* Index of a string descriptor, describing this Feature Unit. */ \ + } /// AUDIO Processing Unit Descriptor UAC1 (4.3.2.6) -#define audio10_desc_processing_unit_n_t(numInputPins, numControlBytes) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 13+p+n. */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_PROCESSING_UNIT. */\ - uint8_t bUnitID ; /* Constant uniquely identifying the Unit within the audio function. */\ - uint16_t wProcessType ; /* Constant identifying the type of processing this Unit is performing. */\ - uint8_t bNrInPins ; /* Number of Input Pins of this Unit: p. */\ - uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Processing Unit are connected. */\ - uint8_t bNrChannels ; /* Number of logical output channels in the Processing Unit's output audio channel cluster. */\ - uint16_t wChannelConfig ; /* Describes the spatial location of the logical channels. */\ - uint8_t iChannelNames ; /* Index of a string descriptor, describing the name of the first logical channel. */\ - uint8_t bControlSize ; /* Size in bytes of the bmControls field. */\ - uint8_t bmControls[numControlBytes]; /* Processing Unit Controls bitmap. */\ - uint8_t iProcessing ; /* Index of a string descriptor, describing the Processing Unit. */\ -} +#define audio10_desc_processing_unit_n_t(numInputPins, numControlBytes) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 13+p+n. */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_PROCESSING_UNIT. */ \ + uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ + uint16_t wProcessType; /* Constant identifying the type of processing this Unit is performing. */ \ + uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ + uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Processing Unit are connected. */ \ + uint8_t bNrChannels; /* Number of logical output channels in the Processing Unit's output audio channel cluster. */ \ + uint16_t wChannelConfig; /* Describes the spatial location of the logical channels. */ \ + uint8_t iChannelNames; /* Index of a string descriptor, describing the name of the first logical channel. */ \ + uint8_t bControlSize; /* Size in bytes of the bmControls field. */ \ + uint8_t bmControls[numControlBytes]; /* Processing Unit Controls bitmap. */ \ + uint8_t iProcessing; /* Index of a string descriptor, describing the Processing Unit. */ \ + } /// AUDIO Extension Unit Descriptor UAC1 (4.3.2.7) -#define audio10_desc_extension_unit_n_t(numInputPins, numControlBytes) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 13+p+n. */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_EXTENSION_UNIT. */\ - uint8_t bUnitID ; /* Constant uniquely identifying the Unit within the audio function. */\ - uint16_t wExtensionCode ; /* Vendor-specific code identifying the Extension Unit. */\ - uint8_t bNrInPins ; /* Number of Input Pins of this Unit: p. */\ - uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Extension Unit are connected. */\ - uint8_t bNrChannels ; /* Number of logical output channels in the Extension Unit's output audio channel cluster. */\ - uint16_t wChannelConfig ; /* Describes the spatial location of the logical channels. */\ - uint8_t iChannelNames ; /* Index of a string descriptor, describing the name of the first logical channel. */\ - uint8_t bControlSize ; /* Size in bytes of the bmControls field. */\ - uint8_t bmControls[numControlBytes]; /* Extension Unit Controls bitmap. */\ - uint8_t iExtension ; /* Index of a string descriptor, describing the Extension Unit. */\ -} +#define audio10_desc_extension_unit_n_t(numInputPins, numControlBytes) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 13+p+n. */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_EXTENSION_UNIT. */ \ + uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ + uint16_t wExtensionCode; /* Vendor-specific code identifying the Extension Unit. */ \ + uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ + uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Extension Unit are connected. */ \ + uint8_t bNrChannels; /* Number of logical output channels in the Extension Unit's output audio channel cluster. */ \ + uint16_t wChannelConfig; /* Describes the spatial location of the logical channels. */ \ + uint8_t iChannelNames; /* Index of a string descriptor, describing the name of the first logical channel. */ \ + uint8_t bControlSize; /* Size in bytes of the bmControls field. */ \ + uint8_t bmControls[numControlBytes]; /* Extension Unit Controls bitmap. */ \ + uint8_t iExtension; /* Index of a string descriptor, describing the Extension Unit. */ \ + } /// AUDIO Class-Specific AS Interface Descriptor UAC1 (4.5.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor in bytes: 7. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_AS_GENERAL. - uint8_t bTerminalLink ; ///< The Terminal ID of the Terminal to which the endpoint of this interface is connected. - uint8_t bDelay ; ///< Expressed in number of frames. - uint16_t wFormatTag ; ///< The Audio Data Format that has to be used to communicate with this interface. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 7. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_AS_GENERAL. + uint8_t bTerminalLink; ///< The Terminal ID of the Terminal to which the endpoint of this interface is connected. + uint8_t bDelay; ///< Expressed in number of frames. + uint16_t wFormatTag; ///< The Audio Data Format that has to be used to communicate with this interface. } audio10_desc_cs_as_interface_t; /// AUDIO Type I Format Type Descriptor UAC1 (2.2.5) -#define audio10_desc_type_I_format_n_t(numSamFreq) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 8+(ns*3). */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */\ - uint8_t bFormatType ; /* Constant identifying the Format Type the AudioStreaming interface is using. */\ - uint8_t bNrChannels ; /* Indicates the number of physical channels in the audio data stream. */\ - uint8_t bSubFrameSize ; /* The number of bytes occupied by one audio subframe. */\ - uint8_t bBitResolution ; /* The number of effectively used bits from the available bits in an audio subframe. */\ - uint8_t bSamFreqType ; /* Indicates how the sampling frequency can be programmed. */\ - uint8_t tSamFreq[numSamFreq*3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */\ -} +#define audio10_desc_type_I_format_n_t(numSamFreq) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 8+(ns*3). */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */ \ + uint8_t bFormatType; /* Constant identifying the Format Type the AudioStreaming interface is using. */ \ + uint8_t bNrChannels; /* Indicates the number of physical channels in the audio data stream. */ \ + uint8_t bSubFrameSize; /* The number of bytes occupied by one audio subframe. */ \ + uint8_t bBitResolution; /* The number of effectively used bits from the available bits in an audio subframe. */ \ + uint8_t bSamFreqType; /* Indicates how the sampling frequency can be programmed. */ \ + uint8_t tSamFreq[numSamFreq * 3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */ \ + } /// AUDIO Type II Format Type Descriptor UAC1 (2.3.5) -#define audio10_desc_type_II_format_n_t(numSamFreq) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 9+(ns*3). */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */\ - uint8_t bFormatType ; /* Constant identifying the Format Type the AudioStreaming interface is using. */\ - uint16_t wMaxBitRate ; /* Indicates the maximum number of bits per second this interface can handle. */\ - uint16_t wSamplesPerFrame ; /* Indicates the number of PCM audio samples contained in one encoded audio frame. */\ - uint8_t bSamFreqType ; /* Indicates how the sampling frequency can be programmed. */\ - uint8_t tSamFreq[numSamFreq*3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */\ -} +#define audio10_desc_type_II_format_n_t(numSamFreq) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 9+(ns*3). */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */ \ + uint8_t bFormatType; /* Constant identifying the Format Type the AudioStreaming interface is using. */ \ + uint16_t wMaxBitRate; /* Indicates the maximum number of bits per second this interface can handle. */ \ + uint16_t wSamplesPerFrame; /* Indicates the number of PCM audio samples contained in one encoded audio frame. */ \ + uint8_t bSamFreqType; /* Indicates how the sampling frequency can be programmed. */ \ + uint8_t tSamFreq[numSamFreq * 3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */ \ + } /// AUDIO Type III Format Type Descriptor UAC1 (2.4.5) -#define audio10_desc_type_III_format_n_t(numSamFreq) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* Size of this descriptor in bytes: 8+(ns*3). */\ - uint8_t bDescriptorType ; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */\ - uint8_t bDescriptorSubType ; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */\ - uint8_t bFormatType ; /* Constant identifying the Format Type the AudioStreaming interface is using. */\ - uint8_t bNrChannels ; /* Indicates the number of physical channels in the audio data stream. */\ - uint8_t bSubFrameSize ; /* The number of bytes occupied by one audio subframe. */\ - uint8_t bBitResolution ; /* The number of effectively used bits from the available bits in an audio subframe. */\ - uint8_t bSamFreqType ; /* Indicates how the sampling frequency can be programmed. */\ - uint8_t tSamFreq[numSamFreq*3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */\ -} +#define audio10_desc_type_III_format_n_t(numSamFreq) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* Size of this descriptor in bytes: 8+(ns*3). */ \ + uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ + uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */ \ + uint8_t bFormatType; /* Constant identifying the Format Type the AudioStreaming interface is using. */ \ + uint8_t bNrChannels; /* Indicates the number of physical channels in the audio data stream. */ \ + uint8_t bSubFrameSize; /* The number of bytes occupied by one audio subframe. */ \ + uint8_t bBitResolution; /* The number of effectively used bits from the available bits in an audio subframe. */ \ + uint8_t bSamFreqType; /* Indicates how the sampling frequency can be programmed. */ \ + uint8_t tSamFreq[numSamFreq * 3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */ \ + } + +/// Standard AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.1) +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 9. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_ENDPOINT. + uint8_t bEndpointAddress;///< The address of the endpoint on the USB device described by this descriptor. + uint8_t bmAttributes; ///< Endpoint attributes when configured using the bEndpointAddress field. + uint16_t wMaxPacketSize; ///< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. + uint8_t bInterval; ///< Interval for polling endpoint for data transfers. + uint8_t bRefresh; ///< The rate at which the endpoint is refreshed. + uint8_t bSynchAddress; ///< The address of the endpoint used to send synchronization information for the data endpoint. +} audio10_desc_as_iso_data_ep_t; /// AUDIO Class-Specific AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor in bytes: 7. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO10_CS_EP_SUBTYPE_GENERAL. - uint8_t bmAttributes ; ///< Bit 0: Sampling Frequency, Bit 1: Pitch, Bit 7: MaxPacketsOnly. - uint8_t bLockDelayUnits ; ///< Indicates the units used for the wLockDelay field. - uint16_t wLockDelay ; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 7. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_EP_SUBTYPE_GENERAL. + uint8_t bmAttributes; ///< Bit 0: Sampling Frequency, Bit 1: Pitch, Bit 7: MaxPacketsOnly. + uint8_t bLockDelayUnits; ///< Indicates the units used for the wLockDelay field. + uint16_t wLockDelay; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. } audio10_desc_cs_as_iso_data_ep_t; /// AUDIO Interrupt Data Message Format UAC1 (3.7.1.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bStatusType ; ///< Indicates the type of status information being reported. - uint8_t bOriginator ; ///< Indicates the entity that originated this status information. +typedef struct TU_ATTR_PACKED { + uint8_t bStatusType;///< Indicates the type of status information being reported. + uint8_t bOriginator;///< Indicates the entity that originated this status information. } audio10_interrupt_data_t; //--------------------------------------------------------------------+ @@ -470,576 +517,494 @@ typedef struct TU_ATTR_PACKED //--------------------------------------------------------------------+ /// A.7 - Audio Function Category Codes -typedef enum -{ - AUDIO20_FUNC_UNDEF = 0x00, - AUDIO20_FUNC_DESKTOP_SPEAKER = 0x01, - AUDIO20_FUNC_HOME_THEATER = 0x02, - AUDIO20_FUNC_MICROPHONE = 0x03, - AUDIO20_FUNC_HEADSET = 0x04, - AUDIO20_FUNC_TELEPHONE = 0x05, - AUDIO20_FUNC_CONVERTER = 0x06, - AUDIO20_FUNC_SOUND_RECODER = 0x07, - AUDIO20_FUNC_IO_BOX = 0x08, +typedef enum { + AUDIO20_FUNC_UNDEF = 0x00, + AUDIO20_FUNC_DESKTOP_SPEAKER = 0x01, + AUDIO20_FUNC_HOME_THEATER = 0x02, + AUDIO20_FUNC_MICROPHONE = 0x03, + AUDIO20_FUNC_HEADSET = 0x04, + AUDIO20_FUNC_TELEPHONE = 0x05, + AUDIO20_FUNC_CONVERTER = 0x06, + AUDIO20_FUNC_SOUND_RECODER = 0x07, + AUDIO20_FUNC_IO_BOX = 0x08, AUDIO20_FUNC_MUSICAL_INSTRUMENT = 0x09, - AUDIO20_FUNC_PRO_AUDIO = 0x0A, - AUDIO20_FUNC_AUDIO_VIDEO = 0x0B, - AUDIO20_FUNC_CONTROL_PANEL = 0x0C, - AUDIO20_FUNC_OTHER = 0xFF, + AUDIO20_FUNC_PRO_AUDIO = 0x0A, + AUDIO20_FUNC_AUDIO_VIDEO = 0x0B, + AUDIO20_FUNC_CONTROL_PANEL = 0x0C, + AUDIO20_FUNC_OTHER = 0xFF, } audio20_function_code_t; /// A.9 - Audio Class-Specific AC Interface Descriptor Subtypes UAC2 -typedef enum -{ - AUDIO20_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, - AUDIO20_CS_AC_INTERFACE_HEADER = 0x01, - AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, - AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, - AUDIO20_CS_AC_INTERFACE_MIXER_UNIT = 0x04, - AUDIO20_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, - AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, - AUDIO20_CS_AC_INTERFACE_EFFECT_UNIT = 0x07, - AUDIO20_CS_AC_INTERFACE_PROCESSING_UNIT = 0x08, - AUDIO20_CS_AC_INTERFACE_EXTENSION_UNIT = 0x09, - AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE = 0x0A, - AUDIO20_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B, - AUDIO20_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C, +typedef enum { + AUDIO20_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, + AUDIO20_CS_AC_INTERFACE_HEADER = 0x01, + AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, + AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, + AUDIO20_CS_AC_INTERFACE_MIXER_UNIT = 0x04, + AUDIO20_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, + AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, + AUDIO20_CS_AC_INTERFACE_EFFECT_UNIT = 0x07, + AUDIO20_CS_AC_INTERFACE_PROCESSING_UNIT = 0x08, + AUDIO20_CS_AC_INTERFACE_EXTENSION_UNIT = 0x09, + AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE = 0x0A, + AUDIO20_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B, + AUDIO20_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C, AUDIO20_CS_AC_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D, } audio20_cs_ac_interface_subtype_t; /// A.10 - Audio Class-Specific AS Interface Descriptor Subtypes UAC2 -typedef enum -{ - AUDIO20_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, - AUDIO20_CS_AS_INTERFACE_AS_GENERAL = 0x01, - AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, - AUDIO20_CS_AS_INTERFACE_ENCODER = 0x03, - AUDIO20_CS_AS_INTERFACE_DECODER = 0x04, +typedef enum { + AUDIO20_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, + AUDIO20_CS_AS_INTERFACE_AS_GENERAL = 0x01, + AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, + AUDIO20_CS_AS_INTERFACE_ENCODER = 0x03, + AUDIO20_CS_AS_INTERFACE_DECODER = 0x04, } audio20_cs_as_interface_subtype_t; /// A.11 - Effect Unit Effect Types -typedef enum -{ - AUDIO20_EFFECT_TYPE_UNDEF = 0x00, - AUDIO20_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01, - AUDIO20_EFFECT_TYPE_REVERBERATION = 0x02, - AUDIO20_EFFECT_TYPE_MOD_DELAY = 0x03, - AUDIO20_EFFECT_TYPE_DYN_RANGE_COMP = 0x04, +typedef enum { + AUDIO20_EFFECT_TYPE_UNDEF = 0x00, + AUDIO20_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01, + AUDIO20_EFFECT_TYPE_REVERBERATION = 0x02, + AUDIO20_EFFECT_TYPE_MOD_DELAY = 0x03, + AUDIO20_EFFECT_TYPE_DYN_RANGE_COMP = 0x04, } audio20_effect_unit_effect_type_t; /// A.12 - Processing Unit Process Types -typedef enum -{ - AUDIO20_PROCESS_TYPE_UNDEF = 0x00, - AUDIO20_PROCESS_TYPE_UP_DOWN_MIX = 0x01, - AUDIO20_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02, - AUDIO20_PROCESS_TYPE_STEREO_EXTENDER = 0x03, +typedef enum { + AUDIO20_PROCESS_TYPE_UNDEF = 0x00, + AUDIO20_PROCESS_TYPE_UP_DOWN_MIX = 0x01, + AUDIO20_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02, + AUDIO20_PROCESS_TYPE_STEREO_EXTENDER = 0x03, } audio20_processing_unit_process_type_t; /// A.13 - Audio Class-Specific EP Descriptor Subtypes UAC2 -typedef enum -{ - AUDIO20_CS_EP_SUBTYPE_UNDEF = 0x00, - AUDIO20_CS_EP_SUBTYPE_GENERAL = 0x01, +typedef enum { + AUDIO20_CS_EP_SUBTYPE_UNDEF = 0x00, + AUDIO20_CS_EP_SUBTYPE_GENERAL = 0x01, } audio20_cs_ep_subtype_t; /// A.14 - Audio Class-Specific Request Codes UAC2 -typedef enum -{ - AUDIO20_CS_REQ_UNDEF = 0x00, - AUDIO20_CS_REQ_CUR = 0x01, - AUDIO20_CS_REQ_RANGE = 0x02, - AUDIO20_CS_REQ_MEM = 0x03, +typedef enum { + AUDIO20_CS_REQ_UNDEF = 0x00, + AUDIO20_CS_REQ_CUR = 0x01, + AUDIO20_CS_REQ_RANGE = 0x02, + AUDIO20_CS_REQ_MEM = 0x03, } audio20_cs_req_t; /// A.17 - Control Selector Codes UAC2 /// A.17.1 - Clock Source Control Selectors -typedef enum -{ - AUDIO20_CS_CTRL_UNDEF = 0x00, - AUDIO20_CS_CTRL_SAM_FREQ = 0x01, - AUDIO20_CS_CTRL_CLK_VALID = 0x02, +typedef enum { + AUDIO20_CS_CTRL_UNDEF = 0x00, + AUDIO20_CS_CTRL_SAM_FREQ = 0x01, + AUDIO20_CS_CTRL_CLK_VALID = 0x02, } audio20_clock_src_control_selector_t; /// A.17.2 - Clock Selector Control Selectors -typedef enum -{ - AUDIO20_CX_CTRL_UNDEF = 0x00, - AUDIO20_CX_CTRL_CONTROL = 0x01, +typedef enum { + AUDIO20_CX_CTRL_UNDEF = 0x00, + AUDIO20_CX_CTRL_CONTROL = 0x01, } audio20_clock_sel_control_selector_t; /// A.17.3 - Clock Multiplier Control Selectors -typedef enum -{ - AUDIO20_CM_CTRL_UNDEF = 0x00, - AUDIO20_CM_CTRL_NUMERATOR_CONTROL = 0x01, - AUDIO20_CM_CTRL_DENOMINATOR_CONTROL = 0x02, +typedef enum { + AUDIO20_CM_CTRL_UNDEF = 0x00, + AUDIO20_CM_CTRL_NUMERATOR_CONTROL = 0x01, + AUDIO20_CM_CTRL_DENOMINATOR_CONTROL = 0x02, } audio20_clock_mul_control_selector_t; /// A.17.4 - Terminal Control Selectors UAC2 -typedef enum -{ - AUDIO20_TE_CTRL_UNDEF = 0x00, - AUDIO20_TE_CTRL_COPY_PROTECT = 0x01, - AUDIO20_TE_CTRL_CONNECTOR = 0x02, - AUDIO20_TE_CTRL_OVERLOAD = 0x03, - AUDIO20_TE_CTRL_CLUSTER = 0x04, - AUDIO20_TE_CTRL_UNDERFLOW = 0x05, - AUDIO20_TE_CTRL_OVERFLOW = 0x06, - AUDIO20_TE_CTRL_LATENCY = 0x07, +typedef enum { + AUDIO20_TE_CTRL_UNDEF = 0x00, + AUDIO20_TE_CTRL_COPY_PROTECT = 0x01, + AUDIO20_TE_CTRL_CONNECTOR = 0x02, + AUDIO20_TE_CTRL_OVERLOAD = 0x03, + AUDIO20_TE_CTRL_CLUSTER = 0x04, + AUDIO20_TE_CTRL_UNDERFLOW = 0x05, + AUDIO20_TE_CTRL_OVERFLOW = 0x06, + AUDIO20_TE_CTRL_LATENCY = 0x07, } audio20_terminal_control_selector_t; /// A.17.5 - Mixer Control Selectors -typedef enum -{ - AUDIO20_MU_CTRL_UNDEF = 0x00, - AUDIO20_MU_CTRL_MIXER = 0x01, - AUDIO20_MU_CTRL_CLUSTER = 0x02, - AUDIO20_MU_CTRL_UNDERFLOW = 0x03, - AUDIO20_MU_CTRL_OVERFLOW = 0x04, - AUDIO20_MU_CTRL_LATENCY = 0x05, +typedef enum { + AUDIO20_MU_CTRL_UNDEF = 0x00, + AUDIO20_MU_CTRL_MIXER = 0x01, + AUDIO20_MU_CTRL_CLUSTER = 0x02, + AUDIO20_MU_CTRL_UNDERFLOW = 0x03, + AUDIO20_MU_CTRL_OVERFLOW = 0x04, + AUDIO20_MU_CTRL_LATENCY = 0x05, } audio20_mixer_control_selector_t; /// A.17.6 - Selector Control Selectors -typedef enum -{ - AUDIO20_SU_CTRL_UNDEF = 0x00, - AUDIO20_SU_CTRL_SELECTOR = 0x01, - AUDIO20_SU_CTRL_LATENCY = 0x02, +typedef enum { + AUDIO20_SU_CTRL_UNDEF = 0x00, + AUDIO20_SU_CTRL_SELECTOR = 0x01, + AUDIO20_SU_CTRL_LATENCY = 0x02, } audio20_sel_control_selector_t; /// A.17.7 - Feature Unit Control Selectors UAC2 -typedef enum -{ - AUDIO20_FU_CTRL_UNDEF = 0x00, - AUDIO20_FU_CTRL_MUTE = 0x01, - AUDIO20_FU_CTRL_VOLUME = 0x02, - AUDIO20_FU_CTRL_BASS = 0x03, - AUDIO20_FU_CTRL_MID = 0x04, - AUDIO20_FU_CTRL_TREBLE = 0x05, - AUDIO20_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, - AUDIO20_FU_CTRL_AGC = 0x07, - AUDIO20_FU_CTRL_DELAY = 0x08, - AUDIO20_FU_CTRL_BASS_BOOST = 0x09, - AUDIO20_FU_CTRL_LOUDNESS = 0x0A, - AUDIO20_FU_CTRL_INPUT_GAIN = 0x0B, - AUDIO20_FU_CTRL_GAIN_PAD = 0x0C, - AUDIO20_FU_CTRL_INVERTER = 0x0D, - AUDIO20_FU_CTRL_UNDERFLOW = 0x0E, - AUDIO20_FU_CTRL_OVERVLOW = 0x0F, - AUDIO20_FU_CTRL_LATENCY = 0x10, +typedef enum { + AUDIO20_FU_CTRL_UNDEF = 0x00, + AUDIO20_FU_CTRL_MUTE = 0x01, + AUDIO20_FU_CTRL_VOLUME = 0x02, + AUDIO20_FU_CTRL_BASS = 0x03, + AUDIO20_FU_CTRL_MID = 0x04, + AUDIO20_FU_CTRL_TREBLE = 0x05, + AUDIO20_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, + AUDIO20_FU_CTRL_AGC = 0x07, + AUDIO20_FU_CTRL_DELAY = 0x08, + AUDIO20_FU_CTRL_BASS_BOOST = 0x09, + AUDIO20_FU_CTRL_LOUDNESS = 0x0A, + AUDIO20_FU_CTRL_INPUT_GAIN = 0x0B, + AUDIO20_FU_CTRL_GAIN_PAD = 0x0C, + AUDIO20_FU_CTRL_INVERTER = 0x0D, + AUDIO20_FU_CTRL_UNDERFLOW = 0x0E, + AUDIO20_FU_CTRL_OVERVLOW = 0x0F, + AUDIO20_FU_CTRL_LATENCY = 0x10, } audio20_feature_unit_control_selector_t; /// A.17.8 Effect Unit Control Selectors /// A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors -typedef enum -{ - AUDIO20_PE_CTRL_UNDEF = 0x00, - AUDIO20_PE_CTRL_ENABLE = 0x01, - AUDIO20_PE_CTRL_CENTERFREQ = 0x02, - AUDIO20_PE_CTRL_QFACTOR = 0x03, - AUDIO20_PE_CTRL_GAIN = 0x04, - AUDIO20_PE_CTRL_UNDERFLOW = 0x05, - AUDIO20_PE_CTRL_OVERFLOW = 0x06, - AUDIO20_PE_CTRL_LATENCY = 0x07, +typedef enum { + AUDIO20_PE_CTRL_UNDEF = 0x00, + AUDIO20_PE_CTRL_ENABLE = 0x01, + AUDIO20_PE_CTRL_CENTERFREQ = 0x02, + AUDIO20_PE_CTRL_QFACTOR = 0x03, + AUDIO20_PE_CTRL_GAIN = 0x04, + AUDIO20_PE_CTRL_UNDERFLOW = 0x05, + AUDIO20_PE_CTRL_OVERFLOW = 0x06, + AUDIO20_PE_CTRL_LATENCY = 0x07, } audio20_parametric_equalizer_control_selector_t; /// A.17.8.2 Reverberation Effect Unit Control Selectors -typedef enum -{ - AUDIO20_RV_CTRL_UNDEF = 0x00, - AUDIO20_RV_CTRL_ENABLE = 0x01, - AUDIO20_RV_CTRL_TYPE = 0x02, - AUDIO20_RV_CTRL_LEVEL = 0x03, - AUDIO20_RV_CTRL_TIME = 0x04, - AUDIO20_RV_CTRL_FEEDBACK = 0x05, - AUDIO20_RV_CTRL_PREDELAY = 0x06, - AUDIO20_RV_CTRL_DENSITY = 0x07, - AUDIO20_RV_CTRL_HIFREQ_ROLLOFF = 0x08, - AUDIO20_RV_CTRL_UNDERFLOW = 0x09, - AUDIO20_RV_CTRL_OVERFLOW = 0x0A, - AUDIO20_RV_CTRL_LATENCY = 0x0B, +typedef enum { + AUDIO20_RV_CTRL_UNDEF = 0x00, + AUDIO20_RV_CTRL_ENABLE = 0x01, + AUDIO20_RV_CTRL_TYPE = 0x02, + AUDIO20_RV_CTRL_LEVEL = 0x03, + AUDIO20_RV_CTRL_TIME = 0x04, + AUDIO20_RV_CTRL_FEEDBACK = 0x05, + AUDIO20_RV_CTRL_PREDELAY = 0x06, + AUDIO20_RV_CTRL_DENSITY = 0x07, + AUDIO20_RV_CTRL_HIFREQ_ROLLOFF = 0x08, + AUDIO20_RV_CTRL_UNDERFLOW = 0x09, + AUDIO20_RV_CTRL_OVERFLOW = 0x0A, + AUDIO20_RV_CTRL_LATENCY = 0x0B, } audio20_reverberation_effect_control_selector_t; /// A.17.8.3 Modulation Delay Effect Unit Control Selectors -typedef enum -{ - AUDIO20_MD_CTRL_UNDEF = 0x00, - AUDIO20_MD_CTRL_ENABLE = 0x01, - AUDIO20_MD_CTRL_BALANCE = 0x02, - AUDIO20_MD_CTRL_RATE = 0x03, - AUDIO20_MD_CTRL_DEPTH = 0x04, - AUDIO20_MD_CTRL_TIME = 0x05, - AUDIO20_MD_CTRL_FEEDBACK = 0x06, - AUDIO20_MD_CTRL_UNDERFLOW = 0x07, - AUDIO20_MD_CTRL_OVERFLOW = 0x08, - AUDIO20_MD_CTRL_LATENCY = 0x09, +typedef enum { + AUDIO20_MD_CTRL_UNDEF = 0x00, + AUDIO20_MD_CTRL_ENABLE = 0x01, + AUDIO20_MD_CTRL_BALANCE = 0x02, + AUDIO20_MD_CTRL_RATE = 0x03, + AUDIO20_MD_CTRL_DEPTH = 0x04, + AUDIO20_MD_CTRL_TIME = 0x05, + AUDIO20_MD_CTRL_FEEDBACK = 0x06, + AUDIO20_MD_CTRL_UNDERFLOW = 0x07, + AUDIO20_MD_CTRL_OVERFLOW = 0x08, + AUDIO20_MD_CTRL_LATENCY = 0x09, } audio20_modulation_delay_control_selector_t; /// A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors -typedef enum -{ - AUDIO20_DR_CTRL_UNDEF = 0x00, - AUDIO20_DR_CTRL_ENABLE = 0x01, - AUDIO20_DR_CTRL_COMPRESSION_RATE = 0x02, - AUDIO20_DR_CTRL_MAXAMPL = 0x03, - AUDIO20_DR_CTRL_THRESHOLD = 0x04, - AUDIO20_DR_CTRL_ATTACK_TIME = 0x05, - AUDIO20_DR_CTRL_RELEASE_TIME = 0x06, - AUDIO20_DR_CTRL_UNDERFLOW = 0x07, - AUDIO20_DR_CTRL_OVERFLOW = 0x08, - AUDIO20_DR_CTRL_LATENCY = 0x09, +typedef enum { + AUDIO20_DR_CTRL_UNDEF = 0x00, + AUDIO20_DR_CTRL_ENABLE = 0x01, + AUDIO20_DR_CTRL_COMPRESSION_RATE = 0x02, + AUDIO20_DR_CTRL_MAXAMPL = 0x03, + AUDIO20_DR_CTRL_THRESHOLD = 0x04, + AUDIO20_DR_CTRL_ATTACK_TIME = 0x05, + AUDIO20_DR_CTRL_RELEASE_TIME = 0x06, + AUDIO20_DR_CTRL_UNDERFLOW = 0x07, + AUDIO20_DR_CTRL_OVERFLOW = 0x08, + AUDIO20_DR_CTRL_LATENCY = 0x09, } audio20_dynamic_range_compression_control_selector_t; /// A.17.9 Processing Unit Control Selectors /// A.17.9.1 Up/Down-mix Processing Unit Control Selectors -typedef enum -{ - AUDIO20_UD_CTRL_UNDEF = 0x00, - AUDIO20_UD_CTRL_ENABLE = 0x01, - AUDIO20_UD_CTRL_MODE_SELECT = 0x02, - AUDIO20_UD_CTRL_CLUSTER = 0x03, - AUDIO20_UD_CTRL_UNDERFLOW = 0x04, - AUDIO20_UD_CTRL_OVERFLOW = 0x05, - AUDIO20_UD_CTRL_LATENCY = 0x06, +typedef enum { + AUDIO20_UD_CTRL_UNDEF = 0x00, + AUDIO20_UD_CTRL_ENABLE = 0x01, + AUDIO20_UD_CTRL_MODE_SELECT = 0x02, + AUDIO20_UD_CTRL_CLUSTER = 0x03, + AUDIO20_UD_CTRL_UNDERFLOW = 0x04, + AUDIO20_UD_CTRL_OVERFLOW = 0x05, + AUDIO20_UD_CTRL_LATENCY = 0x06, } audio20_up_down_mix_control_selector_t; /// A.17.9.2 Dolby Prologic ™ Processing Unit Control Selectors -typedef enum -{ - AUDIO20_DP_CTRL_UNDEF = 0x00, - AUDIO20_DP_CTRL_ENABLE = 0x01, - AUDIO20_DP_CTRL_MODE_SELECT = 0x02, - AUDIO20_DP_CTRL_CLUSTER = 0x03, - AUDIO20_DP_CTRL_UNDERFLOW = 0x04, - AUDIO20_DP_CTRL_OVERFLOW = 0x05, - AUDIO20_DP_CTRL_LATENCY = 0x06, +typedef enum { + AUDIO20_DP_CTRL_UNDEF = 0x00, + AUDIO20_DP_CTRL_ENABLE = 0x01, + AUDIO20_DP_CTRL_MODE_SELECT = 0x02, + AUDIO20_DP_CTRL_CLUSTER = 0x03, + AUDIO20_DP_CTRL_UNDERFLOW = 0x04, + AUDIO20_DP_CTRL_OVERFLOW = 0x05, + AUDIO20_DP_CTRL_LATENCY = 0x06, } audio20_dolby_prologic_control_selector_t; /// A.17.9.3 Stereo Extender Processing Unit Control Selectors -typedef enum -{ - AUDIO20_ST_EXT_CTRL_UNDEF = 0x00, - AUDIO20_ST_EXT_CTRL_ENABLE = 0x01, - AUDIO20_ST_EXT_CTRL_WIDTH = 0x02, - AUDIO20_ST_EXT_CTRL_UNDERFLOW = 0x03, - AUDIO20_ST_EXT_CTRL_OVERFLOW = 0x04, - AUDIO20_ST_EXT_CTRL_LATENCY = 0x05, +typedef enum { + AUDIO20_ST_EXT_CTRL_UNDEF = 0x00, + AUDIO20_ST_EXT_CTRL_ENABLE = 0x01, + AUDIO20_ST_EXT_CTRL_WIDTH = 0x02, + AUDIO20_ST_EXT_CTRL_UNDERFLOW = 0x03, + AUDIO20_ST_EXT_CTRL_OVERFLOW = 0x04, + AUDIO20_ST_EXT_CTRL_LATENCY = 0x05, } audio20_stereo_extender_control_selector_t; /// A.17.10 Extension Unit Control Selectors -typedef enum -{ - AUDIO20_XU_CTRL_UNDEF = 0x00, - AUDIO20_XU_CTRL_ENABLE = 0x01, - AUDIO20_XU_CTRL_CLUSTER = 0x02, - AUDIO20_XU_CTRL_UNDERFLOW = 0x03, - AUDIO20_XU_CTRL_OVERFLOW = 0x04, - AUDIO20_XU_CTRL_LATENCY = 0x05, +typedef enum { + AUDIO20_XU_CTRL_UNDEF = 0x00, + AUDIO20_XU_CTRL_ENABLE = 0x01, + AUDIO20_XU_CTRL_CLUSTER = 0x02, + AUDIO20_XU_CTRL_UNDERFLOW = 0x03, + AUDIO20_XU_CTRL_OVERFLOW = 0x04, + AUDIO20_XU_CTRL_LATENCY = 0x05, } audio20_extension_unit_control_selector_t; /// A.17.11 AudioStreaming Interface Control Selectors -typedef enum -{ - AUDIO20_AS_CTRL_UNDEF = 0x00, - AUDIO20_AS_CTRL_ACT_ALT_SETTING = 0x01, - AUDIO20_AS_CTRL_VAL_ALT_SETTINGS = 0x02, - AUDIO20_AS_CTRL_AUDIO_DATA_FORMAT = 0x03, +typedef enum { + AUDIO20_AS_CTRL_UNDEF = 0x00, + AUDIO20_AS_CTRL_ACT_ALT_SETTING = 0x01, + AUDIO20_AS_CTRL_VAL_ALT_SETTINGS = 0x02, + AUDIO20_AS_CTRL_AUDIO_DATA_FORMAT = 0x03, } audio20_audiostreaming_interface_control_selector_t; /// A.17.12 Encoder Control Selectors -typedef enum -{ - AUDIO20_EN_CTRL_UNDEF = 0x00, - AUDIO20_EN_CTRL_BIT_RATE = 0x01, - AUDIO20_EN_CTRL_QUALITY = 0x02, - AUDIO20_EN_CTRL_VBR = 0x03, - AUDIO20_EN_CTRL_TYPE = 0x04, - AUDIO20_EN_CTRL_UNDERFLOW = 0x05, - AUDIO20_EN_CTRL_OVERFLOW = 0x06, - AUDIO20_EN_CTRL_ENCODER_ERROR = 0x07, - AUDIO20_EN_CTRL_PARAM1 = 0x08, - AUDIO20_EN_CTRL_PARAM2 = 0x09, - AUDIO20_EN_CTRL_PARAM3 = 0x0A, - AUDIO20_EN_CTRL_PARAM4 = 0x0B, - AUDIO20_EN_CTRL_PARAM5 = 0x0C, - AUDIO20_EN_CTRL_PARAM6 = 0x0D, - AUDIO20_EN_CTRL_PARAM7 = 0x0E, - AUDIO20_EN_CTRL_PARAM8 = 0x0F, +typedef enum { + AUDIO20_EN_CTRL_UNDEF = 0x00, + AUDIO20_EN_CTRL_BIT_RATE = 0x01, + AUDIO20_EN_CTRL_QUALITY = 0x02, + AUDIO20_EN_CTRL_VBR = 0x03, + AUDIO20_EN_CTRL_TYPE = 0x04, + AUDIO20_EN_CTRL_UNDERFLOW = 0x05, + AUDIO20_EN_CTRL_OVERFLOW = 0x06, + AUDIO20_EN_CTRL_ENCODER_ERROR = 0x07, + AUDIO20_EN_CTRL_PARAM1 = 0x08, + AUDIO20_EN_CTRL_PARAM2 = 0x09, + AUDIO20_EN_CTRL_PARAM3 = 0x0A, + AUDIO20_EN_CTRL_PARAM4 = 0x0B, + AUDIO20_EN_CTRL_PARAM5 = 0x0C, + AUDIO20_EN_CTRL_PARAM6 = 0x0D, + AUDIO20_EN_CTRL_PARAM7 = 0x0E, + AUDIO20_EN_CTRL_PARAM8 = 0x0F, } audio20_encoder_control_selector_t; /// A.17.13 Decoder Control Selectors /// A.17.13.1 MPEG Decoder Control Selectors -typedef enum -{ - AUDIO20_MPD_CTRL_UNDEF = 0x00, - AUDIO20_MPD_CTRL_DUAL_CHANNEL = 0x01, - AUDIO20_MPD_CTRL_SECOND_STEREO = 0x02, - AUDIO20_MPD_CTRL_MULTILINGUAL = 0x03, - AUDIO20_MPD_CTRL_DYN_RANGE = 0x04, - AUDIO20_MPD_CTRL_SCALING = 0x05, - AUDIO20_MPD_CTRL_HILO_SCALING = 0x06, - AUDIO20_MPD_CTRL_UNDERFLOW = 0x07, - AUDIO20_MPD_CTRL_OVERFLOW = 0x08, - AUDIO20_MPD_CTRL_DECODER_ERROR = 0x09, +typedef enum { + AUDIO20_MPD_CTRL_UNDEF = 0x00, + AUDIO20_MPD_CTRL_DUAL_CHANNEL = 0x01, + AUDIO20_MPD_CTRL_SECOND_STEREO = 0x02, + AUDIO20_MPD_CTRL_MULTILINGUAL = 0x03, + AUDIO20_MPD_CTRL_DYN_RANGE = 0x04, + AUDIO20_MPD_CTRL_SCALING = 0x05, + AUDIO20_MPD_CTRL_HILO_SCALING = 0x06, + AUDIO20_MPD_CTRL_UNDERFLOW = 0x07, + AUDIO20_MPD_CTRL_OVERFLOW = 0x08, + AUDIO20_MPD_CTRL_DECODER_ERROR = 0x09, } audio20_MPEG_decoder_control_selector_t; /// A.17.13.2 AC-3 Decoder Control Selectors -typedef enum -{ - AUDIO20_AD_CTRL_UNDEF = 0x00, - AUDIO20_AD_CTRL_MODE = 0x01, - AUDIO20_AD_CTRL_DYN_RANGE = 0x02, - AUDIO20_AD_CTRL_SCALING = 0x03, - AUDIO20_AD_CTRL_HILO_SCALING = 0x04, - AUDIO20_AD_CTRL_UNDERFLOW = 0x05, - AUDIO20_AD_CTRL_OVERFLOW = 0x06, - AUDIO20_AD_CTRL_DECODER_ERROR = 0x07, +typedef enum { + AUDIO20_AD_CTRL_UNDEF = 0x00, + AUDIO20_AD_CTRL_MODE = 0x01, + AUDIO20_AD_CTRL_DYN_RANGE = 0x02, + AUDIO20_AD_CTRL_SCALING = 0x03, + AUDIO20_AD_CTRL_HILO_SCALING = 0x04, + AUDIO20_AD_CTRL_UNDERFLOW = 0x05, + AUDIO20_AD_CTRL_OVERFLOW = 0x06, + AUDIO20_AD_CTRL_DECODER_ERROR = 0x07, } audio20_AC3_decoder_control_selector_t; /// A.17.13.3 WMA Decoder Control Selectors -typedef enum -{ - AUDIO20_WD_CTRL_UNDEF = 0x00, - AUDIO20_WD_CTRL_UNDERFLOW = 0x01, - AUDIO20_WD_CTRL_OVERFLOW = 0x02, - AUDIO20_WD_CTRL_DECODER_ERROR = 0x03, +typedef enum { + AUDIO20_WD_CTRL_UNDEF = 0x00, + AUDIO20_WD_CTRL_UNDERFLOW = 0x01, + AUDIO20_WD_CTRL_OVERFLOW = 0x02, + AUDIO20_WD_CTRL_DECODER_ERROR = 0x03, } audio20_WMA_decoder_control_selector_t; /// A.17.13.4 DTS Decoder Control Selectors -typedef enum -{ - AUDIO20_DD_CTRL_UNDEF = 0x00, - AUDIO20_DD_CTRL_UNDERFLOW = 0x01, - AUDIO20_DD_CTRL_OVERFLOW = 0x02, - AUDIO20_DD_CTRL_DECODER_ERROR = 0x03, +typedef enum { + AUDIO20_DD_CTRL_UNDEF = 0x00, + AUDIO20_DD_CTRL_UNDERFLOW = 0x01, + AUDIO20_DD_CTRL_OVERFLOW = 0x02, + AUDIO20_DD_CTRL_DECODER_ERROR = 0x03, } audio20_DTS_decoder_control_selector_t; /// A.17.14 Endpoint Control Selectors -typedef enum -{ - AUDIO20_EP_CTRL_UNDEF = 0x00, - AUDIO20_EP_CTRL_PITCH = 0x01, - AUDIO20_EP_CTRL_DATA_OVERRUN = 0x02, - AUDIO20_EP_CTRL_DATA_UNDERRUN = 0x03, +typedef enum { + AUDIO20_EP_CTRL_UNDEF = 0x00, + AUDIO20_EP_CTRL_PITCH = 0x01, + AUDIO20_EP_CTRL_DATA_OVERRUN = 0x02, + AUDIO20_EP_CTRL_DATA_UNDERRUN = 0x03, } audio20_EP_control_selector_t; -/// Terminal Types - -/// 2.1 - Audio Class-Terminal Types UAC2 -typedef enum -{ - AUDIO20_TERM_TYPE_USB_UNDEFINED = 0x0100, - AUDIO20_TERM_TYPE_USB_STREAMING = 0x0101, - AUDIO20_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF, -} audio20_terminal_type_t; - -/// 2.2 - Audio Class-Input Terminal Types UAC2 -typedef enum -{ - AUDIO20_TERM_TYPE_IN_UNDEFINED = 0x0200, - AUDIO20_TERM_TYPE_IN_GENERIC_MIC = 0x0201, - AUDIO20_TERM_TYPE_IN_DESKTOP_MIC = 0x0202, - AUDIO20_TERM_TYPE_IN_PERSONAL_MIC = 0x0203, - AUDIO20_TERM_TYPE_IN_OMNI_MIC = 0x0204, - AUDIO20_TERM_TYPE_IN_ARRAY_MIC = 0x0205, - AUDIO20_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206, -} audio20_terminal_input_type_t; - -/// 2.3 - Audio Class-Output Terminal Types UAC2 -typedef enum -{ - AUDIO20_TERM_TYPE_OUT_UNDEFINED = 0x0300, - AUDIO20_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301, - AUDIO20_TERM_TYPE_OUT_HEADPHONES = 0x0302, - AUDIO20_TERM_TYPE_OUT_HEAD_MNT_DISP_AUIDO = 0x0303, - AUDIO20_TERM_TYPE_OUT_DESKTOP_SPEAKER = 0x0304, - AUDIO20_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305, - AUDIO20_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306, - AUDIO20_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307, -} audio20_terminal_output_type_t; - -/// Rest is yet to be implemented - /// Additional Audio Device Class Codes - Source: Audio Data Formats /// A.1 - Audio Class-Format Type Codes UAC2 -typedef enum -{ - AUDIO20_FORMAT_TYPE_UNDEFINED = 0x00, - AUDIO20_FORMAT_TYPE_I = 0x01, - AUDIO20_FORMAT_TYPE_II = 0x02, - AUDIO20_FORMAT_TYPE_III = 0x03, - AUDIO20_FORMAT_TYPE_IV = 0x04, - AUDIO20_EXT_FORMAT_TYPE_I = 0x81, - AUDIO20_EXT_FORMAT_TYPE_II = 0x82, - AUDIO20_EXT_FORMAT_TYPE_III = 0x83, +typedef enum { + AUDIO20_FORMAT_TYPE_UNDEFINED = 0x00, + AUDIO20_FORMAT_TYPE_I = 0x01, + AUDIO20_FORMAT_TYPE_II = 0x02, + AUDIO20_FORMAT_TYPE_III = 0x03, + AUDIO20_FORMAT_TYPE_IV = 0x04, + AUDIO20_EXT_FORMAT_TYPE_I = 0x81, + AUDIO20_EXT_FORMAT_TYPE_II = 0x82, + AUDIO20_EXT_FORMAT_TYPE_III = 0x83, } audio20_format_type_t; // A.2.1 - Audio Class-Audio Data Format Type I UAC2 -typedef enum -{ - AUDIO20_DATA_FORMAT_TYPE_I_PCM = (uint32_t) (1 << 0), - AUDIO20_DATA_FORMAT_TYPE_I_PCM8 = (uint32_t) (1 << 1), - AUDIO20_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), - AUDIO20_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), - AUDIO20_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO20_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, +typedef enum { + AUDIO20_DATA_FORMAT_TYPE_I_PCM = (uint32_t) (1 << 0), + AUDIO20_DATA_FORMAT_TYPE_I_PCM8 = (uint32_t) (1 << 1), + AUDIO20_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), + AUDIO20_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), + AUDIO20_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), + AUDIO20_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, } audio20_data_format_type_I_t; /// Audio Class-Audio Channel Configuration UAC2 (Table A-11) -typedef enum -{ - AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000, - AUDIO20_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001, - AUDIO20_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002, - AUDIO20_CHANNEL_CONFIG_FRONT_CENTER = 0x00000004, - AUDIO20_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x00000008, - AUDIO20_CHANNEL_CONFIG_BACK_LEFT = 0x00000010, - AUDIO20_CHANNEL_CONFIG_BACK_RIGHT = 0x00000020, +typedef enum { + AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000, + AUDIO20_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001, + AUDIO20_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002, + AUDIO20_CHANNEL_CONFIG_FRONT_CENTER = 0x00000004, + AUDIO20_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x00000008, + AUDIO20_CHANNEL_CONFIG_BACK_LEFT = 0x00000010, + AUDIO20_CHANNEL_CONFIG_BACK_RIGHT = 0x00000020, AUDIO20_CHANNEL_CONFIG_FRONT_LEFT_OF_CENTER = 0x00000040, AUDIO20_CHANNEL_CONFIG_FRONT_RIGHT_OF_CENTER = 0x00000080, - AUDIO20_CHANNEL_CONFIG_BACK_CENTER = 0x00000100, - AUDIO20_CHANNEL_CONFIG_SIDE_LEFT = 0x00000200, - AUDIO20_CHANNEL_CONFIG_SIDE_RIGHT = 0x00000400, - AUDIO20_CHANNEL_CONFIG_TOP_CENTER = 0x00000800, - AUDIO20_CHANNEL_CONFIG_TOP_FRONT_LEFT = 0x00001000, - AUDIO20_CHANNEL_CONFIG_TOP_FRONT_CENTER = 0x00002000, - AUDIO20_CHANNEL_CONFIG_TOP_FRONT_RIGHT = 0x00004000, - AUDIO20_CHANNEL_CONFIG_TOP_BACK_LEFT = 0x00008000, - AUDIO20_CHANNEL_CONFIG_TOP_BACK_CENTER = 0x00010000, - AUDIO20_CHANNEL_CONFIG_TOP_BACK_RIGHT = 0x00020000, + AUDIO20_CHANNEL_CONFIG_BACK_CENTER = 0x00000100, + AUDIO20_CHANNEL_CONFIG_SIDE_LEFT = 0x00000200, + AUDIO20_CHANNEL_CONFIG_SIDE_RIGHT = 0x00000400, + AUDIO20_CHANNEL_CONFIG_TOP_CENTER = 0x00000800, + AUDIO20_CHANNEL_CONFIG_TOP_FRONT_LEFT = 0x00001000, + AUDIO20_CHANNEL_CONFIG_TOP_FRONT_CENTER = 0x00002000, + AUDIO20_CHANNEL_CONFIG_TOP_FRONT_RIGHT = 0x00004000, + AUDIO20_CHANNEL_CONFIG_TOP_BACK_LEFT = 0x00008000, + AUDIO20_CHANNEL_CONFIG_TOP_BACK_CENTER = 0x00010000, + AUDIO20_CHANNEL_CONFIG_TOP_BACK_RIGHT = 0x00020000, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_LEFT_OF_CENTER = 0x00040000, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_RIGHT_OF_CENTER = 0x00080000, AUDIO20_CHANNEL_CONFIG_LEFT_LOW_FRQ_EFFECTS = 0x00100000, AUDIO20_CHANNEL_CONFIG_RIGHT_LOW_FRQ_EFFECTS = 0x00200000, - AUDIO20_CHANNEL_CONFIG_TOP_SIDE_LEFT = 0x00400000, - AUDIO20_CHANNEL_CONFIG_TOP_SIDE_RIGHT = 0x00800000, - AUDIO20_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, - AUDIO20_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, + AUDIO20_CHANNEL_CONFIG_TOP_SIDE_LEFT = 0x00400000, + AUDIO20_CHANNEL_CONFIG_TOP_SIDE_RIGHT = 0x00800000, + AUDIO20_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, + AUDIO20_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO20_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO20_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO20_CHANNEL_CONFIG_RAW_DATA = 0x80000000, } audio20_channel_config_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification /// Audio Class-Control Values UAC2 -typedef enum -{ - AUDIO20_CTRL_NONE = 0x00, ///< No Host access - AUDIO20_CTRL_R = 0x01, ///< Host read access only - AUDIO20_CTRL_RW = 0x03, ///< Host read write access +typedef enum { + AUDIO20_CTRL_NONE = 0x00,///< No Host access + AUDIO20_CTRL_R = 0x01, ///< Host read access only + AUDIO20_CTRL_RW = 0x03, ///< Host read write access } audio20_control_t; /// Audio Class-Specific AC Interface Descriptor Controls UAC2 -typedef enum -{ - AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0, +typedef enum { + AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0, } audio20_cs_ac_interface_control_pos_t; /// Audio Class-Specific AS Interface Descriptor Controls UAC2 -typedef enum -{ - AUDIO20_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0, - AUDIO20_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2, +typedef enum { + AUDIO20_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0, + AUDIO20_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2, } audio20_cs_as_interface_control_pos_t; /// Audio Class-Specific AS Isochronous Data EP Attributes UAC2 -typedef enum -{ - AUDIO20_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, - AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00, +typedef enum { + AUDIO20_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, + AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00, } audio20_cs_as_iso_data_ep_attribute_t; /// Audio Class-Specific AS Isochronous Data EP Controls UAC2 -typedef enum -{ - AUDIO20_CS_AS_ISO_DATA_EP_CTRL_PITCH_POS = 0, - AUDIO20_CS_AS_ISO_DATA_EP_CTRL_DATA_OVERRUN_POS = 2, - AUDIO20_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4, +typedef enum { + AUDIO20_CS_AS_ISO_DATA_EP_CTRL_PITCH_POS = 0, + AUDIO20_CS_AS_ISO_DATA_EP_CTRL_DATA_OVERRUN_POS = 2, + AUDIO20_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4, } audio20_cs_as_iso_data_ep_control_pos_t; /// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC2 -typedef enum -{ - AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, - AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01, - AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, +typedef enum { + AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, + AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01, + AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, } audio20_cs_as_iso_data_ep_lock_delay_unit_t; /// Audio Class-Clock Source Attributes UAC2 -typedef enum -{ - AUDIO20_CLOCK_SOURCE_ATT_EXT_CLK = 0x00, - AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01, - AUDIO20_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02, - AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03, - AUDIO20_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04, +typedef enum { + AUDIO20_CLOCK_SOURCE_ATT_EXT_CLK = 0x00, + AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01, + AUDIO20_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02, + AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03, + AUDIO20_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04, } audio20_clock_source_attribute_t; /// Audio Class-Clock Source Controls UAC2 -typedef enum -{ - AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0, - AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2, +typedef enum { + AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0, + AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2, } audio20_clock_source_control_pos_t; /// Audio Class-Clock Selector Controls UAC2 -typedef enum -{ - AUDIO20_CLOCK_SELECTOR_CTRL_POS = 0, +typedef enum { + AUDIO20_CLOCK_SELECTOR_CTRL_POS = 0, } audio20_clock_selector_control_pos_t; /// Audio Class-Clock Multiplier Controls UAC2 -typedef enum -{ - AUDIO20_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0, - AUDIO20_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2, +typedef enum { + AUDIO20_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0, + AUDIO20_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2, } audio20_clock_multiplier_control_pos_t; /// Audio Class-Input Terminal Controls UAC2 -typedef enum -{ - AUDIO20_IN_TERM_CTRL_CPY_PROT_POS = 0, - AUDIO20_IN_TERM_CTRL_CONNECTOR_POS = 2, - AUDIO20_IN_TERM_CTRL_OVERLOAD_POS = 4, - AUDIO20_IN_TERM_CTRL_CLUSTER_POS = 6, - AUDIO20_IN_TERM_CTRL_UNDERFLOW_POS = 8, - AUDIO20_IN_TERM_CTRL_OVERFLOW_POS = 10, +typedef enum { + AUDIO20_IN_TERM_CTRL_CPY_PROT_POS = 0, + AUDIO20_IN_TERM_CTRL_CONNECTOR_POS = 2, + AUDIO20_IN_TERM_CTRL_OVERLOAD_POS = 4, + AUDIO20_IN_TERM_CTRL_CLUSTER_POS = 6, + AUDIO20_IN_TERM_CTRL_UNDERFLOW_POS = 8, + AUDIO20_IN_TERM_CTRL_OVERFLOW_POS = 10, } audio20_terminal_input_control_pos_t; /// Audio Class-Output Terminal Controls UAC2 -typedef enum -{ - AUDIO20_OUT_TERM_CTRL_CPY_PROT_POS = 0, - AUDIO20_OUT_TERM_CTRL_CONNECTOR_POS = 2, - AUDIO20_OUT_TERM_CTRL_OVERLOAD_POS = 4, - AUDIO20_OUT_TERM_CTRL_UNDERFLOW_POS = 6, - AUDIO20_OUT_TERM_CTRL_OVERFLOW_POS = 8, +typedef enum { + AUDIO20_OUT_TERM_CTRL_CPY_PROT_POS = 0, + AUDIO20_OUT_TERM_CTRL_CONNECTOR_POS = 2, + AUDIO20_OUT_TERM_CTRL_OVERLOAD_POS = 4, + AUDIO20_OUT_TERM_CTRL_UNDERFLOW_POS = 6, + AUDIO20_OUT_TERM_CTRL_OVERFLOW_POS = 8, } audio20_terminal_output_control_pos_t; /// Audio Class-Feature Unit Controls UAC2 -typedef enum -{ - AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS = 0, - AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS = 2, - AUDIO20_FEATURE_UNIT_CTRL_BASS_POS = 4, - AUDIO20_FEATURE_UNIT_CTRL_MID_POS = 6, - AUDIO20_FEATURE_UNIT_CTRL_TREBLE_POS = 8, - AUDIO20_FEATURE_UNIT_CTRL_GRAPHIC_EQU_POS = 10, - AUDIO20_FEATURE_UNIT_CTRL_AGC_POS = 12, - AUDIO20_FEATURE_UNIT_CTRL_DELAY_POS = 14, - AUDIO20_FEATURE_UNIT_CTRL_BASS_BOOST_POS = 16, - AUDIO20_FEATURE_UNIT_CTRL_LOUDNESS_POS = 18, - AUDIO20_FEATURE_UNIT_CTRL_INPUT_GAIN_POS = 20, - AUDIO20_FEATURE_UNIT_CTRL_INPUT_GAIN_PAD_POS = 22, - AUDIO20_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24, - AUDIO20_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26, - AUDIO20_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28, +typedef enum { + AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS = 0, + AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS = 2, + AUDIO20_FEATURE_UNIT_CTRL_BASS_POS = 4, + AUDIO20_FEATURE_UNIT_CTRL_MID_POS = 6, + AUDIO20_FEATURE_UNIT_CTRL_TREBLE_POS = 8, + AUDIO20_FEATURE_UNIT_CTRL_GRAPHIC_EQU_POS = 10, + AUDIO20_FEATURE_UNIT_CTRL_AGC_POS = 12, + AUDIO20_FEATURE_UNIT_CTRL_DELAY_POS = 14, + AUDIO20_FEATURE_UNIT_CTRL_BASS_BOOST_POS = 16, + AUDIO20_FEATURE_UNIT_CTRL_LOUDNESS_POS = 18, + AUDIO20_FEATURE_UNIT_CTRL_INPUT_GAIN_POS = 20, + AUDIO20_FEATURE_UNIT_CTRL_INPUT_GAIN_PAD_POS = 22, + AUDIO20_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24, + AUDIO20_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26, + AUDIO20_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28, } audio20_feature_unit_control_pos_t; //--------------------------------------------------------------------+ @@ -1048,282 +1013,276 @@ typedef enum /// AUDIO Channel Cluster Descriptor UAC2 (4.1) typedef struct TU_ATTR_PACKED { - uint8_t bNrChannels; ///< Number of channels currently connected. - audio20_channel_config_t bmChannelConfig; ///< Bitmap according to 'audio20_channel_config_t' with a 1 set if channel is connected and 0 else. In case channels are non-predefined ignore them here (see UAC2 specification 4.1 Audio Channel Cluster Descriptor. - uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first inserted channel with a non-predefined spatial location. + uint8_t bNrChannels; ///< Number of channels currently connected. + audio20_channel_config_t bmChannelConfig;///< Bitmap according to 'audio20_channel_config_t' with a 1 set if channel is connected and 0 else. In case channels are non-predefined ignore them here (see UAC2 specification 4.1 Audio Channel Cluster Descriptor. + uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first inserted channel with a non-predefined spatial location. } audio20_desc_channel_cluster_t; /// AUDIO Class-Specific AC Interface Header Descriptor UAC2 (4.7.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor in bytes: 9. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_HEADER. - uint16_t bcdADC ; ///< Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: U16_TO_U8S_LE(0x0200). - uint8_t bCategory ; ///< Constant, indicating the primary use of this audio function, as intended by the manufacturer. See: audio20_function_code_t. - uint16_t wTotalLength ; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors. - uint8_t bmControls ; ///< See: audio20_cs_ac_interface_control_pos_t. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 9. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_HEADER. + uint16_t bcdADC; ///< Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: U16_TO_U8S_LE(0x0200). + uint8_t bCategory; ///< Constant, indicating the primary use of this audio function, as intended by the manufacturer. See: audio20_function_code_t. + uint16_t wTotalLength; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors. + uint8_t bmControls; ///< See: audio20_cs_ac_interface_control_pos_t. } audio20_desc_cs_ac_interface_t; TU_VERIFY_STATIC(sizeof(audio20_desc_cs_ac_interface_t) == 9, "size is not correct"); /// AUDIO Clock Source Descriptor UAC2 (4.7.2.1) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor in bytes: 8. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE. - uint8_t bClockID ; ///< Constant uniquely identifying the Clock Source Entity within the audio function. This value is used in all requests to address this Entity. - uint8_t bmAttributes ; ///< See: audio20_clock_source_attribute_t. - uint8_t bmControls ; ///< See: audio20_clock_source_control_pos_t. - uint8_t bAssocTerminal ; ///< Terminal ID of the Terminal that is associated with this Clock Source. - uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Source Entity. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor in bytes: 8. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE. + uint8_t bClockID; ///< Constant uniquely identifying the Clock Source Entity within the audio function. This value is used in all requests to address this Entity. + uint8_t bmAttributes; ///< See: audio20_clock_source_attribute_t. + uint8_t bmControls; ///< See: audio20_clock_source_control_pos_t. + uint8_t bAssocTerminal; ///< Terminal ID of the Terminal that is associated with this Clock Source. + uint8_t iClockSource; ///< Index of a string descriptor, describing the Clock Source Entity. } audio20_desc_clock_source_t; /// AUDIO Clock Selector Descriptor UAC2 (4.7.2.2) for ONE pin -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 7+p. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_SELECTOR. - uint8_t bClockID ; ///< Constant uniquely identifying the Clock Selector Entity within the audio function. This value is used in all requests to address this Entity. - uint8_t bNrInPins ; ///< Number of Input Pins of this Unit: p = 1 thus bNrInPins = 1. - uint8_t baCSourceID ; ///< ID of the Clock Entity to which the first Clock Input Pin of this Clock Selector Entity is connected.. - uint8_t bmControls ; ///< See: audio20_clock_selector_control_pos_t. - uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Selector Entity. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 7+p. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_SELECTOR. + uint8_t bClockID; ///< Constant uniquely identifying the Clock Selector Entity within the audio function. This value is used in all requests to address this Entity. + uint8_t bNrInPins; ///< Number of Input Pins of this Unit: p = 1 thus bNrInPins = 1. + uint8_t baCSourceID; ///< ID of the Clock Entity to which the first Clock Input Pin of this Clock Selector Entity is connected.. + uint8_t bmControls; ///< See: audio20_clock_selector_control_pos_t. + uint8_t iClockSource; ///< Index of a string descriptor, describing the Clock Selector Entity. } audio20_desc_clock_selector_t; /// AUDIO Clock Selector Descriptor (4.7.2.2) for multiple pins #define audio20_desc_clock_selector_n_t(source_num) \ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; \ - uint8_t bDescriptorType ; \ - uint8_t bDescriptorSubType ; \ - uint8_t bClockID ; \ - uint8_t bNrInPins ; \ - struct TU_ATTR_PACKED { \ - uint8_t baSourceID ; \ - } sourceID[source_num] ; \ - uint8_t bmControls ; \ - uint8_t iClockSource ; \ -} + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bClockID; \ + uint8_t bNrInPins; \ + struct TU_ATTR_PACKED { \ + uint8_t baSourceID; \ + } sourceID[source_num]; \ + uint8_t bmControls; \ + uint8_t iClockSource; \ + } /// AUDIO Clock Multiplier Descriptor UAC2 (4.7.2.3) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 7. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_MULTIPLIER. - uint8_t bClockID ; ///< Constant uniquely identifying the Clock Multiplier Entity within the audio function. This value is used in all requests to address this Entity. - uint8_t bCSourceID ; ///< ID of the Clock Entity to which the last Clock Input Pin of this Clock Selector Entity is connected. - uint8_t bmControls ; ///< See: audio20_clock_multiplier_control_pos_t. - uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Multiplier Entity. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 7. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_MULTIPLIER. + uint8_t bClockID; ///< Constant uniquely identifying the Clock Multiplier Entity within the audio function. This value is used in all requests to address this Entity. + uint8_t bCSourceID; ///< ID of the Clock Entity to which the last Clock Input Pin of this Clock Selector Entity is connected. + uint8_t bmControls; ///< See: audio20_clock_multiplier_control_pos_t. + uint8_t iClockSource; ///< Index of a string descriptor, describing the Clock Multiplier Entity. } audio20_desc_clock_multiplier_t; /// AUDIO Input Terminal Descriptor(4.7.2.4) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 17. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL. - uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this terminal. - uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_input_type_t for other input types. - uint8_t bAssocTerminal ; ///< ID of the Output Terminal to which this Input Terminal is associated. - uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Input Terminal is connected. - uint8_t bNrChannels ; ///< Number of logical output channels in the Terminal’s output audio channel cluster. - uint32_t bmChannelConfig ; ///< Describes the spatial location of the logical channels. See:audio20_channel_config_t. - uint8_t iChannelNames ; ///< Index of a string descriptor, describing the name of the first logical channel. - uint16_t bmControls ; ///< See: audio_terminal_input_control_pos_t. - uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 17. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL. + uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this terminal. + uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_input_type_t for other input types. + uint8_t bAssocTerminal; ///< ID of the Output Terminal to which this Input Terminal is associated. + uint8_t bCSourceID; ///< ID of the Clock Entity to which this Input Terminal is connected. + uint8_t bNrChannels; ///< Number of logical output channels in the Terminal’s output audio channel cluster. + uint32_t bmChannelConfig; ///< Describes the spatial location of the logical channels. See:audio20_channel_config_t. + uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first logical channel. + uint16_t bmControls; ///< See: audio_terminal_input_control_pos_t. + uint8_t iTerminal; ///< Index of a string descriptor, describing the Input Terminal. } audio20_desc_input_terminal_t; /// AUDIO Output Terminal Descriptor UAC2 (4.7.2.5) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 12. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL. - uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this Terminal. - uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio20_terminal_type_t for USB streaming and audio20_terminal_output_type_t for other output types. - uint8_t bAssocTerminal ; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. - uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Terminal is connected. - uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Output Terminal is connected. - uint16_t bmControls ; ///< See: audio20_terminal_output_control_pos_t. - uint8_t iTerminal ; ///< Index of a string descriptor, describing the Output Terminal. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 12. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL. + uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this Terminal. + uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. See: audio20_terminal_type_t for USB streaming and audio20_terminal_output_type_t for other output types. + uint8_t bAssocTerminal; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. + uint8_t bSourceID; ///< ID of the Unit or Terminal to which this Terminal is connected. + uint8_t bCSourceID; ///< ID of the Clock Entity to which this Output Terminal is connected. + uint16_t bmControls; ///< See: audio20_terminal_output_control_pos_t. + uint8_t iTerminal; ///< Index of a string descriptor, describing the Output Terminal. } audio20_desc_output_terminal_t; /// AUDIO Feature Unit Descriptor UAC2 (4.7.2.8) for ONE channel -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 14. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT. - uint8_t bUnitID ; ///< Constant uniquely identifying the Unit within the audio function. This value is used in all requests to address this Unit. - uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Feature Unit is connected. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 14. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT. + uint8_t bUnitID; ///< Constant uniquely identifying the Unit within the audio function. This value is used in all requests to address this Unit. + uint8_t bSourceID; ///< ID of the Unit or Terminal to which this Feature Unit is connected. struct TU_ATTR_PACKED { - uint32_t bmaControls ; ///< See: audio20_feature_unit_control_pos_t. Controls0 is master channel 0 (always present) and Controls1 is logical channel 1. - } controls[2] ; - uint8_t iTerminal ; ///< Index of a string descriptor, describing this Feature Unit. + uint32_t bmaControls;///< See: audio20_feature_unit_control_pos_t. Controls0 is master channel 0 (always present) and Controls1 is logical channel 1. + } controls[2]; + uint8_t iTerminal;///< Index of a string descriptor, describing this Feature Unit. } audio20_desc_feature_unit_t; /// AUDIO Feature Unit Descriptor(4.7.2.8) for multiple channels -#define audio20_desc_feature_unit_n_t(ch_num)\ - struct TU_ATTR_PACKED { \ - uint8_t bLength ; /* 6+(ch_num+1)*4 */\ - uint8_t bDescriptorType ; \ - uint8_t bDescriptorSubType ; \ - uint8_t bUnitID ; \ - uint8_t bSourceID ; \ - struct TU_ATTR_PACKED { \ - uint32_t bmaControls ; \ - } controls[ch_num+1] ; \ - uint8_t iTerminal ; \ -} +#define audio20_desc_feature_unit_n_t(ch_num) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; /* 6+(ch_num+1)*4 */ \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bUnitID; \ + uint8_t bSourceID; \ + struct TU_ATTR_PACKED { \ + uint32_t bmaControls; \ + } controls[ch_num + 1]; \ + uint8_t iTerminal; \ + } /// AUDIO Class-Specific AS Interface Descriptor(4.9.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 16. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AS_INTERFACE_AS_GENERAL. - uint8_t bTerminalLink ; ///< The Terminal ID of the Terminal to which this interface is connected. - uint8_t bmControls ; ///< See: audio20_cs_as_interface_control_pos_t. - uint8_t bFormatType ; ///< Constant identifying the Format Type the AudioStreaming interface is using. See: audio20_format_type_t. - uint32_t bmFormats ; ///< The Audio Data Format(s) that can be used to communicate with this interface.See: audio20_data_format_type_I_t. - uint8_t bNrChannels ; ///< Number of physical channels in the AS Interface audio channel cluster. - uint32_t bmChannelConfig ; ///< Describes the spatial location of the physical channels. See: audio20_channel_config_t. - uint8_t iChannelNames ; ///< Index of a string descriptor, describing the name of the first physical channel. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 16. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AS_INTERFACE_AS_GENERAL. + uint8_t bTerminalLink; ///< The Terminal ID of the Terminal to which this interface is connected. + uint8_t bmControls; ///< See: audio20_cs_as_interface_control_pos_t. + uint8_t bFormatType; ///< Constant identifying the Format Type the AudioStreaming interface is using. See: audio20_format_type_t. + uint32_t bmFormats; ///< The Audio Data Format(s) that can be used to communicate with this interface.See: audio20_data_format_type_I_t. + uint8_t bNrChannels; ///< Number of physical channels in the AS Interface audio channel cluster. + uint32_t bmChannelConfig; ///< Describes the spatial location of the physical channels. See: audio20_channel_config_t. + uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first physical channel. } audio20_desc_cs_as_interface_t; /// AUDIO Type I Format Type Descriptor(2.3.1.6 - Audio Formats) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 6. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE. - uint8_t bFormatType ; ///< Constant identifying the Format Type the AudioStreaming interface is using. Value: AUDIO20_FORMAT_TYPE_I. - uint8_t bSubslotSize ; ///< The number of bytes occupied by one audio subslot. Can be 1, 2, 3 or 4. - uint8_t bBitResolution ; ///< The number of effectively used bits from the available bits in an audio subslot. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 6. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE. + uint8_t bFormatType; ///< Constant identifying the Format Type the AudioStreaming interface is using. Value: AUDIO20_FORMAT_TYPE_I. + uint8_t bSubslotSize; ///< The number of bytes occupied by one audio subslot. Can be 1, 2, 3 or 4. + uint8_t bBitResolution; ///< The number of effectively used bits from the available bits in an audio subslot. } audio20_desc_type_I_format_t; /// AUDIO Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) -typedef struct TU_ATTR_PACKED -{ - uint8_t bLength ; ///< Size of this descriptor, in bytes: 8. - uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. - uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO20_CS_EP_SUBTYPE_GENERAL. - uint8_t bmAttributes ; ///< See: audio20_cs_as_iso_data_ep_attribute_t. - uint8_t bmControls ; ///< See: audio20_cs_as_iso_data_ep_control_pos_t. - uint8_t bLockDelayUnits ; ///< Indicates the units used for the wLockDelay field. See: audio20_cs_as_iso_data_ep_lock_delay_unit_t. - uint16_t wLockDelay ; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. Units used depend on the value of the bLockDelayUnits field. +typedef struct TU_ATTR_PACKED { + uint8_t bLength; ///< Size of this descriptor, in bytes: 8. + uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. + uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_EP_SUBTYPE_GENERAL. + uint8_t bmAttributes; ///< See: audio20_cs_as_iso_data_ep_attribute_t. + uint8_t bmControls; ///< See: audio20_cs_as_iso_data_ep_control_pos_t. + uint8_t bLockDelayUnits; ///< Indicates the units used for the wLockDelay field. See: audio20_cs_as_iso_data_ep_lock_delay_unit_t. + uint16_t wLockDelay; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. Units used depend on the value of the bLockDelayUnits field. } audio20_desc_cs_as_iso_data_ep_t; // 5.2.2 Control Request Layout -typedef struct TU_ATTR_PACKED -{ - union - { - struct TU_ATTR_PACKED - { - uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. - uint8_t type : 2; ///< Request type tusb_request_type_t. - uint8_t direction : 1; ///< Direction type. tusb_dir_t - } bmRequestType_bit; - - uint8_t bmRequestType; - }; +typedef struct TU_ATTR_PACKED { + union { + struct TU_ATTR_PACKED { + uint8_t recipient : 5;///< Recipient type tusb_request_recipient_t. + uint8_t type : 2; ///< Request type tusb_request_type_t. + uint8_t direction : 1;///< Direction type. tusb_dir_t + } bmRequestType_bit; + + uint8_t bmRequestType; + }; - uint8_t bRequest; ///< Request type audio_cs_req_t - uint8_t bChannelNumber; - uint8_t bControlSelector; - union - { - uint8_t bInterface; - uint8_t bEndpoint; - }; - uint8_t bEntityID; - uint16_t wLength; + uint8_t bRequest;///< Request type audio_cs_req_t + uint8_t bChannelNumber; + uint8_t bControlSelector; + union { + uint8_t bInterface; + uint8_t bEndpoint; + }; + uint8_t bEntityID; + uint16_t wLength; } audio20_control_request_t; //// 5.2.3 Control Request Parameter Block Layout // 5.2.3.1 1-byte Control CUR Parameter Block -typedef struct TU_ATTR_PACKED -{ - int8_t bCur ; ///< The setting for the CUR attribute of the addressed Control +typedef struct TU_ATTR_PACKED { + int8_t bCur;///< The setting for the CUR attribute of the addressed Control } audio20_control_cur_1_t; // 5.2.3.2 2-byte Control CUR Parameter Block -typedef struct TU_ATTR_PACKED -{ - int16_t bCur ; ///< The setting for the CUR attribute of the addressed Control +typedef struct TU_ATTR_PACKED { + int16_t bCur;///< The setting for the CUR attribute of the addressed Control } audio20_control_cur_2_t; // 5.2.3.3 4-byte Control CUR Parameter Block -typedef struct TU_ATTR_PACKED -{ - int32_t bCur ; ///< The setting for the CUR attribute of the addressed Control +typedef struct TU_ATTR_PACKED { + int32_t bCur;///< The setting for the CUR attribute of the addressed Control } audio20_control_cur_4_t; // Use the following ONLY for RECEIVED data - compiler does not know how many subranges are defined! Use the #define macros below for predefined lengths. // 5.2.3.1 1-byte Control RANGE Parameter Block -#define audio20_control_range_1_n_t(numSubRanges) \ - struct TU_ATTR_PACKED { \ - uint16_t wNumSubRanges; \ - struct TU_ATTR_PACKED { \ - int8_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\ - int8_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\ - uint8_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\ - } subrange[numSubRanges] ; \ -} +#define audio20_control_range_1_n_t(numSubRanges) \ + struct TU_ATTR_PACKED { \ + uint16_t wNumSubRanges; \ + struct TU_ATTR_PACKED { \ + int8_t bMin; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ \ + int8_t bMax; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ \ + uint8_t bRes; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ \ + } subrange[numSubRanges]; \ + } /// 5.2.3.2 2-byte Control RANGE Parameter Block -#define audio20_control_range_2_n_t(numSubRanges) \ - struct TU_ATTR_PACKED { \ - uint16_t wNumSubRanges; \ - struct TU_ATTR_PACKED { \ - int16_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\ - int16_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\ - uint16_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\ - } subrange[numSubRanges]; \ -} +#define audio20_control_range_2_n_t(numSubRanges) \ + struct TU_ATTR_PACKED { \ + uint16_t wNumSubRanges; \ + struct TU_ATTR_PACKED { \ + int16_t bMin; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ \ + int16_t bMax; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ \ + uint16_t bRes; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ \ + } subrange[numSubRanges]; \ + } // 5.2.3.3 4-byte Control RANGE Parameter Block -#define audio20_control_range_4_n_t(numSubRanges) \ - struct TU_ATTR_PACKED { \ - uint16_t wNumSubRanges; \ - struct TU_ATTR_PACKED { \ - int32_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\ - int32_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\ - uint32_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\ - } subrange[numSubRanges]; \ -} +#define audio20_control_range_4_n_t(numSubRanges) \ + struct TU_ATTR_PACKED { \ + uint16_t wNumSubRanges; \ + struct TU_ATTR_PACKED { \ + int32_t bMin; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ \ + int32_t bMax; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ \ + uint32_t bRes; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ \ + } subrange[numSubRanges]; \ + } // 6.1 Interrupt Data Message Format -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bInfo; uint8_t bAttribute; - union - { + union { uint16_t wValue; - struct - { + struct { uint8_t wValue_cn_or_mcn; uint8_t wValue_cs; }; }; - union - { + union { uint16_t wIndex; - struct - { + struct { uint8_t wIndex_ep_or_int; uint8_t wIndex_entity_id; }; }; } audio20_interrupt_data_t; +//--------------------------------------------------------------------+ +// APPLICATION HELPER DEFINITIONS +//--------------------------------------------------------------------+ + +// Combined Interrupt Data Message Format for both UAC1 and UAC2 +typedef union { + audio10_interrupt_data_t v1; + audio20_interrupt_data_t v2; +} audio_interrupt_data_t; + +// MIDI1.0 use the same CS AC Interface Descriptor as UAC1 +typedef audio10_desc_cs_ac_interface_n_t(1) midi10_desc_cs_ac_interface_t; + +// UAC1.0 AC Interface Descriptor with 1 interface, used to read fields other than baInterfaceNr +typedef audio10_desc_cs_ac_interface_n_t(1) audio10_desc_cs_ac_interface_1_t; + /** @} */ #ifdef __cplusplus diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index f795603c5..f56a27fd3 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -938,7 +938,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint } } } else if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL) { - if (tu_unaligned_read16(p_desc + 4) == AUDIO20_TERM_TYPE_USB_STREAMING) { + if (tu_unaligned_read16(p_desc + 4) == AUDIO_TERM_TYPE_USB_STREAMING) { _audiod_fct[i].bclock_id_tx = p_desc[8]; } } @@ -1090,7 +1090,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p // Open new EP if necessary - EPs are only to be closed or opened for AS interfaces - Look for AS interface with correct alternate interface uint8_t const *p_desc = tu_desc_next(audio->p_desc); // Skip entire AC descriptor block - p_desc += ((audio_desc_cs_ac_interface_t const *) p_desc)->wTotalLength; + p_desc += ((audio20_desc_cs_ac_interface_t const *) p_desc)->wTotalLength; // Get pointer at end uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 46b8284ee..8b78fe945 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -93,8 +93,6 @@ typedef struct { static midih_interface_t _midi_host[CFG_TUH_MIDI]; CFG_TUH_MEM_SECTION static midih_epbuf_t _midi_epbuf[CFG_TUH_MIDI]; -typedef audio10_desc_cs_ac_interface_n_t(1) midi10_desc_cs_ac_interface_t; - //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ @@ -226,7 +224,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d p_desc = tu_desc_next(p_desc); TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && - tu_desc_subtype(p_desc) == AUDIO_CS_AC_INTERFACE_HEADER); + tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_HEADER); desc_cb.desc_audio_control = desc_itf; p_desc = tu_desc_next(p_desc); diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 9c4699362..a9997ad3f 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -45,6 +45,13 @@ #define U16_TO_U8S_BE(_u16) TU_U16_HIGH(_u16), TU_U16_LOW(_u16) #define U16_TO_U8S_LE(_u16) TU_U16_LOW(_u16), TU_U16_HIGH(_u16) +#define TU_U24(_high, _mid, _low) ((uint32_t) (((_high) << 16) | ((_mid) << 8) | (_low))) +#define TU_U24_HIGH(_u24) ((uint8_t) (((_u24) >> 16) & 0x0000ff)) +#define TU_U24_MID(_u24) ((uint8_t) (((_u24) >> 8) & 0x0000ff)) +#define TU_U24_LOW(_u24) ((uint8_t) (((_u24) ) & 0x0000ff)) +#define U24_TO_U8S_BE(_u24) TU_U24_HIGH(_u24), TU_U24_MID(_u24), TU_U24_LOW(_u24) +#define U24_TO_U8S_LE(_u24) TU_U24_LOW(_u24), TU_U24_MID(_u24), TU_U24_HIGH(_u24) + #define TU_U32_BYTE3(_u32) ((uint8_t) ((((uint32_t) _u32) >> 24) & 0x000000ff)) // MSB #define TU_U32_BYTE2(_u32) ((uint8_t) ((((uint32_t) _u32) >> 16) & 0x000000ff)) #define TU_U32_BYTE1(_u32) ((uint8_t) ((((uint32_t) _u32) >> 8) & 0x000000ff)) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 9b33a6f61..b0dae6488 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -118,6 +118,18 @@ #define _TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s _TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7) #define _TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s _TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8) +// Apply an macro X to each of the arguments and expand the result wtih comma +#define TU_ARGS_APPLY_EXPAND(_X, ...) TU_XSTRCAT(_TU_ARGS_APPLY_EXPAND_, TU_ARGS_NUM(__VA_ARGS__))(_X, __VA_ARGS__) + +#define _TU_ARGS_APPLY_EXPAND_1(_X, _a1) _X(_a1) +#define _TU_ARGS_APPLY_EXPAND_2(_X, _a1, _a2) _X(_a1), _X(_a2) +#define _TU_ARGS_APPLY_EXPAND_3(_X, _a1, _a2, _a3) _X(_a1), _TU_ARGS_APPLY_EXPAND_2(_X, _a2, _a3) +#define _TU_ARGS_APPLY_EXPAND_4(_X, _a1, _a2, _a3, _a4) _X(_a1), _TU_ARGS_APPLY_EXPAND_3(_X, _a2, _a3, _a4) +#define _TU_ARGS_APPLY_EXPAND_5(_X, _a1, _a2, _a3, _a4, _a5) _X(_a1), _TU_ARGS_APPLY_EXPAND_4(_X, _a2, _a3, _a4, _a5) +#define _TU_ARGS_APPLY_EXPAND_6(_X, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1), _TU_ARGS_APPLY_EXPAND_5(_X, _a2, _a3, _a4, _a5, _a6) +#define _TU_ARGS_APPLY_EXPAND_7(_X, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1), _TU_ARGS_APPLY_EXPAND_6(_X, _a2, _a3, _a4, _a5, _a6, _a7) +#define _TU_ARGS_APPLY_EXPAND_8(_X, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1), _TU_ARGS_APPLY_EXPAND_7(_X, _a2, _a3, _a4, _a5, _a6, _a7, _a8) + //--------------------------------------------------------------------+ // Macro for function default arguments //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index 3e97a3482..3ed1015b6 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -364,238 +364,343 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ TUD_MIDI_JACKID_OUT_EMB(1) //--------------------------------------------------------------------+ -// Audio v2.0 Descriptor Templates -//--------------------------------------------------------------------+ +// Audio Descriptor Templates +//--------------------------------------------------------------------+ + + +/* Audio v1.0 Descriptor Templates */ + +/* Standard AC Interface Descriptor UAC1 (4.3.1) */ +#define TUD_AUDIO10_DESC_STD_AC_LEN 9 +#define TUD_AUDIO10_DESC_STD_AC(_itfnum, _nEPs, _stridx) \ + TUD_AUDIO10_DESC_STD_AC_LEN, TUSB_DESC_INTERFACE, _itfnum, 0x00, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_INT_PROTOCOL_CODE_V1, _stridx + +/* Class-Specific AC Interface Header Descriptor UAC1 (4.3.2) */ +#define TUD_AUDIO10_DESC_CS_AC_LEN(_nintfs) (8 + (_nintfs)) +// Class-Specific AC Interface Header descriptor, take list of streaming interface numbers as variable arguments +#define TUD_AUDIO10_DESC_CS_AC(_bcdADC, _totallen, ...) \ + TUD_AUDIO10_DESC_CS_AC_LEN(TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(_bcdADC), U16_TO_U8S_LE(_totallen + TUD_AUDIO10_DESC_CS_AC_LEN(TU_ARGS_NUM(__VA_ARGS__))), TU_ARGS_NUM(__VA_ARGS__), __VA_ARGS__ + +/* Input Terminal Descriptor UAC1 (4.3.2.1) */ +#define TUD_AUDIO10_DESC_INPUT_TERM_LEN 12 +#define TUD_AUDIO10_DESC_INPUT_TERM(_termid, _termtype, _assocTerm, _nchannels, _channelcfg, _idxchannelnames, _stridx) \ + TUD_AUDIO10_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _nchannels, U16_TO_U8S_LE(_channelcfg), _idxchannelnames, _stridx + +/* Output Terminal Descriptor UAC1 (4.3.2.2) */ +#define TUD_AUDIO10_DESC_OUTPUT_TERM_LEN 9 +#define TUD_AUDIO10_DESC_OUTPUT_TERM(_termid, _termtype, _assocTerm, _srcid, _stridx) \ + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _stridx + +/* Mixer Unit Descriptor UAC1 (4.3.2.3) - One Input Pin */ +#define TUD_AUDIO10_DESC_MIXER_UNIT_ONE_PIN_LEN(_ctrlsize) (11 + (_ctrlsize)) +#define TUD_AUDIO10_DESC_MIXER_UNIT_ONE_PIN(_unitid, _srcid, _nrchannels, _channelcfg, _idxchannelnames, _ctrlsize, _stridx, ...) \ + TUD_AUDIO10_DESC_MIXER_UNIT_ONE_PIN_LEN(_ctrlsize), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_MIXER_UNIT, _unitid, 1, _srcid, _nrchannels, U16_TO_U8S_LE(_channelcfg), _idxchannelnames, __VA_ARGS__, _stridx + +/* Selector Unit Descriptor UAC1 (4.3.2.4) - One Input Pin */ +#define TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN_LEN 7 +#define TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN(_unitid, _srcid, _stridx) \ + TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT, _unitid, 1, _srcid, _stridx + +/* Feature Unit Descriptor UAC1 (4.3.2.5) - Variable Channels */ +#define TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(_nchannels) (7 + (_nchannels + 1) * 2) +// Feature Unit descriptor, take list of control bitmaps for master channel + each channel as variable arguments +#define TUD_AUDIO10_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \ + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, 2, TU_ARGS_APPLY_EXPAND(U16_TO_U8S_LE, __VA_ARGS__), _stridx + +/* Standard AS Interface Descriptor UAC1 (4.5.1) */ +#define TUD_AUDIO10_DESC_STD_AS_LEN 9 +#define TUD_AUDIO10_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ + TUD_AUDIO10_DESC_STD_AS_LEN, TUSB_DESC_INTERFACE, _itfnum, _altset, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_STREAMING, AUDIO_INT_PROTOCOL_CODE_V1, _stridx + +/* Class-Specific AS Interface Descriptor UAC1 (4.5.2) */ +#define TUD_AUDIO10_DESC_CS_AS_INT_LEN 7 +#define TUD_AUDIO10_DESC_CS_AS_INT(_termid, _delay, _formattype) \ + TUD_AUDIO10_DESC_CS_AS_INT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AS_INTERFACE_AS_GENERAL, _termid, _delay, U16_TO_U8S_LE(_formattype) + +/* Type I Format Type Descriptor UAC1 (2.2.5) */ +#define TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs) (8 + (_nfreqs)*3) +// Type I Format descriptor, take list of sample rates in Hz as variable arguments +#define TUD_AUDIO10_DESC_TYPE_I_FORMAT(_nrchannels, _subframesize, _bitresolution, ...) \ + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO10_FORMAT_TYPE_I, _nrchannels, _subframesize, _bitresolution, TU_ARGS_NUM(__VA_ARGS__), TU_ARGS_APPLY_EXPAND(U24_TO_U8S_LE, __VA_ARGS__) + +/* Standard AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.1) */ +#define TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN 9 +#define TUD_AUDIO10_DESC_STD_AS_ISO_EP(_ep, _attr, _maxEPsize, _interval, _sync_ep) \ + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN, TUSB_DESC_ENDPOINT, _ep, _attr, U16_TO_U8S_LE(_maxEPsize), _interval, 0x00, _sync_ep + +/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.2) */ +#define TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN 7 +#define TUD_AUDIO10_DESC_CS_AS_ISO_EP(_attr, _lockdelayunits, _lockdelay) \ + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN, TUSB_DESC_CS_ENDPOINT, AUDIO10_CS_EP_SUBTYPE_GENERAL, _attr, _lockdelayunits, U16_TO_U8S_LE(_lockdelay) + +/* Standard AC Interrupt Endpoint Descriptor UAC1 (4.4.2) */ +#define TUD_AUDIO10_DESC_STD_AC_INT_EP_LEN 9 +#define TUD_AUDIO10_DESC_STD_AC_INT_EP(_ep, _interval) \ + TUD_AUDIO10_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(2), _interval, 0x00, 0x00 + +// AUDIO simple descriptor templates for UAC1 + +// AUDIO simple descriptor (UAC1) for 1 microphone input +// - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal + +#define TUD_AUDIO10_MIC_ONE_CH_DESC_LEN (\ + + TUD_AUDIO10_DESC_STD_AC_LEN\ + + TUD_AUDIO10_DESC_CS_AC_LEN(1)\ + + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(1)\ + + TUD_AUDIO10_DESC_STD_AS_LEN\ + + TUD_AUDIO10_DESC_STD_AS_LEN\ + + TUD_AUDIO10_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN) + +#define TUD_AUDIO10_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize, ...) \ + /* Standard AC Interface Descriptor(4.3.1) */\ + TUD_AUDIO10_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Class-Specific AC Interface Header Descriptor(4.3.2) */\ + TUD_AUDIO10_DESC_CS_AC(/*_bcdADC*/ 0x0100, /*_totallen*/ TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(1), /*_itf*/ ((_itfnum)+1)),\ + /* Input Terminal Descriptor(4.3.2.1) */\ + TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_nchannels*/ 0x01, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ + /* Output Terminal Descriptor(4.3.2.2) */\ + TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_stridx*/ 0x00),\ + /* Feature Unit Descriptor(4.3.2.5) */\ + TUD_AUDIO10_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlmaster*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch1*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME)),\ + /* Standard AS Interface Descriptor(4.5.1) */\ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.5.1) */\ + /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + /* Class-Specific AS Interface Descriptor(4.5.2) */\ + TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_delay*/ 0x00, /*_formattype*/ AUDIO10_DATA_FORMAT_TYPE_I_PCM),\ + /* Type I Format Type Descriptor(2.2.5) */\ + TUD_AUDIO10_DESC_TYPE_I_FORMAT(/*_nrchannels*/ 0x01, /*_subframesize*/ _nBytesPerSample, /*_bitresolution*/ _nBitsUsedPerSample, /*_freqtype*/ 0x01, /*_freq*/ _freq),\ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.6.1.1) */\ + TUD_AUDIO10_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01, /* _sync_ep */ 0x00),\ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.6.1.2) */\ + TUD_AUDIO10_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ, /*_lockdelayunits*/ AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001) + +/* Audio v2.0 Descriptor Templates */ /* Standard Interface Association Descriptor (IAD) */ -#define TUD_AUDIO_DESC_IAD_LEN 8 -#define TUD_AUDIO_DESC_IAD(_firstitf, _nitfs, _stridx) \ - TUD_AUDIO_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, _firstitf, _nitfs, TUSB_CLASS_AUDIO, AUDIO_FUNCTION_SUBCLASS_UNDEFINED, AUDIO_FUNC_PROTOCOL_CODE_V2, _stridx +#define TUD_AUDIO20_DESC_IAD_LEN 8 +#define TUD_AUDIO20_DESC_IAD(_firstitf, _nitfs, _stridx) \ + TUD_AUDIO20_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, _firstitf, _nitfs, TUSB_CLASS_AUDIO, AUDIO_FUNCTION_SUBCLASS_UNDEFINED, AUDIO_FUNC_PROTOCOL_CODE_V2, _stridx /* Standard AC Interface Descriptor(4.7.1) */ -#define TUD_AUDIO_DESC_STD_AC_LEN 9 -#define TUD_AUDIO_DESC_STD_AC(_itfnum, _nEPs, _stridx) /* _nEPs is 0 or 1 */\ - TUD_AUDIO_DESC_STD_AC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_INT_PROTOCOL_CODE_V2, _stridx +#define TUD_AUDIO20_DESC_STD_AC_LEN 9 +#define TUD_AUDIO20_DESC_STD_AC(_itfnum, _nEPs, _stridx) /* _nEPs is 0 or 1 */\ + TUD_AUDIO20_DESC_STD_AC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_INT_PROTOCOL_CODE_V2, _stridx /* Class-Specific AC Interface Header Descriptor(4.7.2) */ -#define TUD_AUDIO_DESC_CS_AC_LEN 9 -#define TUD_AUDIO_DESC_CS_AC(_bcdADC, _category, _totallen, _ctrl) /* _bcdADC : Audio Device Class Specification Release Number in Binary-Coded Decimal, _category : see audio20_function_t, _totallen : Total number of bytes returned for the class-specific AudioControl interface i.e. Clock Source, Unit and Terminal descriptors - Do not include TUD_AUDIO_DESC_CS_AC_LEN, we already do this here*/ \ - TUD_AUDIO_DESC_CS_AC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(_bcdADC), _category, U16_TO_U8S_LE(_totallen + TUD_AUDIO_DESC_CS_AC_LEN), _ctrl +#define TUD_AUDIO20_DESC_CS_AC_LEN 9 +#define TUD_AUDIO20_DESC_CS_AC(_bcdADC, _category, _totallen, _ctrl) /* _bcdADC : Audio Device Class Specification Release Number in Binary-Coded Decimal, _category : see audio20_function_t, _totallen : Total number of bytes returned for the class-specific AudioControl interface i.e. Clock Source, Unit and Terminal descriptors - Do not include TUD_AUDIO20_DESC_CS_AC_LEN, we already do this here*/ \ + TUD_AUDIO20_DESC_CS_AC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(_bcdADC), _category, U16_TO_U8S_LE(_totallen + TUD_AUDIO20_DESC_CS_AC_LEN), _ctrl /* Clock Source Descriptor(4.7.2.1) */ -#define TUD_AUDIO_DESC_CLK_SRC_LEN 8 -#define TUD_AUDIO_DESC_CLK_SRC(_clkid, _attr, _ctrl, _assocTerm, _stridx) \ - TUD_AUDIO_DESC_CLK_SRC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE, _clkid, _attr, _ctrl, _assocTerm, _stridx +#define TUD_AUDIO20_DESC_CLK_SRC_LEN 8 +#define TUD_AUDIO20_DESC_CLK_SRC(_clkid, _attr, _ctrl, _assocTerm, _stridx) \ + TUD_AUDIO20_DESC_CLK_SRC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE, _clkid, _attr, _ctrl, _assocTerm, _stridx /* Input Terminal Descriptor(4.7.2.4) */ -#define TUD_AUDIO_DESC_INPUT_TERM_LEN 17 -#define TUD_AUDIO_DESC_INPUT_TERM(_termid, _termtype, _assocTerm, _clkid, _nchannelslogical, _channelcfg, _idxchannelnames, _ctrl, _stridx) \ - TUD_AUDIO_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _clkid, _nchannelslogical, U32_TO_U8S_LE(_channelcfg), _idxchannelnames, U16_TO_U8S_LE(_ctrl), _stridx +#define TUD_AUDIO20_DESC_INPUT_TERM_LEN 17 +#define TUD_AUDIO20_DESC_INPUT_TERM(_termid, _termtype, _assocTerm, _clkid, _nchannelslogical, _channelcfg, _idxchannelnames, _ctrl, _stridx) \ + TUD_AUDIO20_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _clkid, _nchannelslogical, U32_TO_U8S_LE(_channelcfg), _idxchannelnames, U16_TO_U8S_LE(_ctrl), _stridx /* Output Terminal Descriptor(4.7.2.5) */ -#define TUD_AUDIO_DESC_OUTPUT_TERM_LEN 12 -#define TUD_AUDIO_DESC_OUTPUT_TERM(_termid, _termtype, _assocTerm, _srcid, _clkid, _ctrl, _stridx) \ - TUD_AUDIO_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _clkid, U16_TO_U8S_LE(_ctrl), _stridx +#define TUD_AUDIO20_DESC_OUTPUT_TERM_LEN 12 +#define TUD_AUDIO20_DESC_OUTPUT_TERM(_termid, _termtype, _assocTerm, _srcid, _clkid, _ctrl, _stridx) \ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _clkid, U16_TO_U8S_LE(_ctrl), _stridx /* Feature Unit Descriptor(4.7.2.8) */ -// 1 - Channel -#define TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN 6+(1+1)*4 -#define TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _stridx) \ - TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), _stridx - -// 2 - Channels -#define TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN (6+(2+1)*4) -#define TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _ctrlch2, _stridx) \ - TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), U32_TO_U8S_LE(_ctrlch2), _stridx -// 4 - Channels -#define TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN (6+(4+1)*4) -#define TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _ctrlch2, _ctrlch3, _ctrlch4, _stridx) \ - TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), U32_TO_U8S_LE(_ctrlch2), U32_TO_U8S_LE(_ctrlch3), U32_TO_U8S_LE(_ctrlch4), _stridx - -// For more channels, add definitions here +#define TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(_nchannels) (6 + (_nchannels + 1) * 4) +#define TUD_AUDIO20_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, TU_ARGS_APPLY_EXPAND(U32_TO_U8S_LE, __VA_ARGS__), _stridx /* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */ -#define TUD_AUDIO_DESC_STD_AC_INT_EP_LEN 7 -#define TUD_AUDIO_DESC_STD_AC_INT_EP(_ep, _interval) \ - TUD_AUDIO_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval +#define TUD_AUDIO20_DESC_STD_AC_INT_EP_LEN 7 +#define TUD_AUDIO20_DESC_STD_AC_INT_EP(_ep, _interval) \ + TUD_AUDIO20_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval /* Standard AS Interface Descriptor(4.9.1) */ -#define TUD_AUDIO_DESC_STD_AS_INT_LEN 9 -#define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ - TUD_AUDIO_DESC_STD_AS_INT_LEN, TUSB_DESC_INTERFACE, _itfnum, _altset, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_STREAMING, AUDIO_INT_PROTOCOL_CODE_V2, _stridx +#define TUD_AUDIO20_DESC_STD_AS_LEN 9 +#define TUD_AUDIO20_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ + TUD_AUDIO20_DESC_STD_AS_LEN, TUSB_DESC_INTERFACE, _itfnum, _altset, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_STREAMING, AUDIO_INT_PROTOCOL_CODE_V2, _stridx /* Class-Specific AS Interface Descriptor(4.9.2) */ -#define TUD_AUDIO_DESC_CS_AS_INT_LEN 16 -#define TUD_AUDIO_DESC_CS_AS_INT(_termid, _ctrl, _formattype, _formats, _nchannelsphysical, _channelcfg, _stridx) \ - TUD_AUDIO_DESC_CS_AS_INT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_AS_GENERAL, _termid, _ctrl, _formattype, U32_TO_U8S_LE(_formats), _nchannelsphysical, U32_TO_U8S_LE(_channelcfg), _stridx +#define TUD_AUDIO20_DESC_CS_AS_INT_LEN 16 +#define TUD_AUDIO20_DESC_CS_AS_INT(_termid, _ctrl, _formattype, _formats, _nchannelsphysical, _channelcfg, _stridx) \ + TUD_AUDIO20_DESC_CS_AS_INT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_AS_GENERAL, _termid, _ctrl, _formattype, U32_TO_U8S_LE(_formats), _nchannelsphysical, U32_TO_U8S_LE(_channelcfg), _stridx /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ -#define TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN 6 -#define TUD_AUDIO_DESC_TYPE_I_FORMAT(_subslotsize, _bitresolution) /* _subslotsize is number of bytes per sample (i.e. subslot) and can be 1,2,3, or 4 */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO20_FORMAT_TYPE_I, _subslotsize, _bitresolution +#define TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN 6 +#define TUD_AUDIO20_DESC_TYPE_I_FORMAT(_subslotsize, _bitresolution) /* _subslotsize is number of bytes per sample (i.e. subslot) and can be 1,2,3, or 4 */\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO20_FORMAT_TYPE_I, _subslotsize, _bitresolution /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ -#define TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN 7 -#define TUD_AUDIO_DESC_STD_AS_ISO_EP(_ep, _attr, _maxEPsize, _interval) \ - TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN, TUSB_DESC_ENDPOINT, _ep, _attr, U16_TO_U8S_LE(_maxEPsize), _interval +#define TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN 7 +#define TUD_AUDIO20_DESC_STD_AS_ISO_EP(_ep, _attr, _maxEPsize, _interval) \ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN, TUSB_DESC_ENDPOINT, _ep, _attr, U16_TO_U8S_LE(_maxEPsize), _interval /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ -#define TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN 8 -#define TUD_AUDIO_DESC_CS_AS_ISO_EP(_attr, _ctrl, _lockdelayunit, _lockdelay) \ - TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN, TUSB_DESC_CS_ENDPOINT, AUDIO20_CS_EP_SUBTYPE_GENERAL, _attr, _ctrl, _lockdelayunit, U16_TO_U8S_LE(_lockdelay) +#define TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN 8 +#define TUD_AUDIO20_DESC_CS_AS_ISO_EP(_attr, _ctrl, _lockdelayunit, _lockdelay) \ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN, TUSB_DESC_CS_ENDPOINT, AUDIO20_CS_EP_SUBTYPE_GENERAL, _attr, _ctrl, _lockdelayunit, U16_TO_U8S_LE(_lockdelay) /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */ -#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN 7 -#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _epsize, _interval) \ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(_epsize), _interval +#define TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN 7 +#define TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP(_ep, _epsize, _interval) \ + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(_epsize), _interval // AUDIO simple descriptor (UAC2) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source -#define TUD_AUDIO_MIC_ONE_CH_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) - -#define TUD_AUDIO_MIC_ONE_CH_DESC_N_AS_INT 1 // Number of AS interfaces - -#define TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ +#define TUD_AUDIO20_MIC_ONE_CH_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1)\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) + +#define TUD_AUDIO20_MIC_ONE_CH_DESC_N_AS_INT 1 // Number of AS interfaces + +#define TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) // AUDIO simple descriptor (UAC2) for 4 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source -#define TUD_AUDIO_MIC_FOUR_CH_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) - -#define TUD_AUDIO_MIC_FOUR_CH_DESC_N_AS_INT 1 // Number of AS interfaces - -#define TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ +#define TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(4)\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) + +#define TUD_AUDIO20_MIC_FOUR_CH_DESC_N_AS_INT 1 // Number of AS interfaces + +#define TUD_AUDIO20_MIC_FOUR_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(4), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x04, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x04, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch3*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch4*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch3*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch4*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x04, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x04, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) // AUDIO simple descriptor (UAC2) for mono speaker // - 1 Input Terminal, 2 Feature Unit (Mute and Volume Control), 3 Output Terminal, 4 Clock Source -#define TUD_AUDIO_SPEAKER_MONO_FB_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ - + TUD_AUDIO_DESC_STD_AC_LEN\ - + TUD_AUDIO_DESC_CS_AC_LEN\ - + TUD_AUDIO_DESC_CLK_SRC_LEN\ - + TUD_AUDIO_DESC_INPUT_TERM_LEN\ - + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ - + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_STD_AS_INT_LEN\ - + TUD_AUDIO_DESC_CS_AS_INT_LEN\ - + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ - + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN) - -#define TUD_AUDIO_SPEAKER_MONO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ +#define TUD_AUDIO20_SPEAKER_MONO_FB_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + + TUD_AUDIO20_DESC_STD_AC_LEN\ + + TUD_AUDIO20_DESC_CS_AC_LEN\ + + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1)\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_STD_AS_LEN\ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN) + +#define TUD_AUDIO20_SPEAKER_MONO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ - TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ - TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ - TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO20_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ - TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ - TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ - TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ 1) + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ 1) // Calculate wMaxPacketSize of Endpoints #define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ -- cgit v1.3.1 From d92b810df7670aae0e195fd02abef5014470c2f7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 28 Oct 2025 13:21:38 +0700 Subject: fix Identifiers that start with '__' or '_[A-Z]' are reserved. fix compiling with nuc family --- .github/actions/setup_toolchain/action.yml | 2 +- .../device/audio_4_channel_mic/src/tusb_config.h | 6 +- .../audio_4_channel_mic/src/usb_descriptors.c | 6 +- .../audio_4_channel_mic_freertos/src/tusb_config.h | 6 +- .../src/usb_descriptors.c | 6 +- examples/device/audio_test/src/tusb_config.h | 6 +- examples/device/audio_test/src/usb_descriptors.c | 6 +- .../device/audio_test_freertos/src/tusb_config.h | 6 +- .../audio_test_freertos/src/usb_descriptors.c | 6 +- .../device/audio_test_multi_rate/src/tusb_config.h | 6 +- .../audio_test_multi_rate/src/usb_descriptors.c | 6 +- examples/device/board_test/src/tusb_config.h | 6 +- examples/device/cdc_dual_ports/src/tusb_config.h | 6 +- .../device/cdc_dual_ports/src/usb_descriptors.c | 6 +- examples/device/cdc_msc/src/msc_disk.c | 99 +++++++++++----------- examples/device/cdc_msc/src/tusb_config.h | 6 +- examples/device/cdc_msc/src/usb_descriptors.c | 6 +- examples/device/cdc_msc_freertos/src/tusb_config.h | 6 +- .../device/cdc_msc_freertos/src/usb_descriptors.c | 6 +- examples/device/cdc_uac2/src/tusb_config.h | 6 +- examples/device/cdc_uac2/src/usb_descriptors.c | 6 +- examples/device/dfu/src/usb_descriptors.c | 6 +- examples/device/dfu_runtime/src/usb_descriptors.c | 6 +- .../device/dynamic_configuration/src/tusb_config.h | 6 +- .../dynamic_configuration/src/usb_descriptors.c | 6 +- .../device/hid_boot_interface/src/tusb_config.h | 6 +- .../hid_boot_interface/src/usb_descriptors.c | 6 +- examples/device/hid_composite/src/tusb_config.h | 6 +- .../device/hid_composite/src/usb_descriptors.c | 6 +- .../hid_composite_freertos/src/tusb_config.h | 6 +- .../hid_composite_freertos/src/usb_descriptors.c | 6 +- .../device/hid_generic_inout/src/tusb_config.h | 6 +- .../device/hid_generic_inout/src/usb_descriptors.c | 6 +- .../hid_multiple_interface/src/tusb_config.h | 6 +- .../hid_multiple_interface/src/usb_descriptors.c | 6 +- examples/device/midi_test/src/tusb_config.h | 6 +- examples/device/midi_test/src/usb_descriptors.c | 6 +- .../device/midi_test_freertos/src/tusb_config.h | 6 +- .../midi_test_freertos/src/usb_descriptors.c | 6 +- examples/device/msc_dual_lun/src/tusb_config.h | 6 +- examples/device/msc_dual_lun/src/usb_descriptors.c | 6 +- examples/device/mtp/src/tusb_config.h | 6 +- examples/device/mtp/src/usb_descriptors.c | 6 +- .../device/net_lwip_webserver/src/tusb_config.h | 6 +- .../net_lwip_webserver/src/usb_descriptors.c | 6 +- examples/device/uac2_headset/src/tusb_config.h | 6 +- examples/device/uac2_headset/src/usb_descriptors.c | 6 +- examples/device/uac2_speaker_fb/src/tusb_config.h | 6 +- .../device/uac2_speaker_fb/src/usb_descriptors.c | 6 +- examples/device/usbtmc/src/usb_descriptors.c | 6 +- examples/device/video_capture/src/tusb_config.h | 6 +- .../device/video_capture/src/usb_descriptors.c | 6 +- .../device/video_capture_2ch/src/tusb_config.h | 6 +- .../device/video_capture_2ch/src/usb_descriptors.c | 6 +- examples/device/webusb_serial/src/tusb_config.h | 6 +- .../device/webusb_serial/src/usb_descriptors.c | 6 +- .../host_hid_to_device_cdc/src/usb_descriptors.c | 6 +- .../host_info_to_device_cdc/src/usb_descriptors.c | 6 +- examples/host/cdc_msc_hid/src/tusb_config.h | 6 +- .../host/cdc_msc_hid_freertos/src/tusb_config.h | 6 +- examples/host/hid_controller/src/tusb_config.h | 6 +- examples/host/msc_file_explorer/src/tusb_config.h | 6 +- examples/typec/power_delivery/src/tusb_config.h | 6 +- hw/bsp/ansi_escape.h | 6 +- hw/bsp/nuc100_120/family.cmake | 12 ++- hw/bsp/nuc121_125/family.cmake | 12 +-- hw/bsp/nuc126/family.cmake | 12 +-- hw/bsp/nuc505/family.cmake | 12 +-- lib/rt-thread/tusb_config.h | 6 +- src/class/audio/audio.h | 4 +- src/class/audio/audio_device.h | 2 +- src/class/bth/bth_device.h | 6 +- src/class/cdc/cdc.h | 4 +- src/class/cdc/cdc_device.h | 2 +- src/class/cdc/cdc_host.h | 6 +- src/class/cdc/cdc_rndis.h | 6 +- src/class/cdc/cdc_rndis_host.h | 6 +- src/class/dfu/dfu.h | 6 +- src/class/dfu/dfu_device.h | 6 +- src/class/dfu/dfu_rt_device.h | 6 +- src/class/hid/hid.h | 6 +- src/class/hid/hid_host.h | 6 +- src/class/midi/midi_device.h | 6 +- src/class/msc/msc.h | 6 +- src/class/msc/msc_device.h | 6 +- src/class/net/ncm.h | 4 +- src/class/net/net_device.h | 6 +- src/class/usbtmc/usbtmc.h | 4 +- src/class/vendor/vendor_device.h | 6 +- src/class/vendor/vendor_host.h | 6 +- src/common/tusb_common.h | 6 +- src/common/tusb_compiler.h | 18 ++-- src/common/tusb_debug.h | 6 +- src/common/tusb_fifo.h | 6 +- src/device/usbd.h | 6 +- src/host/hcd.h | 4 +- src/host/usbh.h | 6 +- src/host/usbh_pvt.h | 4 +- src/osal/osal.h | 6 +- src/osal/osal_none.h | 2 +- src/portable/ehci/ehci.h | 6 +- src/portable/ehci/ehci_api.h | 4 +- src/portable/nxp/lpc17_40/dcd_lpc17_40.h | 4 +- src/portable/ohci/ohci.h | 6 +- src/portable/renesas/rusb2/rusb2_type.h | 6 +- src/portable/sunxi/musb_def.h | 4 +- src/portable/synopsys/dwc2/dwc2_bcm.h | 4 +- src/portable/valentyusb/eptri/dcd_eptri.h | 6 +- src/tusb.h | 6 +- src/tusb_option.h | 6 +- src/typec/pd_types.h | 4 +- src/typec/tcd.h | 4 +- src/typec/usbc.h | 6 +- test/fuzz/device/cdc/src/tusb_config.h | 6 +- test/fuzz/device/cdc/src/usb_descriptors.cc | 6 +- test/fuzz/device/msc/src/tusb_config.h | 6 +- test/fuzz/device/msc/src/usb_descriptors.cc | 6 +- test/fuzz/device/net/src/tusb_config.h | 6 +- test/fuzz/device/net/src/usb_descriptors.cc | 6 +- test/unit-test/test/support/tusb_config.h | 6 +- 120 files changed, 404 insertions(+), 405 deletions(-) (limited to 'src/class/midi') diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index 292fd172d..d15a29f20 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -33,7 +33,7 @@ runs: env: TOOLCHAIN: ${{ inputs.toolchain }} run: | - TOOLCHAIN_URL=$(jq -r '."$TOOLCHAIN"' .github/actions/setup_toolchain/toolchain.json) + TOOLCHAIN_URL=$(jq -r --arg tc "$TOOLCHAIN" '.[$tc]' .github/actions/setup_toolchain/toolchain.json) echo "toolchain_url=$TOOLCHAIN_URL" echo "toolchain_url=$TOOLCHAIN_URL" >> $GITHUB_OUTPUT shell: bash diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index 0ee3ba2d0..8ead5c8b0 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -123,4 +123,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_4_channel_mic/src/usb_descriptors.c b/examples/device/audio_4_channel_mic/src/usb_descriptors.c index d48ee0d08..73f856fc8 100644 --- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h index d973be2af..dd7cc7eff 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -129,4 +129,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c index d48ee0d08..73f856fc8 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 10bf53809..2efec5124 100644 --- a/examples/device/audio_test/src/tusb_config.h +++ b/examples/device/audio_test/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -122,4 +122,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c index 52ddc1bb2..5f0f587b3 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h index c9dc50082..4dad6c2b9 100644 --- a/examples/device/audio_test_freertos/src/tusb_config.h +++ b/examples/device/audio_test_freertos/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -128,4 +128,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c index 52ddc1bb2..5f0f587b3 100644 --- a/examples/device/audio_test_freertos/src/usb_descriptors.c +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/audio_test_multi_rate/src/tusb_config.h b/examples/device/audio_test_multi_rate/src/tusb_config.h index b48c0a0be..7ce235df0 100644 --- a/examples/device/audio_test_multi_rate/src/tusb_config.h +++ b/examples/device/audio_test_multi_rate/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -138,4 +138,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_test_multi_rate/src/usb_descriptors.c b/examples/device/audio_test_multi_rate/src/usb_descriptors.c index d1e801120..11e5d2127 100644 --- a/examples/device/audio_test_multi_rate/src/usb_descriptors.c +++ b/examples/device/audio_test_multi_rate/src/usb_descriptors.c @@ -34,9 +34,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h index 81829d450..97ec65f66 100644 --- a/examples/device/board_test/src/tusb_config.h +++ b/examples/device/board_test/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -74,4 +74,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index 7f7df3909..0da4032a7 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -110,4 +110,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index 34cdbfafb..dd0aefaea 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index b39f5efa1..1a95f7f8b 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -58,63 +58,64 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; // filesystem_type = "FAT12 "; volume_serial_number = 0x1234; volume_label = "TinyUSB MSC"; // FAT magic code at offset 510-511 -{ - 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, - 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T', 'i', 'n', 'y', 'U', - 'S', 'B', ' ', 'M', 'S', 'C', 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, - - // Zero up to 2 last bytes of FAT magic code - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA}, + { + 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, + 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T', 'i', 'n', 'y', 'U', + 'S', 'B', ' ', 'M', 'S', 'C', 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, + + // Zero up to 2 last bytes of FAT magic code + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA + }, //------------- Block1: FAT12 Table -------------// -{ - 0xF8, 0xFF, 0xFF, 0xFF, 0x0F// // first 2 entries must be F8FF, third entry is cluster end of readme file + { + 0xF8, 0xFF, 0xFF, 0xFF, 0x0F// first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Block2: Root Directory -------------// -{ - // first entry is volume label - 'T', 'i', 'n', 'y', 'U', 'S', 'B', ' ', 'M', 'S', 'C', 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // second entry is readme file - 'R', 'E', 'A', 'D', 'M', 'E', ' ', ' ', 'T', 'X', 'T', 0x20, 0x00, 0xC6, 0x52, 0x6D, - 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, - sizeof(README_CONTENTS) - 1, 0x00, 0x00, 0x00// readme's files size (4 Bytes) + { + // first entry is volume label + 'T', 'i', 'n', 'y', 'U', 'S', 'B', ' ', 'M', 'S', 'C', 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // second entry is readme file + 'R', 'E', 'A', 'D', 'M', 'E', ' ', ' ', 'T', 'X', 'T', 0x20, 0x00, 0xC6, 0x52, 0x6D, + 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, + sizeof(README_CONTENTS) - 1, 0x00, 0x00, 0x00// readme's files size (4 Bytes) }, //------------- Block3: Readme Content -------------// - README_CONTENTS + {README_CONTENTS} }; // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 811d464e9..fdb2ddf18 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -113,4 +113,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index c9b9a133a..c668ea3a7 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 9cc3a18d1..6b1937a8d 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -120,4 +120,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 58b39a2dd..4950f02e0 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h index 2e744f8d2..bd1dfc688 100644 --- a/examples/device/cdc_uac2/src/tusb_config.h +++ b/examples/device/cdc_uac2/src/tusb_config.h @@ -24,8 +24,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -171,4 +171,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 19ed63b51..252b602ac 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -35,9 +35,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index a7fca87cd..14ec315ea 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/dfu_runtime/src/usb_descriptors.c b/examples/device/dfu_runtime/src/usb_descriptors.c index d64ad151f..1d46ee252 100644 --- a/examples/device/dfu_runtime/src/usb_descriptors.c +++ b/examples/device/dfu_runtime/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/dynamic_configuration/src/tusb_config.h b/examples/device/dynamic_configuration/src/tusb_config.h index b9b3878cc..7309d97c9 100644 --- a/examples/device/dynamic_configuration/src/tusb_config.h +++ b/examples/device/dynamic_configuration/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -112,4 +112,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 4599c6f82..083279938 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) // Configuration mode // 0 : enumerated as CDC/MIDI. Board button is not pressed when enumerating diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index 52723e09f..5d6fd62e1 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -104,4 +104,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_boot_interface/src/usb_descriptors.c b/examples/device/hid_boot_interface/src/usb_descriptors.c index a830dfea8..9b4becc85 100644 --- a/examples/device/hid_boot_interface/src/usb_descriptors.c +++ b/examples/device/hid_boot_interface/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 6bd32c427..895745ed2 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -104,4 +104,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_composite/src/usb_descriptors.c b/examples/device/hid_composite/src/usb_descriptors.c index 168f3f325..46e4b63f9 100644 --- a/examples/device/hid_composite/src/usb_descriptors.c +++ b/examples/device/hid_composite/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index b28033a0c..ad067ac82 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -111,4 +111,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_composite_freertos/src/usb_descriptors.c b/examples/device/hid_composite_freertos/src/usb_descriptors.c index dd8682e64..a745c17b5 100644 --- a/examples/device/hid_composite_freertos/src/usb_descriptors.c +++ b/examples/device/hid_composite_freertos/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index 98143ac4d..58dc52afc 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -104,4 +104,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index b8bcda30e..f26333d50 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/hid_multiple_interface/src/tusb_config.h b/examples/device/hid_multiple_interface/src/tusb_config.h index 49dc962fe..e1805017d 100644 --- a/examples/device/hid_multiple_interface/src/tusb_config.h +++ b/examples/device/hid_multiple_interface/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -104,4 +104,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_multiple_interface/src/usb_descriptors.c b/examples/device/hid_multiple_interface/src/usb_descriptors.c index 0c5645247..cd2d93c44 100644 --- a/examples/device/hid_multiple_interface/src/usb_descriptors.c +++ b/examples/device/hid_multiple_interface/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index 314dde438..f4282b2d7 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -105,4 +105,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index da873479e..e969f33a3 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/midi_test_freertos/src/tusb_config.h b/examples/device/midi_test_freertos/src/tusb_config.h index 0ffdc37fb..c158f5197 100644 --- a/examples/device/midi_test_freertos/src/tusb_config.h +++ b/examples/device/midi_test_freertos/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -105,4 +105,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/midi_test_freertos/src/usb_descriptors.c b/examples/device/midi_test_freertos/src/usb_descriptors.c index da873479e..e969f33a3 100644 --- a/examples/device/midi_test_freertos/src/usb_descriptors.c +++ b/examples/device/midi_test_freertos/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index 9cbbbade9..4fb6816c6 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -104,4 +104,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index 8fbbf0d90..f73935ee0 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/mtp/src/tusb_config.h b/examples/device/mtp/src/tusb_config.h index 4d166aa63..95cc048ee 100644 --- a/examples/device/mtp/src/tusb_config.h +++ b/examples/device/mtp/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -136,4 +136,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/mtp/src/usb_descriptors.c b/examples/device/mtp/src/usb_descriptors.c index db8b32a4d..f0aa3de6b 100644 --- a/examples/device/mtp/src/usb_descriptors.c +++ b/examples/device/mtp/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] MTP | VENDOR | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(MTP, 5)) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | PID_MAP(MTP, 5)) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 31731ac1b..3285ea52c 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -141,4 +141,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index 5bd9ff0f3..1bc568983 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] NET | VENDOR | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(ECM_RNDIS, 5) | _PID_MAP(NCM, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | PID_MAP(ECM_RNDIS, 5) | PID_MAP(NCM, 5) ) // String Descriptor Index enum diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index e9165163b..2678054e1 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -24,8 +24,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -165,4 +165,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index 7aa0b17fc..7b1a41161 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -34,9 +34,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/uac2_speaker_fb/src/tusb_config.h b/examples/device/uac2_speaker_fb/src/tusb_config.h index 18ab2ff96..153b056bf 100644 --- a/examples/device/uac2_speaker_fb/src/tusb_config.h +++ b/examples/device/uac2_speaker_fb/src/tusb_config.h @@ -24,8 +24,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -162,4 +162,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c index 29f7ea6d6..c74eb90dc 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -38,9 +38,9 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 747850593..16bd176f8 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -34,9 +34,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xcafe #define USB_BCD 0x0200 diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 4ba86ca65..390152e16 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -115,4 +115,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 2fd1860c3..114dd5722 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] VIDEO | AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VIDEO, 5) | _PID_MAP(VENDOR, 6) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VIDEO, 5) | PID_MAP(VENDOR, 6) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/video_capture_2ch/src/tusb_config.h b/examples/device/video_capture_2ch/src/tusb_config.h index e84e49879..48ab4d20a 100644 --- a/examples/device/video_capture_2ch/src/tusb_config.h +++ b/examples/device/video_capture_2ch/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -117,4 +117,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/video_capture_2ch/src/usb_descriptors.c b/examples/device/video_capture_2ch/src/usb_descriptors.c index 0d19c53cf..024d16e07 100644 --- a/examples/device/video_capture_2ch/src/usb_descriptors.c +++ b/examples/device/video_capture_2ch/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] VIDEO | AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VIDEO, 5) | _PID_MAP(VENDOR, 6) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VIDEO, 5) | PID_MAP(VENDOR, 6) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index b86ad3752..b6cdf7e56 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -111,4 +111,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index 8579190be..0ef41a68e 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -33,9 +33,9 @@ * Auto ProductID layout's Bitmap: * [MSB] MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors diff --git a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c index ca515b36e..3efa30e20 100644 --- a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c index ca515b36e..3efa30e20 100644 --- a/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 2f8cb5e03..75de3511c 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -134,4 +134,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h index 3cdb227e2..8583e7176 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -139,4 +139,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index 351fe0178..a5c202fda 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -119,4 +119,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index c1829c300..a9d24c89f 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -118,4 +118,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/typec/power_delivery/src/tusb_config.h b/examples/typec/power_delivery/src/tusb_config.h index f7cb3cc04..ee013d056 100644 --- a/examples/typec/power_delivery/src/tusb_config.h +++ b/examples/typec/power_delivery/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -80,4 +80,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/hw/bsp/ansi_escape.h b/hw/bsp/ansi_escape.h index 15af2f3ab..0b72bea17 100644 --- a/hw/bsp/ansi_escape.h +++ b/hw/bsp/ansi_escape.h @@ -28,8 +28,8 @@ * \defgroup group_ansi_esc ANSI Escape Code * @{ */ -#ifndef _TUSB_ANSI_ESC_CODE_H_ -#define _TUSB_ANSI_ESC_CODE_H_ +#ifndef TUSB_ANSI_ESC_CODE_H_ +#define TUSB_ANSI_ESC_CODE_H_ #ifdef __cplusplus @@ -92,6 +92,6 @@ } #endif -#endif /* _TUSB_ANSI_ESC_CODE_H_ */ +#endif /* TUSB_ANSI_ESC_CODE_H_ */ /** @} */ diff --git a/hw/bsp/nuc100_120/family.cmake b/hw/bsp/nuc100_120/family.cmake index f81447596..b8f36bb9b 100644 --- a/hw/bsp/nuc100_120/family.cmake +++ b/hw/bsp/nuc100_120/family.cmake @@ -69,19 +69,17 @@ function(family_configure_example TARGET RTOS) "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES - COMPILE_FLAGS "-Wno-missing-prototypes -Wno-redundant-decls") + COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON diff --git a/hw/bsp/nuc121_125/family.cmake b/hw/bsp/nuc121_125/family.cmake index 718f8db9a..ee52e9ce4 100644 --- a/hw/bsp/nuc121_125/family.cmake +++ b/hw/bsp/nuc121_125/family.cmake @@ -72,14 +72,14 @@ function(family_configure_example TARGET RTOS) "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/hw/bsp/nuc126/family.cmake b/hw/bsp/nuc126/family.cmake index 3fc670cf0..d0f99ba1a 100644 --- a/hw/bsp/nuc126/family.cmake +++ b/hw/bsp/nuc126/family.cmake @@ -75,14 +75,14 @@ function(family_configure_example TARGET RTOS) "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/hw/bsp/nuc505/family.cmake b/hw/bsp/nuc505/family.cmake index a31f5ff73..581cad4d0 100644 --- a/hw/bsp/nuc505/family.cmake +++ b/hw/bsp/nuc505/family.cmake @@ -71,14 +71,14 @@ function(family_configure_example TARGET RTOS) "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") + target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) + target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/lib/rt-thread/tusb_config.h b/lib/rt-thread/tusb_config.h index 11dc21983..6f794dc41 100644 --- a/lib/rt-thread/tusb_config.h +++ b/lib/rt-thread/tusb_config.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __RTTHREAD__ #include @@ -215,4 +215,4 @@ extern "C" { #endif #endif /*__RTTHREAD__*/ -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 0d1acadcc..fc352a1af 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -30,8 +30,8 @@ * Currently only MIDI subclass is supported * @{ */ -#ifndef _TUSB_AUDIO_H__ -#define _TUSB_AUDIO_H__ +#ifndef TUSB_AUDIO_H__ +#define TUSB_AUDIO_H__ #include "common/tusb_common.h" diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 00948767e..b22a918f4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -462,7 +462,7 @@ void audiod_sof_isr (uint8_t rhport, uint32_t frame_count); } #endif -#endif /* _TUSB_AUDIO_DEVICE_H_ */ +#endif /* TUSB_AUDIO_DEVICE_H_ */ /** @} */ /** @} */ diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h index 68f073bff..89a056dc8 100755 --- a/src/class/bth/bth_device.h +++ b/src/class/bth/bth_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_BTH_DEVICE_H_ -#define _TUSB_BTH_DEVICE_H_ +#ifndef TUSB_BTH_DEVICE_H_ +#define TUSB_BTH_DEVICE_H_ #include #include @@ -114,4 +114,4 @@ bool btd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t r } #endif -#endif /* _TUSB_BTH_DEVICE_H_ */ +#endif /* TUSB_BTH_DEVICE_H_ */ diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 10ba16a7c..6d207c717 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -29,8 +29,8 @@ * Currently only Abstract Control Model subclass is supported * @{ */ -#ifndef _TUSB_CDC_H__ -#define _TUSB_CDC_H__ +#ifndef TUSB_CDC_H__ +#define TUSB_CDC_H__ #include "common/tusb_common.h" diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 9673b9807..c321f3d16 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -257,4 +257,4 @@ bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t re } #endif -#endif /* _TUSB_CDC_DEVICE_H_ */ +#endif /* TUSB_CDC_DEVICE_H_ */ diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index bf6711d7e..e8637beac 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_CDC_HOST_H_ -#define _TUSB_CDC_HOST_H_ +#ifndef TUSB_CDC_HOST_H_ +#define TUSB_CDC_HOST_H_ #include "cdc.h" @@ -255,4 +255,4 @@ void cdch_close (uint8_t dev_addr); } #endif -#endif /* _TUSB_CDC_HOST_H_ */ +#endif /* TUSB_CDC_HOST_H_ */ diff --git a/src/class/cdc/cdc_rndis.h b/src/class/cdc/cdc_rndis.h index ad153e0ac..fbbd43206 100644 --- a/src/class/cdc/cdc_rndis.h +++ b/src/class/cdc/cdc_rndis.h @@ -30,8 +30,8 @@ * \defgroup CDC_RNDIS_Common Common Definitions * @{ */ -#ifndef _TUSB_CDC_RNDIS_H_ -#define _TUSB_CDC_RNDIS_H_ +#ifndef TUSB_CDC_RNDIS_H_ +#define TUSB_CDC_RNDIS_H_ #include "cdc.h" @@ -295,7 +295,7 @@ typedef enum } #endif -#endif /* _TUSB_CDC_RNDIS_H_ */ +#endif /* TUSB_CDC_RNDIS_H_ */ /** @} */ /** @} */ diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h index bb431ec1f..e70d27f79 100644 --- a/src/class/cdc/cdc_rndis_host.h +++ b/src/class/cdc/cdc_rndis_host.h @@ -28,8 +28,8 @@ * \defgroup CDC_RNSID_Host Host * @{ */ -#ifndef _TUSB_CDC_RNDIS_HOST_H_ -#define _TUSB_CDC_RNDIS_HOST_H_ +#ifndef TUSB_CDC_RNDIS_HOST_H_ +#define TUSB_CDC_RNDIS_HOST_H_ #include "common/tusb_common.h" #include "host/usbh.h" @@ -58,6 +58,6 @@ void rndish_close(uint8_t dev_addr); } #endif -#endif /* _TUSB_CDC_RNDIS_HOST_H_ */ +#endif /* TUSB_CDC_RNDIS_HOST_H_ */ /** @} */ diff --git a/src/class/dfu/dfu.h b/src/class/dfu/dfu.h index 114c827b8..8cd63656a 100644 --- a/src/class/dfu/dfu.h +++ b/src/class/dfu/dfu.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DFU_H_ -#define _TUSB_DFU_H_ +#ifndef TUSB_DFU_H_ +#define TUSB_DFU_H_ #include "common/tusb_common.h" @@ -116,4 +116,4 @@ TU_VERIFY_STATIC( sizeof(dfu_status_response_t) == 6, "size is not correct"); } #endif -#endif /* _TUSB_DFU_H_ */ +#endif /* TUSB_DFU_H_ */ diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index e59e61ce9..b22b4c450 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DFU_DEVICE_H_ -#define _TUSB_DFU_DEVICE_H_ +#ifndef TUSB_DFU_DEVICE_H_ +#define TUSB_DFU_DEVICE_H_ #include "dfu.h" @@ -96,4 +96,4 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_r } #endif -#endif /* _TUSB_DFU_MODE_DEVICE_H_ */ +#endif /* TUSB_DFU_MODE_DEVICE_H_ */ diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h index 67eb26d95..c4116d8fe 100644 --- a/src/class/dfu/dfu_rt_device.h +++ b/src/class/dfu/dfu_rt_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DFU_RT_DEVICE_H_ -#define _TUSB_DFU_RT_DEVICE_H_ +#ifndef TUSB_DFU_RT_DEVICE_H_ +#define TUSB_DFU_RT_DEVICE_H_ #include "dfu.h" @@ -52,4 +52,4 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_req } #endif -#endif /* _TUSB_DFU_RT_DEVICE_H_ */ +#endif /* TUSB_DFU_RT_DEVICE_H_ */ diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index b69f623a0..0883d95ac 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -28,8 +28,8 @@ * \defgroup ClassDriver_HID Human Interface Device (HID) * @{ */ -#ifndef _TUSB_HID_H_ -#define _TUSB_HID_H_ +#ifndef TUSB_HID_H_ +#define TUSB_HID_H_ #include "common/tusb_common.h" @@ -2071,6 +2071,6 @@ enum { } #endif -#endif /* _TUSB_HID_H__ */ +#endif /* TUSB_HID_H__ */ /// @} diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 032827af1..87f0e7dc9 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_HID_HOST_H_ -#define _TUSB_HID_HOST_H_ +#ifndef TUSB_HID_HOST_H_ +#define TUSB_HID_HOST_H_ #include "hid.h" @@ -182,4 +182,4 @@ void hidh_close(uint8_t dev_addr); } #endif -#endif /* _TUSB_HID_HOST_H_ */ +#endif /* TUSB_HID_HOST_H_ */ diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index c2c6e9859..d23516cec 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MIDI_DEVICE_H_ -#define _TUSB_MIDI_DEVICE_H_ +#ifndef TUSB_MIDI_DEVICE_H_ +#define TUSB_MIDI_DEVICE_H_ #include "class/audio/audio.h" #include "midi.h" @@ -168,7 +168,7 @@ bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t } #endif -#endif /* _TUSB_MIDI_DEVICE_H_ */ +#endif /* TUSB_MIDI_DEVICE_H_ */ /** @} */ /** @} */ diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h index b2b44eac4..3b5d4a855 100644 --- a/src/class/msc/msc.h +++ b/src/class/msc/msc.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MSC_H_ -#define _TUSB_MSC_H_ +#ifndef TUSB_MSC_H_ +#define TUSB_MSC_H_ #include "common/tusb_common.h" @@ -398,4 +398,4 @@ TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct"); } #endif -#endif /* _TUSB_MSC_H_ */ +#endif /* TUSB_MSC_H_ */ diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 7d898e988..21e24971b 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MSC_DEVICE_H_ -#define _TUSB_MSC_DEVICE_H_ +#ifndef TUSB_MSC_DEVICE_H_ +#define TUSB_MSC_DEVICE_H_ #include "common/tusb_common.h" #include "msc.h" @@ -167,4 +167,4 @@ bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t ev } #endif -#endif /* _TUSB_MSC_DEVICE_H_ */ +#endif /* TUSB_MSC_DEVICE_H_ */ diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index 0245a87f2..8989fe0b4 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_NCM_H_ -#define _TUSB_NCM_H_ +#ifndef TUSB_NCM_H_ +#define TUSB_NCM_H_ #include "common/tusb_common.h" diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index ef5ecffc8..96c03fd61 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_NET_DEVICE_H_ -#define _TUSB_NET_DEVICE_H_ +#ifndef TUSB_NET_DEVICE_H_ +#define TUSB_NET_DEVICE_H_ #include #include "class/cdc/cdc.h" @@ -114,4 +114,4 @@ void netd_report (uint8_t *buf, uint16_t len); } #endif -#endif /* _TUSB_NET_DEVICE_H_ */ +#endif /* TUSB_NET_DEVICE_H_ */ diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 327de087c..3bf5e1a17 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBTMC_H__ -#define _TUSB_USBTMC_H__ +#ifndef TUSB_USBTMC_H__ +#define TUSB_USBTMC_H__ #include "common/tusb_common.h" diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 5fe4fc9ff..5376f3917 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_VENDOR_DEVICE_H_ -#define _TUSB_VENDOR_DEVICE_H_ +#ifndef TUSB_VENDOR_DEVICE_H_ +#define TUSB_VENDOR_DEVICE_H_ #include "common/tusb_common.h" @@ -141,4 +141,4 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, u } #endif -#endif /* _TUSB_VENDOR_DEVICE_H_ */ +#endif /* TUSB_VENDOR_DEVICE_H_ */ diff --git a/src/class/vendor/vendor_host.h b/src/class/vendor/vendor_host.h index acfebe7a4..00e3c3402 100644 --- a/src/class/vendor/vendor_host.h +++ b/src/class/vendor/vendor_host.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_VENDOR_HOST_H_ -#define _TUSB_VENDOR_HOST_H_ +#ifndef TUSB_VENDOR_HOST_H_ +#define TUSB_VENDOR_HOST_H_ #include "common/tusb_common.h" @@ -64,4 +64,4 @@ void cush_close(uint8_t dev_addr); } #endif -#endif /* _TUSB_VENDOR_HOST_H_ */ +#endif /* TUSB_VENDOR_HOST_H_ */ diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index dfa9299c1..04149da71 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_COMMON_H_ -#define _TUSB_COMMON_H_ +#ifndef TUSB_COMMON_H_ +#define TUSB_COMMON_H_ #ifdef __cplusplus extern "C" { @@ -391,4 +391,4 @@ uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t b } #endif -#endif /* _TUSB_COMMON_H_ */ +#endif /* TUSB_COMMON_H_ */ diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 9b33a6f61..55950fb45 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -29,8 +29,8 @@ * \brief Group_Compiler brief * @{ */ -#ifndef _TUSB_COMPILER_H_ -#define _TUSB_COMPILER_H_ +#ifndef TUSB_COMPILER_H_ +#define TUSB_COMPILER_H_ #define TU_TOKEN(x) x #define TU_STRING(x) #x ///< stringify without expand @@ -45,9 +45,9 @@ #define TU_INCLUDE_PATH(_dir,_file) TU_XSTRING( TU_TOKEN(_dir)TU_TOKEN(_file) ) #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ - #define _TU_COUNTER_ __COUNTER__ + #define TU_COUNTER __COUNTER__ #else - #define _TU_COUNTER_ __LINE__ + #define TU_COUNTER __LINE__ #endif // Compile-time Assert @@ -56,9 +56,9 @@ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define TU_VERIFY_STATIC _Static_assert #elif defined(__CCRX__) - #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, _TU_COUNTER_)[(const_expr) ? 1 : 0]; + #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, TU_COUNTER)[(const_expr) ? 1 : 0]; #else - #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } + #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, TU_COUNTER) = 1/(!!(const_expr)) } #endif /* --------------------- Fuzzing types -------------------------------------- */ @@ -68,8 +68,8 @@ #define tu_static static #endif -// for declaration of reserved field, make use of _TU_COUNTER_ -#define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_) +// for declaration of reserved field, make use of TU_COUNTER +#define TU_RESERVED TU_XSTRCAT(reserved, TU_COUNTER) #define TU_LITTLE_ENDIAN (0x12u) #define TU_BIG_ENDIAN (0x21u) @@ -305,6 +305,6 @@ #error Byte order is undefined #endif -#endif /* _TUSB_COMPILER_H_ */ +#endif /* TUSB_COMPILER_H_ */ /// @} diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 86517b9c9..e3f9d3f18 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DEBUG_H_ -#define _TUSB_DEBUG_H_ +#ifndef TUSB_DEBUG_H_ +#define TUSB_DEBUG_H_ #ifdef __cplusplus extern "C" { @@ -168,4 +168,4 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 } #endif -#endif /* _TUSB_DEBUG_H_ */ +#endif diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 879acda4f..f2a6c5469 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_FIFO_H_ -#define _TUSB_FIFO_H_ +#ifndef TUSB_FIFO_H_ +#define TUSB_FIFO_H_ #ifdef __cplusplus extern "C" { @@ -196,4 +196,4 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); } #endif -#endif /* _TUSB_FIFO_H_ */ +#endif diff --git a/src/device/usbd.h b/src/device/usbd.h index c62986150..f75803b14 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBD_H_ -#define _TUSB_USBD_H_ +#ifndef TUSB_USBD_H_ +#define TUSB_USBD_H_ #include "common/tusb_common.h" @@ -904,6 +904,6 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ } #endif -#endif /* _TUSB_USBD_H_ */ +#endif /* TUSB_USBD_H_ */ /** @} */ diff --git a/src/host/hcd.h b/src/host/hcd.h index d3551bf5b..4a17326ec 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_HCD_H_ -#define _TUSB_HCD_H_ +#ifndef TUSB_HCD_H_ +#define TUSB_HCD_H_ #include "common/tusb_common.h" #include "osal/osal.h" diff --git a/src/host/usbh.h b/src/host/usbh.h index 8d48bf90d..4b6747848 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBH_H_ -#define _TUSB_USBH_H_ +#ifndef TUSB_USBH_H_ +#define TUSB_USBH_H_ #ifdef __cplusplus extern "C" { @@ -179,7 +179,7 @@ TU_ATTR_ALWAYS_INLINE static inline void tuh_task(void) { // Check if there is pending events need processing by tuh_task() bool tuh_task_event_ready(void); -#ifndef _TUSB_HCD_H_ +#ifndef TUSB_HCD_H_ extern void hcd_int_handler(uint8_t rhport, bool in_isr); #endif diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 9d91e52e8..d722bb7e8 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBH_PVT_H_ -#define _TUSB_USBH_PVT_H_ +#ifndef TUSB_USBH_PVT_H_ +#define TUSB_USBH_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" diff --git a/src/osal/osal.h b/src/osal/osal.h index 658b18584..44521620f 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_H_ -#define _TUSB_OSAL_H_ +#ifndef TUSB_OSAL_H_ +#define TUSB_OSAL_H_ #ifdef __cplusplus extern "C" { @@ -101,4 +101,4 @@ typedef void (*osal_task_func_t)(void* param); } #endif -#endif /* _TUSB_OSAL_H_ */ +#endif diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 6f9b8b0dc..bc86dcb28 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -156,7 +156,7 @@ typedef osal_queue_def_t* osal_queue_t; } TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { - tu_fifo_clear(&qdef->ff); + (void) tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h index 87659701b..719bdeafc 100644 --- a/src/portable/ehci/ehci.h +++ b/src/portable/ehci/ehci.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_EHCI_H_ -#define _TUSB_EHCI_H_ +#ifndef TUSB_EHCI_H_ +#define TUSB_EHCI_H_ /* Abbreviation @@ -458,4 +458,4 @@ TU_VERIFY_STATIC(sizeof(ehci_cap_registers_t) == 16, "size is not correct"); } #endif -#endif /* _TUSB_EHCI_H_ */ +#endif /* TUSB_EHCI_H_ */ diff --git a/src/portable/ehci/ehci_api.h b/src/portable/ehci/ehci_api.h index 12e0a73d7..79fbe702a 100644 --- a/src/portable/ehci/ehci_api.h +++ b/src/portable/ehci/ehci_api.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_EHCI_API_H_ -#define _TUSB_EHCI_API_H_ +#ifndef TUSB_EHCI_API_H_ +#define TUSB_EHCI_API_H_ #ifdef __cplusplus extern "C" { diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.h b/src/portable/nxp/lpc17_40/dcd_lpc17_40.h index 654b80866..25c9f9985 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.h +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DCD_LPC17_40_H_ -#define _TUSB_DCD_LPC17_40_H_ +#ifndef TUSB_DCD_LPC17_40_H_ +#define TUSB_DCD_LPC17_40_H_ #include "common/tusb_common.h" diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 94bad5df7..3366f15f7 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OHCI_H_ -#define _TUSB_OHCI_H_ +#ifndef TUSB_OHCI_H_ +#define TUSB_OHCI_H_ #ifdef __cplusplus extern "C" { @@ -304,4 +304,4 @@ TU_VERIFY_STATIC( sizeof(ohci_registers_t) == (0x54 + (4 * TUP_OHCI_RHPORTS)), " } #endif -#endif /* _TUSB_OHCI_H_ */ +#endif /* TUSB_OHCI_H_ */ diff --git a/src/portable/renesas/rusb2/rusb2_type.h b/src/portable/renesas/rusb2/rusb2_type.h index dd88f66a7..71837d03c 100644 --- a/src/portable/renesas/rusb2/rusb2_type.h +++ b/src/portable/renesas/rusb2/rusb2_type.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_RUSB2_TYPE_H_ -#define _TUSB_RUSB2_TYPE_H_ +#ifndef TUSB_RUSB2_TYPE_H_ +#define TUSB_RUSB2_TYPE_H_ #include #include @@ -1777,4 +1777,4 @@ TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R_FS ) == 0x0404, "incorrect offset } #endif -#endif /* _TUSB_RUSB2_TYPE_H_ */ +#endif /* TUSB_RUSB2_TYPE_H_ */ diff --git a/src/portable/sunxi/musb_def.h b/src/portable/sunxi/musb_def.h index 53da5ded2..ce9b89d55 100644 --- a/src/portable/sunxi/musb_def.h +++ b/src/portable/sunxi/musb_def.h @@ -26,8 +26,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MUSB_DEF -#define _TUSB_MUSB_DEF +#ifndef TUSB_MUSB_DEF +#define TUSB_MUSB_DEF #define USBC_Readb(reg) (*(volatile unsigned char *)(reg)) diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index e5824606a..df6d4a852 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DWC2_BCM_H_ -#define _TUSB_DWC2_BCM_H_ +#ifndef TUSB_DWC2_BCM_H_ +#define TUSB_DWC2_BCM_H_ #ifdef __cplusplus extern "C" { diff --git a/src/portable/valentyusb/eptri/dcd_eptri.h b/src/portable/valentyusb/eptri/dcd_eptri.h index d67635d7c..2fe74a712 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.h +++ b/src/portable/valentyusb/eptri/dcd_eptri.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DCD_VALENTYUSB_EPTRI_H_ -#define _TUSB_DCD_VALENTYUSB_EPTRI_H_ +#ifndef TUSB_DCD_VALENTYUSB_EPTRI_H_ +#define TUSB_DCD_VALENTYUSB_EPTRI_H_ #include "common/tusb_common.h" #ifdef __cplusplus @@ -36,4 +36,4 @@ } #endif -#endif /* _TUSB_DCD_VALENTYUSB_EPTRI_H_ */ +#endif /* TUSB_DCD_VALENTYUSB_EPTRI_H_ */ diff --git a/src/tusb.h b/src/tusb.h index 6a469eef4..62b3b9783 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_H_ -#define _TUSB_H_ +#ifndef TUSB_H_ +#define TUSB_H_ #ifdef __cplusplus extern "C" { @@ -178,4 +178,4 @@ bool tusb_deinit(uint8_t rhport); } #endif -#endif /* _TUSB_H_ */ +#endif /* TUSB_H_ */ diff --git a/src/tusb_option.h b/src/tusb_option.h index 14404c59c..e00311039 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OPTION_H_ -#define _TUSB_OPTION_H_ +#ifndef TUSB_OPTION_H_ +#define TUSB_OPTION_H_ #include "common/tusb_compiler.h" @@ -727,6 +727,6 @@ // To avoid GCC compiler warnings when -pedantic option is used (strict ISO C) typedef int make_iso_compilers_happy; -#endif /* _TUSB_OPTION_H_ */ +#endif /* TUSB_OPTION_H_ */ /** @} */ diff --git a/src/typec/pd_types.h b/src/typec/pd_types.h index 1b2968f65..950f4d488 100644 --- a/src/typec/pd_types.h +++ b/src/typec/pd_types.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_PD_TYPES_H_ -#define _TUSB_PD_TYPES_H_ +#ifndef TUSB_PD_TYPES_H_ +#define TUSB_PD_TYPES_H_ #ifdef __cplusplus extern "C" { diff --git a/src/typec/tcd.h b/src/typec/tcd.h index bcbdab8ed..da7ab4b13 100644 --- a/src/typec/tcd.h +++ b/src/typec/tcd.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_TCD_H_ -#define _TUSB_TCD_H_ +#ifndef TUSB_TCD_H_ +#define TUSB_TCD_H_ #include "common/tusb_common.h" #include "pd_types.h" diff --git a/src/typec/usbc.h b/src/typec/usbc.h index 448542aab..711119596 100644 --- a/src/typec/usbc.h +++ b/src/typec/usbc.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_UTCD_H_ -#define _TUSB_UTCD_H_ +#ifndef TUSB_UTCD_H_ +#define TUSB_UTCD_H_ #include "common/tusb_common.h" #include "pd_types.h" @@ -63,7 +63,7 @@ void tuc_task (void) { tuc_task_ext(UINT32_MAX, false); } -#ifndef _TUSB_TCD_H_ +#ifndef TUSB_TCD_H_ extern void tcd_int_handler(uint8_t rhport); #endif diff --git a/test/fuzz/device/cdc/src/tusb_config.h b/test/fuzz/device/cdc/src/tusb_config.h index 10a8a825a..76f44619e 100644 --- a/test/fuzz/device/cdc/src/tusb_config.h +++ b/test/fuzz/device/cdc/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -111,4 +111,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/test/fuzz/device/cdc/src/usb_descriptors.cc b/test/fuzz/device/cdc/src/usb_descriptors.cc index c26bd18c3..0d7d17b4b 100644 --- a/test/fuzz/device/cdc/src/usb_descriptors.cc +++ b/test/fuzz/device/cdc/src/usb_descriptors.cc @@ -30,10 +30,10 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) #define USB_PID \ - (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) | \ - _PID_MAP(VENDOR, 4)) + (0x4000 | PID_MAP(CDC, 0) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | \ + PID_MAP(VENDOR, 4)) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/test/fuzz/device/msc/src/tusb_config.h b/test/fuzz/device/msc/src/tusb_config.h index ca39c6b0a..abd8cd4ce 100644 --- a/test/fuzz/device/msc/src/tusb_config.h +++ b/test/fuzz/device/msc/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -111,4 +111,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/test/fuzz/device/msc/src/usb_descriptors.cc b/test/fuzz/device/msc/src/usb_descriptors.cc index 6d9c4cd96..55c113ad7 100644 --- a/test/fuzz/device/msc/src/usb_descriptors.cc +++ b/test/fuzz/device/msc/src/usb_descriptors.cc @@ -30,10 +30,10 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) #define USB_PID \ - (0x4000 | _PID_MAP(MSC, 0) | _PID_MAP(HID, 1) | _PID_MAP(MIDI, 2) | \ - _PID_MAP(VENDOR, 3)) + (0x4000 | PID_MAP(MSC, 0) | PID_MAP(HID, 1) | PID_MAP(MIDI, 2) | \ + PID_MAP(VENDOR, 3)) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/test/fuzz/device/net/src/tusb_config.h b/test/fuzz/device/net/src/tusb_config.h index 6ad859337..4fe98e043 100644 --- a/test/fuzz/device/net/src/tusb_config.h +++ b/test/fuzz/device/net/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -119,4 +119,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/test/fuzz/device/net/src/usb_descriptors.cc b/test/fuzz/device/net/src/usb_descriptors.cc index e57a791b6..301f23829 100644 --- a/test/fuzz/device/net/src/usb_descriptors.cc +++ b/test/fuzz/device/net/src/usb_descriptors.cc @@ -30,10 +30,10 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | CDC [LSB] */ -#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) #define USB_PID \ - (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) | \ - _PID_MAP(VENDOR, 4)) + (0x4000 | PID_MAP(CDC, 0) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | \ + PID_MAP(VENDOR, 4)) #define USB_VID 0xCafe #define USB_BCD 0x0200 diff --git a/test/unit-test/test/support/tusb_config.h b/test/unit-test/test/support/tusb_config.h index 00818fae5..dee24f65d 100644 --- a/test/unit-test/test/support/tusb_config.h +++ b/test/unit-test/test/support/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ // testing framework #include "unity.h" @@ -103,4 +103,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ -- cgit v1.3.1 From fc661abc18beefb57f5d1352219ed72678b59e0b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 12 Nov 2025 10:41:58 +0700 Subject: migrate midi_device to use edpt stream API also add tud_midi_n_packet_write/read_n() --- .clang-format | 1 + src/class/midi/midi_device.c | 511 ++++++++++++++++----------------------- src/class/midi/midi_device.h | 130 ++++------ src/class/vendor/vendor_device.c | 3 +- src/common/tusb_fifo.c | 25 +- src/common/tusb_fifo.h | 38 +-- src/common/tusb_private.h | 14 +- src/tusb.c | 4 +- 8 files changed, 288 insertions(+), 438 deletions(-) (limited to 'src/class/midi') diff --git a/.clang-format b/.clang-format index 907dd7cdd..c278fec37 100644 --- a/.clang-format +++ b/.clang-format @@ -70,6 +70,7 @@ IncludeCategories: - Regex: '.*' Priority: 3 IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentPPDirectives: BeforeHash InsertBraces: true IndentCaseLabels: true InsertNewlineAtEOF: true diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 7dac7c4a5..f065e486a 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -36,13 +36,19 @@ #include "midi_device.h" +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf) { + (void)itf; +} + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { + uint8_t rhport; uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; // For Stream read()/write() API // Messages are always 4 bytes long, queue them for reading and writing so the @@ -51,134 +57,97 @@ typedef struct { midi_driver_stream_t stream_read; /*------------- From this point, data is not cleared by bus reset -------------*/ - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; - uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_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; + + uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE]; + } ep_stream; } midid_interface_t; -#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff) +#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, ep_stream) + +static midid_interface_t _midid_itf[CFG_TUD_MIDI]; // Endpoint Transfer buffer -CFG_TUD_MEM_SECTION static struct { +typedef struct { TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE); TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE); -} _midid_epbuf[CFG_TUD_MIDI]; +} midid_epbuf_t; + +CFG_TUD_MEM_SECTION static midid_epbuf_t _midid_epbuf[CFG_TUD_MIDI]; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static midid_interface_t _midid_itf[CFG_TUD_MIDI]; - bool tud_midi_n_mounted (uint8_t itf) { - midid_interface_t* midi = &_midid_itf[itf]; - return midi->ep_in && midi->ep_out; -} + midid_interface_t *p_midi = &_midid_itf[itf]; -static void _prep_out_transaction(uint8_t idx) { - const uint8_t rhport = 0; - midid_interface_t* p_midi = &_midid_itf[idx]; - uint16_t available = tu_fifo_remaining(&p_midi->rx_ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= CFG_TUD_MIDI_EP_BUFSIZE, ); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_midi->ep_out), ); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_midi->rx_ff); - - if ( available >= CFG_TUD_MIDI_EP_BUFSIZE ) { - usbd_edpt_xfer(rhport, p_midi->ep_out, _midid_epbuf[idx].epout, CFG_TUD_MIDI_EP_BUFSIZE); - }else - { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, p_midi->ep_out); - } -} - - -//--------------------------------------------------------------------+ -// Weak stubs: invoked if no strong implementation is available -//--------------------------------------------------------------------+ -TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf) { - (void) itf; + const bool tx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.tx); + const bool rx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.rx); + return tx_opened && rx_opened; } //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ -uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) -{ +uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) { (void) cable_num; - - midid_interface_t* midi = &_midid_itf[itf]; - const midi_driver_stream_t* stream = &midi->stream_read; + const midid_interface_t *p_midi = &_midid_itf[itf]; + const midi_driver_stream_t *stream = &p_midi->stream_read; + const tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; // when using with packet API stream total & index are both zero - return tu_fifo_count(&midi->rx_ff) + (uint8_t) (stream->total - stream->index); + return tu_edpt_stream_read_available(ep_str) + (uint8_t)(stream->total - stream->index); } -uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize) -{ +uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize) { (void) cable_num; - TU_VERIFY(bufsize, 0); - - uint8_t* buf8 = (uint8_t*) buffer; + TU_VERIFY(buffer != NULL && bufsize > 0, 0); - midid_interface_t* midi = &_midid_itf[itf]; - midi_driver_stream_t* stream = &midi->stream_read; + uint8_t *buf8 = (uint8_t *)buffer; + midid_interface_t *p_midi = &_midid_itf[itf]; + midi_driver_stream_t *stream = &p_midi->stream_read; uint32_t total_read = 0; - while( bufsize ) - { + while (bufsize > 0) { // Get new packet from fifo, then set packet expected bytes - if ( stream->total == 0 ) - { - // return if there is no more data from fifo - if ( !tud_midi_n_packet_read(itf, stream->buffer) ) return total_read; + if (stream->total == 0) { + if (!tud_midi_n_packet_read(itf, stream->buffer)) { + return total_read; // return if there is no more data from fifo + } - uint8_t const code_index = stream->buffer[0] & 0x0f; + const uint8_t code_index = stream->buffer[0] & 0x0f; // MIDI 1.0 Table 4-1: Code Index Number Classifications - switch(code_index) - { + switch (code_index) { case MIDI_CIN_MISC: case MIDI_CIN_CABLE_EVENT: // These are reserved and unused, possibly issue somewhere, skip this packet return 0; - break; case MIDI_CIN_SYSEX_END_1BYTE: case MIDI_CIN_1BYTE_DATA: stream->total = 1; - break; + break; case MIDI_CIN_SYSCOM_2BYTE : case MIDI_CIN_SYSEX_END_2BYTE : case MIDI_CIN_PROGRAM_CHANGE : case MIDI_CIN_CHANNEL_PRESSURE : stream->total = 2; - break; + break; default: stream->total = 3; - break; + break; } } // Copy data up to bufsize - uint8_t const count = (uint8_t) tu_min32(stream->total - stream->index, bufsize); + const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize); // Skip the header (1st byte) in the buffer TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)); @@ -189,8 +158,7 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui bufsize -= count; // complete current event packet, reset stream - if ( stream->total == stream->index ) - { + if (stream->total == stream->index) { stream->index = 0; stream->total = 0; } @@ -199,150 +167,107 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui return total_read; } -bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]) -{ - midid_interface_t* midi = &_midid_itf[itf]; - TU_VERIFY(midi->ep_out); +bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { + midid_interface_t *p_midi = &_midid_itf[itf]; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); + return 4 == tu_edpt_stream_read(p_midi->rhport, ep_str, packet, 4); +} + +uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) { + midid_interface_t *p_midi = &_midid_itf[itf]; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - const uint32_t num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4); - _prep_out_transaction(itf); - return (num_read == 4); + const uint32_t num_read = tu_edpt_stream_read(p_midi->rhport, ep_str, packets, 4u * max_packets); + return num_read >> 2u; } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ - -static uint32_t write_flush(uint8_t idx) { - midid_interface_t* midi = &_midid_itf[idx]; - - if (!tu_fifo_count(&midi->tx_ff)) { - return 0; // No data to send - } - - const uint8_t rhport = 0; - - // skip if previous transfer not complete - TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 ); - - uint16_t count = tu_fifo_read_n(&midi->tx_ff, _midid_epbuf[idx].epin, CFG_TUD_MIDI_EP_BUFSIZE); - - if (count) { - TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, _midid_epbuf[idx].epin, count), 0 ); - return count; - }else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, midi->ep_in); - return 0; - } -} - -uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t* buffer, uint32_t bufsize) -{ - midid_interface_t* midi = &_midid_itf[itf]; - TU_VERIFY(midi->ep_in, 0); - - midi_driver_stream_t* stream = &midi->stream_write; +uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) { + midid_interface_t *p_midi = &_midid_itf[itf]; + midi_driver_stream_t *stream = &p_midi->stream_write; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); uint32_t i = 0; - while ( (i < bufsize) && (tu_fifo_remaining(&midi->tx_ff) >= 4) ) - { + while (i < bufsize) { + if (tu_edpt_stream_write_available(p_midi->rhport, ep_str) < 4) { + break; + } + const uint8_t data = buffer[i]; i++; - if ( stream->index == 0 ) - { + if (stream->index == 0) { //------------- New event packet -------------// const uint8_t msg = data >> 4; - stream->index = 2; + stream->index = 2; stream->buffer[1] = data; // Check to see if we're still in a SysEx transmit. - if ( ((stream->buffer[0]) & 0xF) == MIDI_CIN_SYSEX_START ) - { - if ( data == MIDI_STATUS_SYSEX_END ) - { - stream->buffer[0] = (uint8_t) ((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); - stream->total = 2; - } - else - { + if (((stream->buffer[0]) & 0xF) == MIDI_CIN_SYSEX_START) { + if (data == MIDI_STATUS_SYSEX_END) { + stream->buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); + stream->total = 2; + } 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) - { + stream->buffer[0] = (uint8_t)((cable_num << 4) | msg); + stream->total = 4; + } 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 ) - { + stream->buffer[0] = (uint8_t)((cable_num << 4) | msg); + stream->total = 3; + } 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 ) - { + stream->total = 4; + } 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 ) - { + stream->total = 3; + } else if (data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER) { stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE; - stream->total = 4; - } - else - { + stream->total = 4; + } else { stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; - stream->total = 2; + stream->total = 2; } stream->buffer[0] |= (uint8_t)(cable_num << 4); - } - 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[0] = (uint8_t)(cable_num << 4 | 0xf); stream->buffer[2] = 0; stream->buffer[3] = 0; - stream->index = 2; - stream->total = 2; + stream->total = 2; // index already set to 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] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END ) - { - stream->buffer[0] = (uint8_t) ((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1))); - stream->total = stream->index; + if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { + stream->buffer[0] = (uint8_t)((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1))); + stream->total = stream->index; } } // Send out packet - if ( stream->index == stream->total ) - { + if (stream->index == stream->total) { // zeroes unused bytes for (uint8_t idx = stream->total; idx < 4; idx++) { stream->buffer[idx] = 0; } - const uint16_t count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4); + const uint32_t count = tu_edpt_stream_write(p_midi->rhport, ep_str, stream->buffer, 4); // complete current event packet, reset stream stream->index = stream->total = 0; @@ -352,25 +277,37 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t* } } - write_flush(itf); + (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); return i; } bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) { - midid_interface_t* midi = &_midid_itf[itf]; - TU_VERIFY(midi->ep_in); + midid_interface_t *p_midi = &_midid_itf[itf]; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); - if (tu_fifo_remaining(&midi->tx_ff) < 4) { - return false; - } - - tu_fifo_write_n(&midi->tx_ff, packet, 4); - write_flush(itf); + TU_VERIFY(tu_edpt_stream_write_available(p_midi->rhport, ep_str) >= 4); + TU_VERIFY(tu_edpt_stream_write(p_midi->rhport, ep_str, packet, 4) > 0); + (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); return true; } +uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets) { + midid_interface_t *p_midi = &_midid_itf[itf]; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); + + uint32_t n_bytes = tu_edpt_stream_write_available(p_midi->rhport, ep_str); + n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2u); + + const uint32_t n_write = tu_edpt_stream_write(p_midi->rhport, ep_str, packets, n_bytes); + (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + + return n_write >> 2u; +} + //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ @@ -378,72 +315,64 @@ void midid_init(void) { tu_memclr(_midid_itf, sizeof(_midid_itf)); for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { - midid_interface_t* midi = &_midid_itf[i]; - - // config fifo - tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, false); // true, true - tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS. + midid_interface_t *p_midi = &_midid_itf[i]; + midid_epbuf_t *p_epbuf = &_midid_epbuf[i]; - #if CFG_FIFO_MUTEX - osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex); - TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, ); + tu_edpt_stream_init( + &p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, + p_epbuf->epout, CFG_TUD_MIDI_EP_BUFSIZE); - tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL); - #endif + tu_edpt_stream_init( + &p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, p_epbuf->epin, + CFG_TUD_MIDI_EP_BUFSIZE); } } bool midid_deinit(void) { - #if CFG_FIFO_MUTEX - for(uint8_t i=0; irx_ff.mutex_rd; - osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL); - } - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL); - } + for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { + midid_interface_t *p_midi = &_midid_itf[i]; + tu_edpt_stream_deinit(&p_midi->ep_stream.rx); + tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } - #endif - return true; } -void midid_reset(uint8_t rhport) -{ - (void) rhport; +void midid_reset(uint8_t rhport) { + (void)rhport; + for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { + midid_interface_t *p_midi = &_midid_itf[i]; + tu_memclr(p_midi, ITF_MEM_RESET_SIZE); + + tu_edpt_stream_clear(&p_midi->ep_stream.rx); + tu_edpt_stream_close(&p_midi->ep_stream.rx); - for(uint8_t i=0; irx_ff); - tu_fifo_clear(&midi->tx_ff); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + tu_edpt_stream_close(&p_midi->ep_stream.tx); } } -uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) { - uint16_t drv_len = 0; - uint8_t const * p_desc = (uint8_t const *)desc_itf; +TU_ATTR_ALWAYS_INLINE static inline uint8_t find_midi_itf(uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUD_MIDI; idx++) { + const midid_interface_t *p_midi = &_midid_itf[idx]; + if (ep_addr == p_midi->ep_stream.rx.ep_addr || ep_addr == p_midi->ep_stream.tx.ep_addr) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; +} + +uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { + const uint8_t *p_desc = (const uint8_t *)desc_itf; + const uint8_t *desc_end = p_desc + max_len; // 1st Interface is Audio Control v1 (optional) if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { - drv_len = tu_desc_len(desc_itf); p_desc = tu_desc_next(desc_itf); // Skip Class Specific descriptors - while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { + p_desc = tu_desc_next(p_desc); } } @@ -451,59 +380,44 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint1 TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); const tusb_desc_interface_t* desc_midi = (const tusb_desc_interface_t*) p_desc; - TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && - AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && - AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, 0); + TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && + AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, + 0); - // Find available interface - midid_interface_t * p_midi = NULL; - uint8_t idx; - for(idx=0; idxrhport = rhport; p_midi->itf_num = desc_midi->bInterfaceNumber; (void) p_midi->itf_num; - // next descriptor - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); // Find and open endpoint descriptors - uint8_t found_endpoints = 0; - while ( (found_endpoints < desc_midi->bNumEndpoints) && (drv_len <= max_len) ) - { - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { - TU_ASSERT(usbd_edpt_open(rhport, (const tusb_desc_endpoint_t*) p_desc), 0); - uint8_t ep_addr = ((const tusb_desc_endpoint_t*) p_desc)->bEndpointAddress; - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) - { - p_midi->ep_in = ep_addr; + uint8_t found_ep = 0; + while ((found_ep < desc_midi->bNumEndpoints) && tu_desc_in_bounds(p_desc, desc_end)) { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p_midi->ep_stream.tx, desc_ep); } else { - p_midi->ep_out = ep_addr; + tu_edpt_stream_open(&p_midi->ep_stream.rx, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_midi->ep_stream.rx) > 0, 0); // prepare to receive data } - // Class Specific MIDI Stream endpoint descriptor - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - - found_endpoints += 1; + p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor + found_ep++; } - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } - // Prepare for incoming data - _prep_out_transaction(idx); - - return drv_len; + return (uint16_t)(p_desc - (const uint8_t *)desc_itf); } // Invoked when a control transfer occurred on an interface of this class @@ -514,44 +428,31 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_req return false; // driver doesn't support any request yet } -bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) result; - (void) rhport; - - uint8_t idx; - midid_interface_t* p_midi; +bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void)result; - // Identify which interface to use - for (idx = 0; idx < CFG_TUD_MIDI; idx++) { - p_midi = &_midid_itf[idx]; - if ((ep_addr == p_midi->ep_out) || (ep_addr == p_midi->ep_in)) { - break; - } - } + uint8_t idx = find_midi_itf(ep_addr); TU_ASSERT(idx < CFG_TUD_MIDI); + midid_interface_t *p_midi = &_midid_itf[idx]; - // receive new data - if (ep_addr == p_midi->ep_out) { - tu_fifo_write_n(&p_midi->rx_ff, _midid_epbuf[idx].epout, (uint16_t)xferred_bytes); - - // invoke receive callback if available - tud_midi_rx_cb(idx); - - // prepare for next - // TODO for now ep_out is not used by public API therefore there is no race condition, - // and does not need to claim like ep_in - _prep_out_transaction(idx); - } else if (ep_addr == p_midi->ep_in) { - if (0 == write_flush(idx)) { - // 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->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE))) { - if (usbd_edpt_claim(rhport, p_midi->ep_in)) { - usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0); - } - } + tu_edpt_stream_t *ep_st_rx = &p_midi->ep_stream.rx; + tu_edpt_stream_t *ep_st_tx = &p_midi->ep_stream.tx; + + if (ep_addr == ep_st_rx->ep_addr) { + // Received new data: put into stream's fifo + if (result == XFER_RESULT_SUCCESS) { + tu_edpt_stream_read_xfer_complete(ep_st_rx, xferred_bytes); + tud_midi_rx_cb(idx); // invoke callback } + tu_edpt_stream_read_xfer(rhport, ep_st_rx); // prepare for next data + } else if (ep_addr == ep_st_tx->ep_addr && result == XFER_RESULT_SUCCESS) { + // sent complete: try to send more if possible + if (0 == tu_edpt_stream_write_xfer(rhport, ep_st_tx)) { + // If there is no data left, a ZLP should be sent if needed + (void)tu_edpt_stream_write_zlp_if_needed(rhport, ep_st_tx, xferred_bytes); + } + } else { + return false; } return true; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index d23516cec..ddbc2f9f0 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -36,21 +36,21 @@ #if !defined(CFG_TUD_MIDI_EP_BUFSIZE) && defined(CFG_TUD_MIDI_EPSIZE) #warning CFG_TUD_MIDI_EPSIZE is renamed to CFG_TUD_MIDI_EP_BUFSIZE, please update to use the new name - #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE + #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE #endif #ifndef CFG_TUD_MIDI_EP_BUFSIZE - #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif #ifdef __cplusplus - extern "C" { +extern "C" { #endif -/** \addtogroup MIDI_Serial Serial - * @{ - * \defgroup MIDI_Serial_Device Device - * @{ */ +//--------------------------------------------------------------------+ +// Application Callback API (optional) +//--------------------------------------------------------------------+ +void tud_midi_rx_cb(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) @@ -58,117 +58,77 @@ //--------------------------------------------------------------------+ // Check if midi interface is mounted -bool tud_midi_n_mounted (uint8_t itf); +bool tud_midi_n_mounted(uint8_t itf); // Get the number of bytes available for reading -uint32_t tud_midi_n_available (uint8_t itf, uint8_t cable_num); - -// Read byte stream (legacy) -uint32_t tud_midi_n_stream_read (uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize); - -// Write byte Stream (legacy) -uint32_t tud_midi_n_stream_write (uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize); - -// Read event packet (4 bytes) -bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]); - -// Write event packet (4 bytes) -bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]); +uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num); -//--------------------------------------------------------------------+ -// Application API (Single Interface) -//--------------------------------------------------------------------+ -static inline bool tud_midi_mounted (void); -static inline uint32_t tud_midi_available (void); - -static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize); -static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize); - -static inline bool tud_midi_packet_read (uint8_t packet[4]); -static inline bool tud_midi_packet_write (uint8_t const packet[4]); - -//------------- Deprecated API name -------------// -// TODO remove after 0.10.0 release - -TU_ATTR_DEPRECATED("tud_midi_read() is renamed to tud_midi_stream_read()") -static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize) -{ - return tud_midi_stream_read(buffer, bufsize); -} +// Read byte stream (legacy) +uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize); -TU_ATTR_DEPRECATED("tud_midi_write() is renamed to tud_midi_stream_write()") -static inline uint32_t tud_midi_write(uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) -{ - return tud_midi_stream_write(cable_num, buffer, bufsize); -} +// Write byte Stream (legacy) +uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize); +// Read an event 4-byte packet +bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]); -TU_ATTR_DEPRECATED("tud_midi_send() is renamed to tud_midi_packet_write()") -static inline bool tud_midi_send(uint8_t packet[4]) -{ - return tud_midi_packet_write(packet); -} +// Read multiple event packets, return number of read packets +uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets); -TU_ATTR_DEPRECATED("tud_midi_receive() is renamed to tud_midi_packet_read()") -static inline bool tud_midi_receive(uint8_t packet[4]) -{ - return tud_midi_packet_read(packet); -} +// Write an event 4-byte packet +bool tud_midi_n_packet_write(uint8_t itf, const uint8_t packet[4]); -//--------------------------------------------------------------------+ -// Application Callback API (optional) -//--------------------------------------------------------------------+ -void tud_midi_rx_cb(uint8_t itf); +// Write multiple event packets, return number of written packets +uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets); //--------------------------------------------------------------------+ -// Inline Functions +// Application API (Single Interface) //--------------------------------------------------------------------+ - -static inline bool tud_midi_mounted (void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_mounted(void) { return tud_midi_n_mounted(0); } -static inline uint32_t tud_midi_available (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_available(void) { return tud_midi_n_available(0, 0); } -static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_read(void *buffer, uint32_t bufsize) { return tud_midi_n_stream_read(0, 0, buffer, bufsize); } -static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi_stream_write(uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) { return tud_midi_n_stream_write(0, cable_num, buffer, bufsize); } -static inline bool tud_midi_packet_read (uint8_t packet[4]) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_read(uint8_t packet[4]) { return tud_midi_n_packet_read(0, packet); } -static inline bool tud_midi_packet_write (uint8_t const packet[4]) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_packet_read_n(uint8_t packets[], uint32_t max_packets) { + return tud_midi_n_packet_read_n(0, packets, max_packets); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_write(const uint8_t packet[4]) { return tud_midi_n_packet_write(0, packet); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_packet_write_n(const uint8_t packets[], uint32_t n_packets) { + return tud_midi_n_packet_write_n(0, packets, n_packets); +} + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void midid_init (void); -bool midid_deinit (void); -void midid_reset (uint8_t rhport); -uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); -bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); +void midid_init(void); +bool midid_deinit(void); +void midid_reset(uint8_t rhport); +uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request); +bool midid_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); #ifdef __cplusplus - } +} #endif -#endif /* TUSB_MIDI_DEVICE_H_ */ - -/** @} */ -/** @} */ +#endif diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 27724b194..c916ebe47 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -202,8 +202,9 @@ void vendord_reset(uint8_t rhport) { vendord_interface_t* p_itf = &_vendord_itf[i]; tu_memclr(p_itf, ITF_MEM_RESET_SIZE); tu_edpt_stream_clear(&p_itf->rx.stream); - tu_edpt_stream_clear(&p_itf->tx.stream); tu_edpt_stream_close(&p_itf->rx.stream); + + tu_edpt_stream_clear(&p_itf->tx.stream); tu_edpt_stream_close(&p_itf->tx.stream); } } diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 419046b8b..5c9e586fb 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -551,27 +551,10 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_ @returns Number of items in FIFO */ /******************************************************************************/ -uint16_t tu_fifo_count(tu_fifo_t *f) { +uint16_t tu_fifo_count(const tu_fifo_t *f) { return tu_min16(_ff_count(f->depth, f->wr_idx, f->rd_idx), f->depth); } -/******************************************************************************/ -/*! - @brief Check if FIFO is empty. - - As this function only reads the read and write pointers once, this function is - reentrant and thus thread and ISR save without any mutexes. - - @param[in] f - Pointer to the FIFO buffer to manipulate - - @returns Number of items in FIFO - */ -/******************************************************************************/ -bool tu_fifo_empty(tu_fifo_t *f) { - return f->wr_idx == f->rd_idx; -} - /******************************************************************************/ /*! @brief Check if FIFO is full. @@ -585,7 +568,7 @@ bool tu_fifo_empty(tu_fifo_t *f) { @returns Number of items in FIFO */ /******************************************************************************/ -bool tu_fifo_full(tu_fifo_t *f) { +bool tu_fifo_full(const tu_fifo_t *f) { return _ff_count(f->depth, f->wr_idx, f->rd_idx) >= f->depth; } @@ -602,7 +585,7 @@ bool tu_fifo_full(tu_fifo_t *f) { @returns Number of items in FIFO */ /******************************************************************************/ -uint16_t tu_fifo_remaining(tu_fifo_t *f) { +uint16_t tu_fifo_remaining(const tu_fifo_t *f) { return _ff_remaining(f->depth, f->wr_idx, f->rd_idx); } @@ -627,7 +610,7 @@ uint16_t tu_fifo_remaining(tu_fifo_t *f) { @returns True if overflow happened */ /******************************************************************************/ -bool tu_fifo_overflowed(tu_fifo_t *f) { +bool tu_fifo_overflowed(const tu_fifo_t *f) { return _ff_count(f->depth, f->wr_idx, f->rd_idx) > f->depth; } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 0f4ba00d8..9d8b864e9 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -155,33 +155,35 @@ void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_m #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) #endif -bool tu_fifo_write (tu_fifo_t* f, void const * data); -uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * data, uint16_t n); -#ifdef TUP_MEM_CONST_ADDR -uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n); -#endif +bool tu_fifo_write(tu_fifo_t *f, void const *data); +uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n); + +bool tu_fifo_read(tu_fifo_t *f, void *buffer); +uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n); -bool tu_fifo_read (tu_fifo_t* f, void * buffer); -uint16_t tu_fifo_read_n (tu_fifo_t* f, void * buffer, uint16_t n); #ifdef TUP_MEM_CONST_ADDR -uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n); +uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t *f, const void *data, uint16_t n); +uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t *f, void *buffer, uint16_t n); #endif -bool tu_fifo_peek (tu_fifo_t* f, void * p_buffer); -uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n); +bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer); +uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n); -uint16_t tu_fifo_count (tu_fifo_t* f); -uint16_t tu_fifo_remaining (tu_fifo_t* f); -bool tu_fifo_empty (tu_fifo_t* f); -bool tu_fifo_full (tu_fifo_t* f); -bool tu_fifo_overflowed (tu_fifo_t* f); -void tu_fifo_correct_read_pointer (tu_fifo_t* f); +uint16_t tu_fifo_count(const tu_fifo_t *f); +uint16_t tu_fifo_remaining(const tu_fifo_t *f); +bool tu_fifo_full(const tu_fifo_t *f); +bool tu_fifo_overflowed(const tu_fifo_t *f); -TU_ATTR_ALWAYS_INLINE static inline -uint16_t tu_fifo_depth(tu_fifo_t* f) { +TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_empty(const tu_fifo_t *f) { + return f->wr_idx == f->rd_idx; +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_depth(const tu_fifo_t *f) { return f->depth; } +void tu_fifo_correct_read_pointer(tu_fifo_t *f); + // Pointer modifications intended to be used in combinations with DMAs. // USE WITH CARE - NO SAFETY CHECKS CONDUCTED HERE! NOT MUTEX PROTECTED! void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n); diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index dcd5c45d6..367209e57 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -105,6 +105,10 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512; } +TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) { + return s->ep_addr != 0; +} + TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s) { s->ep_addr = 0; } @@ -121,7 +125,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* // Write to stream uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); -// Start an usb transfer if endpoint is not busy +// Start an usb transfer if endpoint is not busy. Return number of queued bytes uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s); // Start an zero-length packet if needed @@ -151,20 +155,18 @@ void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_byt // Complete read transfer with provided buffer TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t* s, const void * buf, uint32_t xferred_bytes) { +void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t *s, const void *buf, uint32_t xferred_bytes) { if (0u != tu_fifo_depth(&s->ff)) { tu_fifo_write_n(&s->ff, buf, (uint16_t) xferred_bytes); } } // Get the number of bytes available for reading -TU_ATTR_ALWAYS_INLINE static inline -uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_edpt_stream_read_available(const tu_edpt_stream_t *s) { return (uint32_t) tu_fifo_count(&s->ff); } -TU_ATTR_ALWAYS_INLINE static inline -bool tu_edpt_stream_peek(tu_edpt_stream_t* s, uint8_t* ch) { +TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_peek(tu_edpt_stream_t *s, uint8_t *ch) { return tu_fifo_peek(&s->ff, ch); } diff --git a/src/tusb.c b/src/tusb.c index 7411f19df..b308e2915 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -424,7 +424,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { TU_VERIFY(stream_claim(hwid, s), 0); // Pull data from FIFO -> EP buf - uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + const uint16_t count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); if (count > 0) { TU_ASSERT(stream_xfer(hwid, s, count), 0); @@ -437,7 +437,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { } } -uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { TU_VERIFY(bufsize > 0); // TODO support ZLP if (0 == tu_fifo_depth(&s->ff)) { -- cgit v1.3.1 From f11adb02ebc0c594a7114b08585b8af18c3ee6d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 12 Nov 2025 21:22:25 +0700 Subject: migrate cdc device to use edpt stream API tu_edpt_stream_open() does not clear fifo, allow for persistent stream when disconnect/reconnect --- .clang-format | 7 +- .../net_lwip_webserver/src/usb_descriptors.c | 2 +- src/class/cdc/cdc_device.c | 393 +++++++++------------ src/class/midi/midi_device.c | 2 + src/class/vendor/vendor_device.c | 16 +- src/common/tusb_private.h | 7 +- src/tusb.c | 8 +- 7 files changed, 194 insertions(+), 241 deletions(-) (limited to 'src/class/midi') diff --git a/.clang-format b/.clang-format index c278fec37..40d40f7e9 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,7 @@ --- Language: Cpp BasedOnStyle: LLVM -AlignAfterOpenBracket: AlwaysBreak +AlignAfterOpenBracket: Align AlignConsecutiveAssignments: Enabled: true AcrossEmptyLines: false @@ -38,6 +38,7 @@ AllowShortEnumsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: false @@ -57,8 +58,10 @@ BraceWrapping: SplitEmptyRecord: true SplitEmptyNamespace: true BracedInitializerIndentWidth: 2 +BreakBeforeBinaryOperators: None BreakConstructorInitializers: AfterColon BreakConstructorInitializersBeforeComma: false +ContinuationIndentWidth: 2 ColumnLimit: 120 ConstructorInitializerAllOnOneLineOrOnePerLine: false Cpp11BracedListStyle: true @@ -78,6 +81,8 @@ MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: All +PenaltyBreakBeforeFirstCallParameter: 1000000 +PenaltyBreakOpenParenthesis: 1000000 QualifierAlignment: Custom QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type'] ReflowComments: false diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index b49962d65..c976cb62b 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -270,7 +270,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_contro switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) { //-V2520 //-V2659 + switch (request->bRequest) { case 1: if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index b3253b141..92139b14e 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -48,28 +48,23 @@ typedef struct { uint8_t rhport; uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; - uint8_t ep_notify; uint8_t line_state; // Bit 0: DTR, Bit 1: RTS /*------------- From this point, data is not cleared by bus reset -------------*/ - char wanted_char; TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; + char wanted_char; - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; - - uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); + uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; + } stream; } cdcd_interface_t; -#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) +#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); @@ -80,111 +75,102 @@ typedef struct { #endif } cdcd_epbuf_t; -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ -static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; - -static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); - -static bool _prep_out_transaction(uint8_t itf) { - const uint8_t rhport = 0; - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY(tud_ready() && p_cdc->ep_out); - - uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= CFG_TUD_CDC_EP_BUFSIZE); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_out)); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_cdc->rx_ff); - - if (available >= CFG_TUD_CDC_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); - } else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(p_cdc->rhport, p_cdc->ep_out); - return false; - } -} - //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { - (void) itf; - (void) wanted_char; + (void)itf; + (void)wanted_char; } TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_notify_complete_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - (void) itf; - (void) dtr; - (void) rts; + (void)itf; + (void)dtr; + (void)rts; } -TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { - (void) itf; - (void) p_line_coding; +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, const cdc_line_coding_t *p_line_coding) { + (void)itf; + (void)p_line_coding; } TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { - (void) itf; - (void) duration_ms; + (void)itf; + (void)duration_ms; +} + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; +static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); + +TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) { + const cdcd_interface_t *p_cdc = &_cdcd_itf[idx]; + if (ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr || + (ep_addr == p_cdc->ep_notify && ep_addr != 0)) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { - TU_VERIFY(driver_cfg); + TU_VERIFY(driver_cfg != NULL); _cdcd_cfg = *driver_cfg; return true; } bool tud_cdc_n_ready(uint8_t itf) { - return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0; + TU_VERIFY(itf < CFG_TUD_CDC); + TU_VERIFY(tud_ready()); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + + const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->stream.tx); + const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->stream.rx); + return in_opened && out_opened; } bool tud_cdc_n_connected(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_CDC); + TU_VERIFY(tud_ready()); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; // DTR (bit 0) active is considered as connected - return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); + return tu_bit_test(p_cdc->line_state, 0); } uint8_t tud_cdc_n_get_line_state(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_CDC, 0); return _cdcd_itf[itf].line_state; } -void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) { +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) { + TU_VERIFY(itf < CFG_TUD_CDC, ); (*coding) = _cdcd_itf[itf].line_coding; } #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *state) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); @@ -200,8 +186,9 @@ bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *st } bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); @@ -218,6 +205,7 @@ bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed #endif void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { + TU_VERIFY(itf < CFG_TUD_CDC, ); _cdcd_itf[itf].wanted_char = wanted; } @@ -225,77 +213,55 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { // READ API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { - return tu_fifo_count(&_cdcd_itf[itf].rx_ff); + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_read_available(&p_cdc->stream.rx); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(itf); - return num_read; + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->stream.rx, buffer, bufsize); } -bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { - return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); +bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_peek(&p_cdc->stream.rx, chr); } void tud_cdc_n_read_flush(uint8_t itf) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(itf); + TU_VERIFY(itf < CFG_TUD_CDC, ); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + tu_edpt_stream_clear(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->stream.rx); } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t wr_count = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - - // flush if queue more than packet size - if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE - #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size - #endif - ) { - tud_cdc_n_write_flush(itf); - } - - return wr_count; + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->stream.tx, buffer, bufsize); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; - TU_VERIFY(tud_ready(), 0); // Skip if usb is not ready yet - - // No data to send - if (0 == tu_fifo_count(&p_cdc->tx_ff)) { - return 0; - } - - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_in), 0); // Claim the endpoint - - // Pull data from FIFO - const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); - - if (count > 0) { - TU_ASSERT(usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_in, p_epbuf->epin, count), 0); - return count; - } else { - // Release endpoint since we don't make any transfer - // Note: data is dropped if terminal is not connected - usbd_edpt_release(p_cdc->rhport, p_cdc->ep_in); - return 0; - } + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->stream.tx); } uint32_t tud_cdc_n_write_available(uint8_t itf) { - return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->stream.tx); } bool tud_cdc_n_write_clear(uint8_t itf) { - return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_clear(&p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -304,7 +270,8 @@ bool tud_cdc_n_write_clear(uint8_t itf) { void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { - cdcd_interface_t* p_cdc = &_cdcd_itf[i]; + cdcd_interface_t *p_cdc = &_cdcd_itf[i]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; p_cdc->wanted_char = (char) -1; @@ -314,44 +281,23 @@ void cdcd_init(void) { p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; - // Config RX fifo - tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false); + tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, + p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable - tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, _cdcd_cfg.tx_overwritabe_if_not_connected); - - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex); - TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); - - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL); - #endif + tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, + p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); } } bool cdcd_deinit(void) { - #if OSAL_MUTEX_REQUIRED for(uint8_t i=0; irx_ff.mutex_rd; - const osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; - - if (mutex_rd != NULL) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); - } - - if (mutex_wr != NULL) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); - } + tu_edpt_stream_deinit(&p_cdc->stream.rx); + tu_edpt_stream_deinit(&p_cdc->stream.tx); } - #endif - return true; } @@ -360,74 +306,85 @@ void cdcd_reset(uint8_t rhport) { for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; - tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - if (!_cdcd_cfg.rx_persistent) { - tu_fifo_clear(&p_cdc->rx_ff); - } - if (!_cdcd_cfg.tx_persistent) { - tu_fifo_clear(&p_cdc->tx_ff); - } - tu_fifo_set_overwritable(&p_cdc->tx_ff, _cdcd_cfg.tx_overwritabe_if_not_connected); + + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // // back to default + tu_edpt_stream_close(&p_cdc->stream.rx); + tu_edpt_stream_close(&p_cdc->stream.tx); } } uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) { // Only support ACM subclass - TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); + TU_VERIFY(TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, + 0); - // Find available interface - cdcd_interface_t* p_cdc; - uint8_t cdc_id; - for (cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) { - p_cdc = &_cdcd_itf[cdc_id]; - if (p_cdc->ep_in == 0) { - break; - } - } + const uint8_t cdc_id = find_cdc_itf(0); // Find available interface TU_ASSERT(cdc_id < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[cdc_id]; //------------- Control Interface -------------// p_cdc->rhport = rhport; p_cdc->itf_num = itf_desc->bInterfaceNumber; - uint16_t drv_len = sizeof(tusb_desc_interface_t); - const uint8_t* p_desc = tu_desc_next(itf_desc); + const uint8_t *p_desc = (const uint8_t *)itf_desc; + const uint8_t *desc_end = p_desc + max_len; - // Communication Functional Descriptors - while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { - drv_len += tu_desc_len(p_desc); + // Skip all class-specific descriptor + p_desc = tu_desc_next(itf_desc); + while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); } + // notification endpoint (optional) if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { - // notification endpoint const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notify = desc_ep->bEndpointAddress; - drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } - //------------- Data Interface (if any) -------------// - if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((const tusb_desc_interface_t*) p_desc)->bInterfaceClass)) { - // next to endpoint descriptor - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + //------------- Data Interface (optional) -------------// + if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) { + const tusb_desc_interface_t *data_itf_desc = (const tusb_desc_interface_t *)p_desc; + if (TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass) { + for (uint8_t e = 0; e < data_itf_desc->bNumEndpoints; e++) { + if (!tu_desc_in_bounds(p_desc, desc_end)) { + break; + } + p_desc = tu_desc_next(p_desc); - // Open endpoint pair - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - } + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; + tu_edpt_stream_open(stream_tx, desc_ep); + + if (_cdcd_cfg.tx_persistent) { + tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data + } else { + tu_edpt_stream_clear(stream_tx); + } + } else { + tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; - // Prepare for incoming data - _prep_out_transaction(cdc_id); + tu_edpt_stream_open(stream_rx, desc_ep); + if (!_cdcd_cfg.rx_persistent) { + tu_edpt_stream_clear(stream_rx); + } + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data + } + } - return drv_len; + p_desc = tu_desc_next(p_desc); + } + } + + return p_desc - (const uint8_t *)itf_desc; } // Invoked when a control transfer occurred on an interface of this class @@ -449,7 +406,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } TU_VERIFY(itf < CFG_TUD_CDC); - switch (request->bRequest) { //-V2520 //-V2659 + switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); @@ -484,15 +441,13 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa if (_cdcd_cfg.tx_overwritabe_if_not_connected) { - tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, !dtr); } else { - tu_fifo_set_overwritable(&p_cdc->tx_ff, false); + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, false); } TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); - - // Invoke callback - tud_cdc_line_state_cb(itf, dtr, rts); + tud_cdc_line_state_cb(itf, dtr, rts); // invoke callback } else { // nothing to do } @@ -507,7 +462,6 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } else { // nothing to do } - break; default: @@ -518,58 +472,45 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; + (void)result; - uint8_t itf; - cdcd_interface_t* p_cdc; - - // Identify which interface to use - for (itf = 0; itf < CFG_TUD_CDC; itf++) { - p_cdc = &_cdcd_itf[itf]; - if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in) || (ep_addr == p_cdc->ep_notify)) { - break; - } - } + uint8_t itf = find_cdc_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_CDC); - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; + tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; - // Received new data - if (ep_addr == p_cdc->ep_out) { - tu_fifo_write_n(&p_cdc->rx_ff, p_epbuf->epout, (uint16_t) xferred_bytes); + // Received new data, move to fifo + if (ep_addr == stream_rx->ep_addr) { + tu_edpt_stream_read_xfer_complete(stream_rx, xferred_bytes); - // Check for wanted char and invoke callback if needed - if (((signed char) p_cdc->wanted_char) != -1) { + // Check for wanted char and invoke wanted callback (multiple times if multiple wanted received) + if (((signed char)p_cdc->wanted_char) != -1) { for (uint32_t i = 0; i < xferred_bytes; i++) { - if ((p_cdc->wanted_char == (char) p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { + if ((p_cdc->wanted_char == (char)stream_rx->ep_buf[i]) && !tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } - // invoke receive callback (if there is still data) - if (!tu_fifo_empty(&p_cdc->rx_ff)) { + // invoke receive callback if there is still data + if (!tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_cb(itf); } - // prepare for OUT transaction - _prep_out_transaction(itf); + tu_edpt_stream_read_xfer(rhport, stream_rx); // prepare for more data } // Data sent to host, we continue to fetch from tx fifo to send. // Note: This will cause incorrect baudrate set in line coding. // Though maybe the baudrate is not really important !!! - if (ep_addr == p_cdc->ep_in) { + if (ep_addr == stream_tx->ep_addr) { // invoke transmit callback to possibly refill tx fifo tud_cdc_tx_complete_cb(itf); - if (0 == tud_cdc_n_write_flush(itf)) { - // If there is no data left, a ZLP should be sent if - // xferred_bytes is multiple of EP Packet size and not zero - if (0 == tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes > 0 && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { - if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0)); - } - } + if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) { + // If there is no data left, a ZLP should be sent if needed + tu_edpt_stream_write_zlp_if_needed(rhport, stream_tx, xferred_bytes); } } diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index f065e486a..79e7dfa71 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -405,8 +405,10 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_open(&p_midi->ep_stream.tx, desc_ep); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); } else { tu_edpt_stream_open(&p_midi->ep_stream.rx, desc_ep); + tu_edpt_stream_clear(&p_midi->ep_stream.rx); TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_midi->ep_stream.rx) > 0, 0); // prepare to receive data } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c916ebe47..7da4d2239 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -234,16 +234,18 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - // open endpoint stream, skip if already opened + // open endpoint stream, skip if already opened (multiple IN/OUT endpoints) if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - if (p_vendor->tx.stream.ep_addr == 0) { - tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep); - tud_vendor_n_write_flush(itf); + tu_edpt_stream_t *stream_tx = &p_vendor->tx.stream; + if (stream_tx->ep_addr == 0) { + tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data } } else { - if (p_vendor->rx.stream.ep_addr == 0) { - tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep); - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data + tu_edpt_stream_t *stream_rx = &p_vendor->rx.stream; + if (stream_rx->ep_addr == 0) { + tu_edpt_stream_open(stream_rx, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data } } } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 367209e57..f82f87b6f 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -100,7 +100,6 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); // Open an stream for an endpoint TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { - tu_fifo_clear(&s->ff); s->ep_addr = desc_ep->bEndpointAddress; s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512; } @@ -113,11 +112,15 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s->ep_addr = 0; } -// Clear fifo TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { return tu_fifo_clear(&s->ff); } +TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *s) { + return tu_fifo_empty(&s->ff); +} + + //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index b308e2915..df33f2680 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -354,8 +354,8 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { - (void) s; +bool tu_edpt_stream_deinit(tu_edpt_stream_t *s) { + (void)s; #if OSAL_MUTEX_REQUIRED if (s->ff.mutex_wr) { osal_mutex_delete(s->ff.mutex_wr); @@ -363,7 +363,7 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { if (s->ff.mutex_rd) { osal_mutex_delete(s->ff.mutex_rd); } -#endif + #endif return true; } @@ -412,7 +412,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_st bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (mps - 1)))); + TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (mps - 1)))); TU_VERIFY(stream_claim(hwid, s)); TU_ASSERT(stream_xfer(hwid, s, 0)); return true; -- cgit v1.3.1 From 397a3af8afc4bc5460572da4a40629684dfa788c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 13 Nov 2025 12:02:02 +0700 Subject: clear endpoint stream when open for cdc_host and midi_host --- src/class/cdc/cdc_device.c | 15 ++++++------- src/class/cdc/cdc_host.c | 50 ++++++++++++++++++-------------------------- src/class/midi/midi_device.c | 14 +++++++------ src/class/midi/midi_host.c | 48 ++++++++++++++++++++++-------------------- src/common/tusb_common.h | 2 +- src/common/tusb_private.h | 1 - src/tusb.c | 2 +- 7 files changed, 61 insertions(+), 71 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 92139b14e..80fa81d99 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -141,7 +141,7 @@ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { bool tud_cdc_n_ready(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + const cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->stream.tx); const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->stream.rx); @@ -151,9 +151,8 @@ bool tud_cdc_n_ready(uint8_t itf) { bool tud_cdc_n_connected(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; // DTR (bit 0) active is considered as connected - return tu_bit_test(p_cdc->line_state, 0); + return tu_bit_test(_cdcd_itf[itf].line_state, 0); } uint8_t tud_cdc_n_get_line_state(uint8_t itf) { @@ -214,8 +213,7 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_read_available(&p_cdc->stream.rx); + return tu_edpt_stream_read_available(&_cdcd_itf[itf].stream.rx); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { @@ -226,8 +224,7 @@ uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { TU_VERIFY(itf < CFG_TUD_CDC); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_peek(&p_cdc->stream.rx, chr); + return tu_edpt_stream_peek(&_cdcd_itf[itf].stream.rx, chr); } void tud_cdc_n_read_flush(uint8_t itf) { @@ -362,8 +359,8 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; - tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_open(stream_tx, desc_ep); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data } else { @@ -384,7 +381,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } } - return p_desc - (const uint8_t *)itf_desc; + return (uint16_t)(p_desc - (const uint8_t *)itf_desc); } // Invoked when a control transfer occurred on an interface of this class diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 7fdf0a7b9..35717ddf6 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -298,6 +298,7 @@ TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial d //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +static bool open_ep_stream_pair(cdch_interface_t *p_cdc, const tusb_desc_endpoint_t *desc_ep); TU_ATTR_ALWAYS_INLINE static inline cdch_interface_t * get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); @@ -364,7 +365,7 @@ static cdch_interface_t* get_itf_by_xfer(const tuh_xfer_t * xfer) { #endif default: - break; + break; // unknown driver } } } @@ -389,8 +390,6 @@ static cdch_interface_t * make_new_itf(uint8_t daddr, tusb_desc_interface_t cons return NULL; } -static bool open_ep_stream_pair(cdch_interface_t * p_cdc , tusb_desc_endpoint_t const *desc_ep); - //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -519,7 +518,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->daddr, &p_cdc->stream.rx); + (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -648,13 +647,10 @@ bool cdch_init(void) { 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, - 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, CFG_TUH_CDC_RX_EPSIZE); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + epbuf->tx, CFG_TUH_CDC_TX_EPSIZE)); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, + CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx, CFG_TUH_CDC_RX_EPSIZE)); } return true; @@ -663,8 +659,8 @@ bool cdch_init(void) { bool cdch_deinit(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; - tu_edpt_stream_deinit(&p_cdc->stream.tx); - tu_edpt_stream_deinit(&p_cdc->stream.rx); + (void)tu_edpt_stream_deinit(&p_cdc->stream.tx); + (void)tu_edpt_stream_deinit(&p_cdc->stream.rx); } return true; } @@ -674,11 +670,9 @@ void cdch_close(uint8_t daddr) { cdch_interface_t *p_cdc = &cdch_data[idx]; if (p_cdc->daddr == daddr) { TU_LOG_CDC(p_cdc, "close"); + tuh_cdc_umount_cb(idx); // invoke callback - // Invoke application callback - tuh_cdc_umount_cb(idx); - - p_cdc->daddr = 0; + p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); @@ -696,13 +690,12 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t TU_ASSERT(p_cdc); if (ep_addr == p_cdc->stream.tx.ep_addr) { - // invoke tx complete callback to possibly refill tx fifo - tuh_cdc_tx_complete_cb(idx); + tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback 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(daddr, &p_cdc->stream.tx, xferred_bytes); + (void)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 @@ -718,7 +711,6 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t #endif { tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); - tuh_cdc_rx_cb(idx); // invoke receive callback } @@ -727,7 +719,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } else if (ep_addr == p_cdc->ep_notif) { // TODO handle notification endpoint } else { - TU_ASSERT(false); + return false; } return true; @@ -736,20 +728,17 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ - static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t const *desc_ep) { for (size_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); + tu_edpt_stream_t *stream = + (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; + tu_edpt_stream_open(stream, desc_ep); + tu_edpt_stream_clear(stream); - if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); - } else { - tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); - } - - desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep); + desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); } return true; @@ -832,6 +821,7 @@ static void cdch_process_set_config(tuh_xfer_t *xfer) { } } +// return false if there is no active transfer static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { enum { ENUM_SET_LINE_CODING = 0, diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 79e7dfa71..b20903d68 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -404,15 +404,17 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_midi->ep_stream.tx, desc_ep); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; + tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_clear(stream_tx); } else { - tu_edpt_stream_open(&p_midi->ep_stream.rx, desc_ep); - tu_edpt_stream_clear(&p_midi->ep_stream.rx); - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_midi->ep_stream.rx) > 0, 0); // prepare to receive data + tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; + tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_clear(stream_rx); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare to receive data } - p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor + p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor found_ep++; } diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 8b78fe945..07062875c 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -59,9 +59,6 @@ typedef struct { uint8_t iInterface; uint8_t itf_count; // number of interface including Audio Control + MIDI streaming - uint8_t ep_in; // IN endpoint address - uint8_t ep_out; // OUT endpoint address - uint8_t rx_cable_count; // IN endpoint CS descriptor bNumEmbMIDIJack value uint8_t tx_cable_count; // OUT endpoint CS descriptor bNumEmbMIDIJack value @@ -147,8 +144,6 @@ void midih_close(uint8_t daddr) { TU_LOG_DRV(" MIDI close addr = %u index = %u\r\n", daddr, idx); tuh_midi_umount_cb(idx); - p_midi->ep_in = 0; - p_midi->ep_out = 0; p_midi->bInterfaceNumber = 0; p_midi->rx_cable_count = 0; p_midi->tx_cable_count = 0; @@ -169,23 +164,25 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint const uint8_t idx = get_idx_by_ep_addr(dev_addr, ep_addr); TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; + tu_edpt_stream_t *ep_str_rx = &p_midi->ep_stream.rx; + tu_edpt_stream_t *ep_str_tx = &p_midi->ep_stream.tx; - if (ep_addr == p_midi->ep_stream.rx.ep_addr) { + if (ep_addr == ep_str_rx->ep_addr) { // receive new data, put it into FIFO and invoke callback if available // Note: some devices send back all zero packets even if there is no data ready - if (xferred_bytes && !tu_mem_is_zero(p_midi->ep_stream.rx.ep_buf, xferred_bytes)) { - tu_edpt_stream_read_xfer_complete(&p_midi->ep_stream.rx, xferred_bytes); + if (xferred_bytes && !tu_mem_is_zero(ep_str_rx->ep_buf, xferred_bytes)) { + tu_edpt_stream_read_xfer_complete(ep_str_rx, xferred_bytes); tuh_midi_rx_cb(idx, xferred_bytes); } - tu_edpt_stream_read_xfer(dev_addr, &p_midi->ep_stream.rx); // prepare for next transfer - } else if (ep_addr == p_midi->ep_stream.tx.ep_addr) { + tu_edpt_stream_read_xfer(dev_addr, ep_str_rx); // prepare for next transfer + } else if (ep_addr == ep_str_tx->ep_addr) { tuh_midi_tx_cb(idx, xferred_bytes); - if (0 == tu_edpt_stream_write_xfer(dev_addr, &p_midi->ep_stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(dev_addr, ep_str_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->ep_stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(dev_addr, ep_str_tx, xferred_bytes); } } @@ -295,21 +292,20 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress); + tu_edpt_stream_t *ep_stream; if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { - p_midi->ep_out = p_ep->bEndpointAddress; p_midi->tx_cable_count = p_csep->bNumEmbMIDIJack; desc_cb.desc_epout = p_ep; - - TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); - tu_edpt_stream_open(&p_midi->ep_stream.tx, p_ep); + ep_stream = &p_midi->ep_stream.tx; } else { - p_midi->ep_in = p_ep->bEndpointAddress; p_midi->rx_cable_count = p_csep->bNumEmbMIDIJack; - desc_cb.desc_epin = p_ep; - - TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); - tu_edpt_stream_open(&p_midi->ep_stream.rx, p_ep); + desc_cb.desc_epin = p_ep; + ep_stream = &p_midi->ep_stream.rx; } + TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); + tu_edpt_stream_open(ep_stream, p_ep); + tu_edpt_stream_clear(ep_stream); + break; } @@ -379,8 +375,14 @@ bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { desc->bDescriptorType = TUSB_DESC_INTERFACE; desc->bInterfaceNumber = p_midi->bInterfaceNumber; - desc->bAlternateSetting = 0; - desc->bNumEndpoints = (uint8_t)((p_midi->ep_in != 0 ? 1:0) + (p_midi->ep_out != 0 ? 1:0)); + desc->bAlternateSetting = 0; + desc->bNumEndpoints = 0; + if (tu_edpt_stream_is_opened(&p_midi->ep_stream.tx)) { + desc->bNumEndpoints++; + } + if (tu_edpt_stream_is_opened(&p_midi->ep_stream.rx)) { + desc->bNumEndpoints++; + } desc->bInterfaceClass = TUSB_CLASS_AUDIO; desc->bInterfaceSubClass = AUDIO_SUBCLASS_MIDI_STREAMING; desc->bInterfaceProtocol = 0; diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 7aa42a2d7..f377d5272 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -354,7 +354,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE]; } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_in_bounds(uint8_t const* p_desc, uint8_t const* desc_end) { +TU_ATTR_ALWAYS_INLINE static inline bool tu_desc_in_bounds(const uint8_t *p_desc, const uint8_t *desc_end) { if (p_desc >= desc_end) { return false; } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index f82f87b6f..be1264a71 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -120,7 +120,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t * return tu_fifo_empty(&s->ff); } - //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index df33f2680..6fb5309ab 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -517,7 +517,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { } uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { - uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); + const uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize); tu_edpt_stream_read_xfer(hwid, s); return num_read; } -- cgit v1.3.1 From 0fa30024333508b6cd6e1a68dfaf3cdcf1377671 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Nov 2025 16:34:00 +0700 Subject: omit ep buffer for midi device if device support CFG_TUD_EDPT_DEDICATED_HWFIFO --- src/class/cdc/cdc_device.h | 8 ++++++++ src/class/midi/midi_device.c | 26 ++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 6f21af4f3..8b5761747 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -36,6 +36,14 @@ #define CFG_TUD_CDC_NOTIFY 0 #endif +#ifndef CFG_TUD_CDC_TX_BUFSIZE + #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#endif + +#ifndef CFG_TUD_CDC_RX_BUFSIZE + #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#endif + #if !defined(CFG_TUD_CDC_EP_BUFSIZE) && defined(CFG_TUD_CDC_EPSIZE) #warning CFG_TUD_CDC_EPSIZE is renamed to CFG_TUD_CDC_EP_BUFSIZE, please update to use the new name #define CFG_TUD_CDC_EP_BUFSIZE CFG_TUD_CDC_EPSIZE diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index b20903d68..8d1dc7d4a 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (CFG_TUD_ENABLED && CFG_TUD_MIDI) +#if CFG_TUD_ENABLED && CFG_TUD_MIDI //--------------------------------------------------------------------+ // INCLUDE @@ -71,20 +71,21 @@ typedef struct { static midid_interface_t _midid_itf[CFG_TUD_MIDI]; -// Endpoint Transfer buffer + #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 +// Endpoint Transfer buffer: not used if dedicated hw FIFO is available typedef struct { TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE); TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE); } midid_epbuf_t; CFG_TUD_MEM_SECTION static midid_epbuf_t _midid_epbuf[CFG_TUD_MIDI]; + #endif //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ bool tud_midi_n_mounted (uint8_t itf) { midid_interface_t *p_midi = &_midid_itf[itf]; - const bool tx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.tx); const bool rx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.rx); return tx_opened && rx_opened; @@ -313,18 +314,23 @@ uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_ //--------------------------------------------------------------------+ void midid_init(void) { tu_memclr(_midid_itf, sizeof(_midid_itf)); - for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { midid_interface_t *p_midi = &_midid_itf[i]; + + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + uint8_t *epout_buf = NULL; + uint8_t *epin_buf = NULL; + #else midid_epbuf_t *p_epbuf = &_midid_epbuf[i]; + uint8_t *epout_buf = p_epbuf->epout; + uint8_t *epin_buf = p_epbuf->epin; + #endif - tu_edpt_stream_init( - &p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, - p_epbuf->epout, CFG_TUD_MIDI_EP_BUFSIZE); + tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, + CFG_TUD_MIDI_RX_BUFSIZE, epout_buf, CFG_TUD_MIDI_EP_BUFSIZE); - tu_edpt_stream_init( - &p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, p_epbuf->epin, - CFG_TUD_MIDI_EP_BUFSIZE); + tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, + epin_buf, CFG_TUD_MIDI_EP_BUFSIZE); } } -- cgit v1.3.1 From 39853dfb25c8828490e197ad4c1dd9616949110a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Dec 2025 20:47:08 +0700 Subject: move hwid into edpt stream for consistent API --- src/class/cdc/cdc_device.c | 33 ++++++++-------- src/class/cdc/cdc_host.c | 20 +++++----- src/class/midi/midi_device.c | 35 +++++++++-------- src/class/midi/midi_host.c | 32 ++++++++-------- src/class/vendor/vendor_device.c | 29 +++++++------- src/common/tusb_private.h | 28 +++++++------- src/device/usbd.c | 14 +++---- src/tusb.c | 83 ++++++++++++++++++++-------------------- 8 files changed, 139 insertions(+), 135 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index dfdee8bd4..8ea4080cc 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -203,7 +203,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->rx_stream, buffer, bufsize); + return tu_edpt_stream_read(&p_cdc->rx_stream, buffer, bufsize); } bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { @@ -215,7 +215,7 @@ void tud_cdc_n_read_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, ); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; tu_edpt_stream_clear(&p_cdc->rx_stream); - tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->rx_stream); + tu_edpt_stream_read_xfer(&p_cdc->rx_stream); } //--------------------------------------------------------------------+ @@ -224,19 +224,19 @@ void tud_cdc_n_read_flush(uint8_t itf) { uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->tx_stream, buffer, bufsize); + return tu_edpt_stream_write(&p_cdc->tx_stream, buffer, bufsize); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->tx_stream); + return tu_edpt_stream_write_xfer(&p_cdc->tx_stream); } uint32_t tud_cdc_n_write_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->tx_stream); + return tu_edpt_stream_write_available(&p_cdc->tx_stream); } bool tud_cdc_n_write_clear(uint8_t itf) { @@ -269,14 +269,14 @@ void cdcd_init(void) { uint8_t *epin_buf = _cdcd_epbuf[i].epin; #endif - tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, - epout_buf, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf, + CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable - tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, - p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, p_cdc->tx_ff_buf, + CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); } } @@ -351,20 +351,20 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep); if (_cdcd_cfg.tx_persistent) { - tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data + tu_edpt_stream_write_xfer(stream_tx); // flush pending data } else { tu_edpt_stream_clear(stream_tx); } } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data } } @@ -460,6 +460,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void)rhport; (void)result; uint8_t itf = find_cdc_itf(ep_addr); @@ -510,7 +511,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ tud_cdc_rx_cb(itf); } - tu_edpt_stream_read_xfer(rhport, stream_rx); // prepare for more data + tu_edpt_stream_read_xfer(stream_rx); // prepare for more data } // Data sent to host, we continue to fetch from tx fifo to send. @@ -518,9 +519,9 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (ep_addr == stream_tx->ep_addr) { tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo - if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) { + if (0 == tu_edpt_stream_write_xfer(stream_tx)) { // If there is no data left, a ZLP should be sent if needed - tu_edpt_stream_write_zlp_if_needed(rhport, stream_tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(stream_tx, xferred_bytes); } } diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index e069d9f71..28abbf098 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -470,13 +470,13 @@ bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t * line_coding) 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->daddr, &p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(&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->daddr, &p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { @@ -489,7 +489,7 @@ bool tuh_cdc_write_clear(uint8_t idx) { 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->daddr, &p_cdc->stream.tx); + return tu_edpt_stream_write_available(&p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -499,7 +499,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) { 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->daddr, &p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { @@ -519,7 +519,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); tu_edpt_stream_clear(&p_cdc->stream.rx); - (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); + (void)tu_edpt_stream_read_xfer(&p_cdc->stream.rx); return true; } @@ -693,10 +693,10 @@ 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) { tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback - if (0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(&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 - (void)tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); + (void)tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } } else if (ep_addr == p_cdc->stream.rx.ep_addr) { #if CFG_TUH_CDC_FTDI @@ -716,7 +716,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } // prepare for next transfer if needed - tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else if (ep_addr == p_cdc->ep_notif) { // TODO handle notification endpoint } else { @@ -736,7 +736,7 @@ 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)); tu_edpt_stream_t *stream = (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; - tu_edpt_stream_open(stream, desc_ep); + tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep); tu_edpt_stream_clear(stream); desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); @@ -799,7 +799,7 @@ static void set_config_complete(cdch_interface_t *p_cdc, bool success) { p_cdc->mounted = true; tuh_cdc_mount_cb(idx); // Prepare for incoming data - tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else { // clear the interface entry p_cdc->daddr = 0; diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 8d1dc7d4a..e0a5aa9c3 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -172,7 +172,7 @@ bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); - return 4 == tu_edpt_stream_read(p_midi->rhport, ep_str, packet, 4); + return 4 == tu_edpt_stream_read(ep_str, packet, 4); } uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) { @@ -180,7 +180,7 @@ uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_p tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - const uint32_t num_read = tu_edpt_stream_read(p_midi->rhport, ep_str, packets, 4u * max_packets); + const uint32_t num_read = tu_edpt_stream_read(ep_str, packets, 4u * max_packets); return num_read >> 2u; } @@ -195,7 +195,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t * uint32_t i = 0; while (i < bufsize) { - if (tu_edpt_stream_write_available(p_midi->rhport, ep_str) < 4) { + if (tu_edpt_stream_write_available(ep_str) < 4) { break; } @@ -268,7 +268,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t * stream->buffer[idx] = 0; } - const uint32_t count = tu_edpt_stream_write(p_midi->rhport, ep_str, stream->buffer, 4); + const uint32_t count = tu_edpt_stream_write(ep_str, stream->buffer, 4); // complete current event packet, reset stream stream->index = stream->total = 0; @@ -278,7 +278,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t * } } - (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + (void)tu_edpt_stream_write_xfer(ep_str); return i; } @@ -288,9 +288,9 @@ bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) { tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); - TU_VERIFY(tu_edpt_stream_write_available(p_midi->rhport, ep_str) >= 4); - TU_VERIFY(tu_edpt_stream_write(p_midi->rhport, ep_str, packet, 4) > 0); - (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + TU_VERIFY(tu_edpt_stream_write_available(ep_str) >= 4); + TU_VERIFY(tu_edpt_stream_write(ep_str, packet, 4) > 0); + (void)tu_edpt_stream_write_xfer(ep_str); return true; } @@ -300,11 +300,11 @@ uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - uint32_t n_bytes = tu_edpt_stream_write_available(p_midi->rhport, ep_str); + uint32_t n_bytes = tu_edpt_stream_write_available(ep_str); n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2u); - const uint32_t n_write = tu_edpt_stream_write(p_midi->rhport, ep_str, packets, n_bytes); - (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + const uint32_t n_write = tu_edpt_stream_write(ep_str, packets, n_bytes); + (void)tu_edpt_stream_write_xfer(ep_str); return n_write >> 2u; } @@ -411,13 +411,13 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; - tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; - tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep); tu_edpt_stream_clear(stream_rx); - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare to receive data + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare to receive data } p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor @@ -439,6 +439,7 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_req } bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void)rhport; (void)result; uint8_t idx = find_midi_itf(ep_addr); @@ -454,12 +455,12 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32 tu_edpt_stream_read_xfer_complete(ep_st_rx, xferred_bytes); tud_midi_rx_cb(idx); // invoke callback } - tu_edpt_stream_read_xfer(rhport, ep_st_rx); // prepare for next data + tu_edpt_stream_read_xfer(ep_st_rx); // prepare for next data } else if (ep_addr == ep_st_tx->ep_addr && result == XFER_RESULT_SUCCESS) { // sent complete: try to send more if possible - if (0 == tu_edpt_stream_write_xfer(rhport, ep_st_tx)) { + if (0 == tu_edpt_stream_write_xfer(ep_st_tx)) { // If there is no data left, a ZLP should be sent if needed - (void)tu_edpt_stream_write_zlp_if_needed(rhport, ep_st_tx, xferred_bytes); + (void)tu_edpt_stream_write_zlp_if_needed(ep_st_tx, xferred_bytes); } } else { return false; diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 07062875c..b4f5ac445 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -175,14 +175,14 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint tuh_midi_rx_cb(idx, xferred_bytes); } - tu_edpt_stream_read_xfer(dev_addr, ep_str_rx); // prepare for next transfer + tu_edpt_stream_read_xfer(ep_str_rx); // prepare for next transfer } else if (ep_addr == ep_str_tx->ep_addr) { tuh_midi_tx_cb(idx, xferred_bytes); - if (0 == tu_edpt_stream_write_xfer(dev_addr, ep_str_tx)) { + if (0 == tu_edpt_stream_write_xfer(ep_str_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, ep_str_tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(ep_str_tx, xferred_bytes); } } @@ -303,7 +303,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d ep_stream = &p_midi->ep_stream.rx; } TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); - tu_edpt_stream_open(ep_stream, p_ep); + tu_edpt_stream_open(ep_stream, dev_addr, p_ep); tu_edpt_stream_clear(ep_stream); break; @@ -335,7 +335,7 @@ bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) { }; tuh_midi_mount_cb(idx, &mount_cb_data); - tu_edpt_stream_read_xfer(dev_addr, &p_midi->ep_stream.rx); // prepare for incoming data + tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); // prepare for incoming data // No special config things to do for MIDI usbh_driver_set_config_complete(dev_addr, p_midi->bInterfaceNumber); @@ -414,7 +414,7 @@ uint32_t tuh_midi_read_available(uint8_t idx) { uint32_t tuh_midi_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; - return tu_edpt_stream_write_xfer(p_midi->daddr, &p_midi->ep_stream.tx); + return tu_edpt_stream_write_xfer(&p_midi->ep_stream.tx); } //--------------------------------------------------------------------+ @@ -427,7 +427,7 @@ uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t* buffer, uint32_t bufsize) uint32_t count4 = tu_min32(bufsize, tu_edpt_stream_read_available(&p_midi->ep_stream.rx)); count4 = tu_align4(count4); // round down to multiple of 4 TU_VERIFY(count4 > 0, 0); - return tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, buffer, count4); + return tu_edpt_stream_read(&p_midi->ep_stream.rx, buffer, count4); } uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bufsize) { @@ -436,7 +436,7 @@ uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bu const uint32_t bufsize4 = tu_align4(bufsize); TU_VERIFY(bufsize4 > 0, 0); - return tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, buffer, bufsize4); + return tu_edpt_stream_write(&p_midi->ep_stream.tx, buffer, bufsize4); } //--------------------------------------------------------------------+ @@ -450,8 +450,8 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu midi_driver_stream_t *stream = &p_midi->stream_write; uint32_t byte_count = 0; - while ((byte_count < bufsize) && (tu_edpt_stream_write_available(p_midi->daddr, &p_midi->ep_stream.tx) >= 4)) { - uint8_t const data = buffer[byte_count]; + while ((byte_count < bufsize) && (tu_edpt_stream_write_available(&p_midi->ep_stream.tx) >= 4)) { + const uint8_t data = buffer[byte_count]; byte_count++; if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) { // real-time messages need to be sent right away @@ -460,7 +460,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu streamrt.buffer[1] = data; streamrt.index = 2; streamrt.total = 2; - uint32_t const count = tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, streamrt.buffer, 4); + const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, streamrt.buffer, 4); TU_ASSERT(count == 4, byte_count); // Check FIFO overflown, since we already check fifo remaining. It is probably race condition } else if (stream->index == 0) { //------------- New event packet -------------// @@ -529,7 +529,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu } TU_LOG3_MEM(stream->buffer, 4, 2); - const uint32_t count = tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, stream->buffer, 4); + const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, stream->buffer, 4); // complete current event packet, reset stream stream->index = 0; @@ -551,7 +551,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff return 0; } *p_cable_num = (one_byte >> 4) & 0xf; - uint32_t nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + uint32_t nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->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->stream_read.buffer[0] >> 4) & 0x0f; @@ -579,7 +579,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff } else { // bad packet discard - nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); continue; } } else if (status < MIDI_STATUS_SYSEX_START) { @@ -626,7 +626,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff } else { // bad packet discard - nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); continue; } @@ -639,7 +639,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff uint8_t new_cable = (one_byte >> 4) & 0xf; if (new_cable == *p_cable_num) { // still on the same cable. Continue reading the stream - nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); } } } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index eb78a13c4..9972911e0 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -119,14 +119,14 @@ bool tud_vendor_n_peek(uint8_t idx, uint8_t *u8) { uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_read(p_itf->rhport, &p_itf->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(&p_itf->stream.rx, buffer, bufsize); } void tud_vendor_n_read_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, ); vendord_interface_t *p_itf = &_vendord_itf[idx]; tu_edpt_stream_clear(&p_itf->stream.rx); - tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->stream.rx); + tu_edpt_stream_read_xfer(&p_itf->stream.rx); } #endif @@ -134,7 +134,7 @@ void tud_vendor_n_read_flush(uint8_t idx) { bool tud_vendor_n_read_xfer(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->stream.rx); + return tu_edpt_stream_read_xfer(&p_itf->stream.rx); } #endif @@ -145,20 +145,20 @@ bool tud_vendor_n_read_xfer(uint8_t idx) { uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_write(p_itf->rhport, &p_itf->stream.tx, buffer, (uint16_t)bufsize); + return tu_edpt_stream_write(&p_itf->stream.tx, buffer, (uint16_t)bufsize); } #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_write_xfer(p_itf->rhport, &p_itf->stream.tx); + return tu_edpt_stream_write_xfer(&p_itf->stream.tx); } uint32_t tud_vendor_n_write_available(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_write_available(p_itf->rhport, &p_itf->stream.tx); + return tu_edpt_stream_write_available(&p_itf->stream.tx); } #endif @@ -270,15 +270,15 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_vendor->stream.tx; if (stream_tx->ep_addr == 0) { - tu_edpt_stream_open(stream_tx, desc_ep); - tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data + tu_edpt_stream_open(stream_tx, rhport, desc_ep); + tu_edpt_stream_write_xfer(stream_tx); // flush pending data } } else { tu_edpt_stream_t *stream_rx = &p_vendor->stream.rx; if (stream_rx->ep_addr == 0) { - tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data #endif } } @@ -291,7 +291,8 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin } bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; + (void)rhport; + (void)result; const uint8_t idx = find_vendor_itf(ep_addr); TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_vendor = &_vendord_itf[idx]; @@ -310,7 +311,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint #endif #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx); // prepare next data + tu_edpt_stream_read_xfer(&p_vendor->stream.rx); // prepare next data #endif } else if (ep_addr == p_vendor->stream.tx.ep_addr) { // Send complete @@ -318,9 +319,9 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // try to send more if possible - if (0 == tu_edpt_stream_write_xfer(rhport, &p_vendor->stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(&p_vendor->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(rhport, &p_vendor->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(&p_vendor->stream.tx, xferred_bytes); } #endif } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 69e82cda1..5cea7b5a0 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -65,17 +65,17 @@ typedef struct TU_ATTR_PACKED { } tu_edpt_state_t; typedef struct { - bool is_host; // 1: host, 0: device + uint8_t hwid; // device: rhport, host: daddr + bool is_host; // 1: host, 0: device uint8_t ep_addr; - uint16_t ep_bufsize; + uint16_t mps; + uint16_t ep_bufsize; uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; - uint16_t mps; // mutex: read if rx, otherwise write OSAL_MUTEX_DEF(ff_mutexdef); - }tu_edpt_stream_t; //--------------------------------------------------------------------+ @@ -112,8 +112,8 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); //--------------------------------------------------------------------+ // Init an endpoint stream -bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, - void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); +bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, + uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize); // Deinit an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) { @@ -129,7 +129,9 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t } // Open an endpoint stream -TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { +TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid, + const tusb_desc_endpoint_t *desc_ep) { + s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; s->mps = tu_edpt_packet_size(desc_ep); } @@ -155,27 +157,27 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t * //--------------------------------------------------------------------+ // Write to stream -uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy. Return number of queued bytes -uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s); // Start an zero-length packet if needed -bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes); +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes); // Get the number of bytes available for writing to FIFO // Note: if no fifo, return endpoint size if not busy, 0 otherwise -uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s); //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ // Read from stream -uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy -uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s); // Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline diff --git a/src/device/usbd.c b/src/device/usbd.c index 86cbcac26..80d9fee3e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -503,9 +503,9 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; // skip if already initialized } TU_ASSERT(rh_init); -#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL + #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* speed_str = 0; - switch (rh_init->speed) { + switch (rh_init->speed) { case TUSB_SPEED_HIGH: speed_str = "High"; break; @@ -651,7 +651,9 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { } #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup + if (event.event_id == DCD_EVENT_SETUP_RECEIVED) { + TU_LOG_USBD("\r\n"); // extra line for setup + } TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); #endif @@ -1047,7 +1049,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { while (p_desc < desc_end) { uint8_t assoc_itf_count = 1; - // Class will always starts with Interface Association (if any) and then Interface descriptor + // Class will always start with Interface Association (if any) and then Interface descriptor if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) { const tusb_desc_interface_assoc_t *desc_iad = (const tusb_desc_interface_assoc_t *)p_desc; @@ -1136,9 +1138,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { // bind all endpoints to found driver tu_edpt_bind_driver(_usbd_dev.ep2drv, desc_itf, drv_len, drv_id); - // next Interface - p_desc += drv_len; - + p_desc += drv_len; // next Interface break; // exit driver find loop } } diff --git a/src/tusb.c b/src/tusb.c index fc1ef7e1a..14b388d04 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -336,8 +336,8 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, // Endpoint Stream Helper for both Host and Device stack //--------------------------------------------------------------------+ -bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, - void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) { +bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, + uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize) { (void) is_tx; #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED == 0 // FIFO is required @@ -362,45 +362,45 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -static bool stream_claim(uint8_t hwid, tu_edpt_stream_t *s) { +static bool stream_claim(tu_edpt_stream_t *s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_claim(hwid, s->ep_addr); - #endif + return usbh_edpt_claim(s->hwid, s->ep_addr); + #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_claim(hwid, s->ep_addr); - #endif + return usbd_edpt_claim(s->hwid, s->ep_addr); + #endif } return false; } -static bool stream_xfer(uint8_t hwid, tu_edpt_stream_t *s, uint16_t count) { +static bool stream_xfer(tu_edpt_stream_t *s, uint16_t count) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); - #endif + return usbh_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count); + #endif } else { #if CFG_TUD_ENABLED if (s->ep_buf == NULL) { - return usbd_edpt_xfer_fifo(hwid, s->ep_addr, &s->ff, count, false); + return usbd_edpt_xfer_fifo(s->hwid, s->ep_addr, &s->ff, count, false); } else { - return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); + return usbd_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); } #endif } return false; } -static bool stream_release(uint8_t hwid, tu_edpt_stream_t *s) { +static bool stream_release(tu_edpt_stream_t *s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_release(hwid, s->ep_addr); - #endif + return usbh_edpt_release(s->hwid, s->ep_addr); + #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_release(hwid, s->ep_addr); - #endif + return usbd_edpt_release(s->hwid, s->ep_addr); + #endif } return false; } @@ -408,18 +408,18 @@ static bool stream_release(uint8_t hwid, tu_edpt_stream_t *s) { //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ -bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (s->mps - 1)))); - TU_VERIFY(stream_claim(hwid, s)); - TU_ASSERT(stream_xfer(hwid, s, 0)); + TU_VERIFY(stream_claim(s)); + TU_ASSERT(stream_xfer(s, 0)); return true; } -uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { const uint16_t ff_count = tu_fifo_count(&s->ff); TU_VERIFY(ff_count > 0, 0); // skip if no data - TU_VERIFY(stream_claim(hwid, s), 0); + TU_VERIFY(stream_claim(s), 0); // Pull data from FIFO -> EP buf uint16_t count; @@ -430,23 +430,23 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { } if (count > 0) { - TU_ASSERT(stream_xfer(hwid, s, count), 0); + TU_ASSERT(stream_xfer(s, count), 0); return count; } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected - stream_release(hwid, s); + stream_release(s); return 0; } } -uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { TU_VERIFY(bufsize > 0); #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode - TU_VERIFY(stream_claim(hwid, s), 0); + TU_VERIFY(stream_claim(s), 0); uint32_t xact_len; if (s->ep_buf != NULL) { // using ep buf @@ -456,7 +456,7 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf // using hwfifo xact_len = bufsize; } - TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0); + TU_ASSERT(stream_xfer(s, (uint16_t)xact_len), 0); return xact_len; } else @@ -467,31 +467,30 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) if ((tu_fifo_count(&s->ff) >= s->mps) || (tu_fifo_depth(&s->ff) < s->mps)) { - tu_edpt_stream_write_xfer(hwid, s); + tu_edpt_stream_write_xfer(s); } return ret; } } -uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t *s) { +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) { #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode bool is_busy = true; if (s->is_host) { #if CFG_TUH_ENABLED - is_busy = usbh_edpt_busy(hwid, s->ep_addr); - #endif + is_busy = usbh_edpt_busy(s->hwid, s->ep_addr); + #endif } else { #if CFG_TUD_ENABLED - is_busy = usbd_edpt_busy(hwid, s->ep_addr); - #endif + is_busy = usbd_edpt_busy(s->hwid, s->ep_addr); + #endif } return is_busy ? 0 : s->ep_bufsize; } else #endif { - (void)hwid; return (uint32_t)tu_fifo_remaining(&s->ff); } } @@ -499,13 +498,13 @@ uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t *s) { //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ -uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) { +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode: RX need ep buffer TU_VERIFY(s->ep_buf != NULL, 0); - TU_VERIFY(stream_claim(hwid, s), 0); - TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0); + TU_VERIFY(stream_claim(s), 0); + TU_ASSERT(stream_xfer(s, s->ep_bufsize), 0); return s->ep_bufsize; } else #endif @@ -517,7 +516,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) { // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming TU_VERIFY(available >= s->mps); - TU_VERIFY(stream_claim(hwid, s), 0); + TU_VERIFY(stream_claim(s), 0); available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed if (available >= s->mps) { @@ -526,19 +525,19 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) { if (s->ep_buf != NULL) { count = tu_min16(count, s->ep_bufsize); } - TU_ASSERT(stream_xfer(hwid, s, count), 0); + TU_ASSERT(stream_xfer(s, count), 0); return count; } else { // Release endpoint since we don't make any transfer - stream_release(hwid, s); + stream_release(s); return 0; } } } -uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize) { const uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize); - tu_edpt_stream_read_xfer(hwid, s); + tu_edpt_stream_read_xfer(s); return num_read; } -- cgit v1.3.1 From ef018e364e886852e2789542b5758da6143af614 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Dec 2025 15:58:10 +0700 Subject: refactor usbh_class_driver_t's open() to return number of driver len instead of bool. help to simplify parsing configuration --- src/class/cdc/cdc_host.c | 250 +++++++++++++++++------------------ src/class/cdc/cdc_host.h | 73 ++++++----- src/class/cdc/cdc_rndis_host.c | 289 ----------------------------------------- src/class/cdc/cdc_rndis_host.h | 63 --------- src/class/hid/hid_host.c | 23 ++-- src/class/hid/hid_host.h | 56 ++++---- src/class/midi/midi_host.c | 41 +++--- src/class/midi/midi_host.h | 62 +++++---- src/class/msc/msc_host.c | 21 ++- src/class/msc/msc_host.h | 48 ++++--- src/common/tusb_common.h | 5 +- src/common/tusb_private.h | 3 - src/host/hub.c | 14 +- src/host/hub.h | 12 +- src/host/usbh.c | 96 +++++--------- src/host/usbh_pvt.h | 17 ++- src/tusb.c | 31 ----- 17 files changed, 349 insertions(+), 755 deletions(-) delete mode 100644 src/class/cdc/cdc_rndis_host.c delete mode 100644 src/class/cdc/cdc_rndis_host.h (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 28abbf098..ff1a8338d 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -41,13 +41,14 @@ #include "serial/pl2303.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged -#ifndef CFG_TUH_CDC_LOG_LEVEL - #define CFG_TUH_CDC_LOG_LEVEL 2 -#endif + #ifndef CFG_TUH_CDC_LOG_LEVEL + #define CFG_TUH_CDC_LOG_LEVEL 2 + #endif -#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__) -#define TU_LOG_CDC(_cdc, _format, ...) TU_LOG_DRV("[:%u:%u] CDCh %s " _format "\r\n", _cdc->daddr, _cdc->bInterfaceNumber, \ - serial_drivers[_cdc->serial_drid].name, ##__VA_ARGS__) + #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__) + #define TU_LOG_CDC(_cdc, _format, ...) \ + TU_LOG_DRV("[:%u:%u] CDCh %s " _format "\r\n", _cdc->daddr, _cdc->bInterfaceNumber, \ + serial_drivers[_cdc->serial_drid].name, ##__VA_ARGS__) //--------------------------------------------------------------------+ // Host CDC Interface @@ -113,63 +114,59 @@ static void cdch_set_line_coding_stage1_baudrate_complete(tuh_xfer_t *xfer); static void cdch_set_line_coding_stage2_data_format_complete(tuh_xfer_t *xfer); //------------- ACM prototypes -------------// -static bool acm_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); -static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); -static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); - -static bool acm_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool acm_set_control_line_state(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static uint16_t acm_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -//------------- FTDI prototypes -------------// -#if CFG_TUH_CDC_FTDI + //------------- FTDI prototypes -------------// + #if CFG_TUH_CDC_FTDI static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; -static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len); -static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); -static void ftdi_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t *xfer); -static bool ftdi_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool ftdi_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool ftdi_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -#endif +static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static void ftdi_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + #endif -//------------- CP210X prototypes -------------// -#if CFG_TUH_CDC_CP210X + //------------- CP210X prototypes -------------// + #if CFG_TUH_CDC_CP210X static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; -static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); -static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); -static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); - -static bool cp210x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool cp210x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool cp210x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -#endif +static uint16_t cp210x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static bool cp210x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + #endif -//------------- CH34x prototypes -------------// -#if CFG_TUH_CDC_CH34X + //------------- CH34x prototypes -------------// + #if CFG_TUH_CDC_CH34X static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; -static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); -static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); -static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); - -static bool ch34x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool ch34x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool ch34x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -#endif +static uint16_t ch34x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static bool ch34x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + #endif -//------------- PL2303 prototypes -------------// -#if CFG_TUH_CDC_PL2303 + //------------- PL2303 prototypes -------------// + #if CFG_TUH_CDC_PL2303 static uint16_t const pl2303_vid_pid_list[][2] = {CFG_TUH_CDC_PL2303_VID_PID_LIST}; static const pl2303_type_data_t pl2303_type_data[PL2303_TYPE_COUNT] = {PL2303_TYPE_DATA}; -static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); -static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); -static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); - -static bool pl2303_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool pl2303_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -#endif +static uint16_t pl2303_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static bool pl2303_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + #endif //------------- Common -------------// enum { @@ -197,11 +194,12 @@ enum { typedef bool (*serial_driver_func_t)(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); typedef struct { - uint16_t const (*vid_pid_list)[2]; - uint16_t const vid_pid_count; - bool (*const open)(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len); - bool (*const process_set_config)(cdch_interface_t * p_cdc, tuh_xfer_t * xfer); - void (*const request_complete)(cdch_interface_t * p_cdc, tuh_xfer_t * xfer); // internal request complete handler to update line state + const uint16_t (*vid_pid_list)[2]; + const uint16_t vid_pid_count; + uint16_t (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); + bool (*const process_set_config)(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); + // internal request complete handler to update line state + void (*const request_complete)(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); serial_driver_func_t set_control_line_state, set_baudrate, set_data_format, set_line_coding; @@ -731,11 +729,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t //--------------------------------------------------------------------+ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t const *desc_ep) { for (size_t i = 0; i < 2; i++) { - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && - TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); - tu_edpt_stream_t *stream = - (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; + const uint8_t ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress); + tu_edpt_stream_t *stream = (ep_dir == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep); tu_edpt_stream_clear(stream); @@ -745,8 +742,8 @@ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t co return true; } -bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { - (void) rhport; +uint16_t cdch_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { + (void)rhport; // For CDC: only support ACM subclass // Note: Protocol 0xFF can be RNDIS device if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && @@ -755,15 +752,15 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d } 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)); + TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid), 0); - for (size_t dr = 1; dr < SERIAL_DRIVER_COUNT; dr++) { - const cdch_serial_driver_t *driver = &serial_drivers[dr]; + for (size_t drv = 1; drv < SERIAL_DRIVER_COUNT; drv++) { + const cdch_serial_driver_t *driver = &serial_drivers[drv]; for (size_t i = 0; i < driver->vid_pid_count; i++) { if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) { - const bool ret = driver->open(daddr, itf_desc, max_len); + const uint16_t drv_len = driver->open(daddr, itf_desc, max_len); TU_LOG_DRV("[:%u:%u] CDCh %s open %s\r\n", daddr, itf_desc->bInterfaceNumber, driver->name, ret ? "OK" : "FAILED"); - return ret; + return drv_len; } } } @@ -771,7 +768,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d // not supported class } - return false; + return 0; } bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { @@ -1012,19 +1009,19 @@ enum { CONFIG_ACM_COMPLETE = 0 }; -static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { - uint8_t const *p_desc_end = ((uint8_t const *) itf_desc) + max_len; +static uint16_t acm_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { + const uint8_t *p_desc = (const uint8_t *)itf_desc; + const uint8_t *desc_end = p_desc + max_len; cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); - TU_VERIFY(p_cdc); - + TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_ACM; //------------- Control Interface -------------// - uint8_t const *p_desc = tu_desc_next(itf_desc); + p_desc = tu_desc_next(p_desc); // Communication Functional Descriptors - while ((p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) { + while ((p_desc < desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) { if (CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc)) { // save ACM bmCapabilities p_cdc->acm.capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; @@ -1035,26 +1032,27 @@ static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint1 // Open notification endpoint of control interface if any if (itf_desc->bNumEndpoints == 1) { - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)); - tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; - - TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// - if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass)) { - // next to endpoint descriptor - p_desc = tu_desc_next(p_desc); - - // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const *) p_desc)); + if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) { + const tusb_desc_interface_t *data_itf = (const tusb_desc_interface_t *)p_desc; + if (data_itf->bInterfaceClass == TUSB_CLASS_CDC_DATA) { + p_desc = tu_desc_next(p_desc); // next to endpoint descriptor + + // data endpoints expected to be in pairs + TU_ASSERT(open_ep_stream_pair(p_cdc, (const tusb_desc_endpoint_t *)p_desc), 0); + p_desc += data_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t); + } } - return true; + return (uint16_t)((uintptr_t)p_desc - (uintptr_t)itf_desc); } static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { @@ -1187,28 +1185,29 @@ enum { CONFIG_FTDI_COMPLETE }; -static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { +static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // FTDI Interface includes 1 vendor interface + 2 bulk endpoints TU_VERIFY(itf_desc->bInterfaceSubClass == 0xff && itf_desc->bInterfaceProtocol == 0xff && - itf_desc->bNumEndpoints == 2); - TU_VERIFY(sizeof(tusb_desc_interface_t) + 2 * sizeof(tusb_desc_endpoint_t) <= max_len); + itf_desc->bNumEndpoints == 2, + 0); + const uint16_t drv_len = sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t); + TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); - TU_VERIFY(p_cdc); + TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_FTDI; // endpoint pair - tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc); - /* - * NOTE: Some customers have programmed FT232R/FT245R devices - * with an endpoint size of 0 - not good. - */ - TU_ASSERT(desc_ep->wMaxPacketSize != 0); + /* NOTE: Some users have programmed FT232R/FT245R devices + * with an endpoint size of 0 !!! */ + TU_ASSERT(desc_ep->wMaxPacketSize != 0, 0); - // data endpoints expected to be in pairs - return open_ep_stream_pair(p_cdc, desc_ep); + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0); + + return drv_len; } static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { @@ -1579,21 +1578,22 @@ enum { CONFIG_CP210X_COMPLETE }; -static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { +static uint16_t cp210x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // CP210x Interface includes 1 vendor interface + 2 bulk endpoints - TU_VERIFY(itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0 && itf_desc->bNumEndpoints == 2); - TU_VERIFY(sizeof(tusb_desc_interface_t) + 2 * sizeof(tusb_desc_endpoint_t) <= max_len); + TU_VERIFY(itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0 && itf_desc->bNumEndpoints == 2, 0); + const uint16_t drv_len = sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t); + TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); - TU_VERIFY(p_cdc); + TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_CP210X; - // endpoint pair - tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); - // data endpoints expected to be in pairs - return open_ep_stream_pair(p_cdc, desc_ep); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc); + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); + + return drv_len; } static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { @@ -1753,29 +1753,29 @@ enum { CONFIG_CH34X_COMPLETE }; -static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { +static uint16_t ch34x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints - TU_VERIFY(itf_desc->bNumEndpoints == 3); - TU_VERIFY(sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); + TU_VERIFY(itf_desc->bNumEndpoints == 3, 0); + const uint16_t drv_len = sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t); + TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t * p_cdc = make_new_itf(daddr, itf_desc); - TU_VERIFY(p_cdc); + TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_CH34X; - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc); // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); - desc_ep += 2; + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0); + desc_ep = (const tusb_desc_endpoint_t *)((uintptr_t)desc_ep + 2 * sizeof(tusb_desc_endpoint_t)); // Interrupt endpoint: not used for now - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && - TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); - TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; - return true; + return drv_len; } static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { @@ -2089,13 +2089,14 @@ enum { CONFIG_PL2303_COMPLETE }; -static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { +static uint16_t pl2303_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // PL2303 Interface includes 1 vendor interface + 1 interrupt endpoints + 2 bulk - TU_VERIFY(itf_desc->bNumEndpoints == 3); - TU_VERIFY(sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); + TU_VERIFY(itf_desc->bNumEndpoints == 3, 0); + const uint16_t drv_len = sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t); + TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); - TU_VERIFY(p_cdc); + TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_PL2303; p_cdc->pl2303.quirks = 0; @@ -2104,16 +2105,15 @@ static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, ui tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); // Interrupt endpoint: not used for now - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && - TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); - TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; desc_ep += 1; // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0); - return true; + return drv_len; } static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index e8637beac..57919c7ff 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -30,7 +30,7 @@ #include "cdc.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ @@ -39,22 +39,22 @@ // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE -#define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif // RX Endpoint size #ifndef CFG_TUH_CDC_RX_EPSIZE -#define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS #endif // TX FIFO size #ifndef CFG_TUH_CDC_TX_BUFSIZE -#define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif // TX Endpoint size #ifndef CFG_TUH_CDC_TX_EPSIZE -#define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS #endif //--------------------------------------------------------------------+ @@ -67,7 +67,7 @@ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num); // Get Interface information // return true if index is correct and interface is currently mounted -bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info); +bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t *info); // Check if an interface is mounted bool tuh_cdc_mounted(uint8_t idx); @@ -75,7 +75,7 @@ bool tuh_cdc_mounted(uint8_t idx); // Get local (cached) line state // This function should return correct values if tuh_cdc_set_control_line_state() / tuh_cdc_get_control_line_state() // are invoked previously or CFG_TUH_CDC_LINE_STATE_ON_ENUM is defined. -bool tuh_cdc_get_control_line_state_local(uint8_t idx, uint16_t* line_state); +bool tuh_cdc_get_control_line_state_local(uint8_t idx, uint16_t *line_state); // Get current DTR status TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_get_dtr(uint8_t idx) { @@ -100,7 +100,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) { // This function should return correct values if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() // are invoked previously or CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined. // NOTE: This function does not make any USB transfer request to device. -bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t* line_coding); +bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t *line_coding); #define tuh_cdc_get_local_line_coding tuh_cdc_get_line_coding_local // backward compatibility @@ -112,7 +112,7 @@ bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t* line_coding); uint32_t tuh_cdc_write_available(uint8_t idx); // Write to cdc interface -uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize); +uint32_t tuh_cdc_write(uint8_t idx, const void *buffer, uint32_t bufsize); // Force sending data if possible, return number of forced bytes uint32_t tuh_cdc_write_flush(uint8_t idx); @@ -128,13 +128,13 @@ bool tuh_cdc_write_clear(uint8_t idx); uint32_t tuh_cdc_read_available(uint8_t idx); // Read from cdc interface -uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize); +uint32_t tuh_cdc_read(uint8_t idx, void *buffer, uint32_t bufsize); // Get a byte from RX FIFO without removing it -bool tuh_cdc_peek(uint8_t idx, uint8_t* ch); +bool tuh_cdc_peek(uint8_t idx, uint8_t *ch); // Clear the received FIFO -bool tuh_cdc_read_clear (uint8_t idx); +bool tuh_cdc_read_clear(uint8_t idx); //--------------------------------------------------------------------+ // Control Request API @@ -149,16 +149,18 @@ bool tuh_cdc_read_clear (uint8_t idx); bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Set DTR -TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_dtr(uint8_t idx, bool dtr_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - cdc_line_control_state_t line_state = { .dtr = dtr_state }; - line_state.rts = tuh_cdc_get_rts(idx); +TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_dtr(uint8_t idx, bool dtr_state, tuh_xfer_cb_t complete_cb, + uintptr_t user_data) { + cdc_line_control_state_t line_state = {.dtr = dtr_state}; + line_state.rts = tuh_cdc_get_rts(idx); return tuh_cdc_set_control_line_state(idx, line_state.value, complete_cb, user_data); } // Request to Set RTS -TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - cdc_line_control_state_t line_state = { .rts = rts_state }; - line_state.dtr = tuh_cdc_get_dtr(idx); +TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_state, tuh_xfer_cb_t complete_cb, + uintptr_t user_data) { + cdc_line_control_state_t line_state = {.rts = rts_state}; + line_state.dtr = tuh_cdc_get_dtr(idx); return tuh_cdc_set_control_line_state(idx, line_state.value, complete_cb, user_data); } @@ -166,11 +168,13 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_s bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to set data format -bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Set Line Coding = baudrate + data format // Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet -bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +bool tuh_cdc_set_line_coding(uint8_t idx, const cdc_line_coding_t *line_coding, tuh_xfer_cb_t complete_cb, + uintptr_t user_data); // Request to Get Line Coding (ACM only) // Should only use if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() never got invoked and @@ -179,11 +183,13 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // Connect by set both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data); + return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, + user_data); } // Disconnect by clear both DTR, RTS -TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, + uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } @@ -192,7 +198,8 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfe // Each Function will make a USB control transfer request to/from device the function will block until request is // complete. The function will return the transfer request result //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_control_line_state_sync(uint8_t idx, uint16_t line_state) { +TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_control_line_state_sync(uint8_t idx, + uint16_t line_state) { TU_API_SYNC(tuh_cdc_set_control_line_state, idx, line_state); } @@ -208,11 +215,13 @@ TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_baudrate_sync TU_API_SYNC(tuh_cdc_set_baudrate, idx, baudrate); } -TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_data_format_sync(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { +TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_data_format_sync(uint8_t idx, uint8_t stop_bits, + uint8_t parity, uint8_t data_bits) { TU_API_SYNC(tuh_cdc_set_data_format, idx, stop_bits, parity, data_bits); } -TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_line_coding_sync(uint8_t idx, cdc_line_coding_t const* line_coding) { +TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t +tuh_cdc_set_line_coding_sync(uint8_t idx, const cdc_line_coding_t *line_coding) { TU_API_SYNC(tuh_cdc_set_line_coding, idx, line_coding); } @@ -244,15 +253,15 @@ extern void tuh_cdc_tx_complete_cb(uint8_t idx); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -bool cdch_init (void); -bool cdch_deinit (void); -bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); -bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); -bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void cdch_close (uint8_t dev_addr); +bool cdch_init(void); +bool cdch_deinit(void); +uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num); +bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void cdch_close(uint8_t dev_addr); #ifdef __cplusplus - } +} #endif #endif /* TUSB_CDC_HOST_H_ */ diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c deleted file mode 100644 index e975ea440..000000000 --- a/src/class/cdc/cdc_rndis_host.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if (CFG_TUH_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS) - -//--------------------------------------------------------------------+ -// INCLUDE -//--------------------------------------------------------------------+ -#include "common/tusb_common.h" -#include "cdc_host.h" -#include "cdc_rndis_host.h" - -#if 0 // TODO remove subtask related macros later -// Sub Task -#define OSAL_SUBTASK_BEGIN -#define OSAL_SUBTASK_END return TUSB_ERROR_NONE; - -#define STASK_RETURN(_error) return _error; -#define STASK_INVOKE(_subtask, _status) (_status) = _subtask -#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) -#endif - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ -#define RNDIS_MSG_PAYLOAD_MAX (1024*4) - -CFG_TUH_MEM_SECTION static uint8_t msg_notification[CFG_TUH_DEVICE_MAX][8]; -CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static uint8_t msg_payload[RNDIS_MSG_PAYLOAD_MAX]; - -static rndish_data_t rndish_data[CFG_TUH_DEVICE_MAX]; - -// TODO Microsoft requires message length for any get command must be at least 4096 bytes - -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ -static tusb_error_t rndis_body_subtask(void); -static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_data_t *p_cdc, - uint8_t * p_mess, uint32_t mess_length, - uint8_t *p_response ); - -//--------------------------------------------------------------------+ -// APPLICATION API -//--------------------------------------------------------------------+ -tusb_error_t tusbh_cdc_rndis_get_mac_addr(uint8_t dev_addr, uint8_t mac_address[6]) -{ - TU_ASSERT( tusbh_cdc_rndis_is_mounted(dev_addr), TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED); - TU_VERIFY( mac_address, TUSB_ERROR_INVALID_PARA); - - memcpy(mac_address, rndish_data[dev_addr-1].mac_address, 6); - - return TUSB_ERROR_NONE; -} - -//--------------------------------------------------------------------+ -// IMPLEMENTATION -//--------------------------------------------------------------------+ - -// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper -// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with -// forever loop cannot have any return at all. -OSAL_TASK_FUNCTION(cdch_rndis_task) (void* param;) -{ - OSAL_TASK_BEGIN - rndis_body_subtask(); - OSAL_TASK_END -} - -static tusb_error_t rndis_body_subtask(void) -{ - static uint8_t relative_addr; - - OSAL_SUBTASK_BEGIN - - for (relative_addr = 0; relative_addr < CFG_TUH_DEVICE_MAX; relative_addr++) - { - - } - - tusb_time_delay_ms_api(100); - - OSAL_SUBTASK_END -} - -//--------------------------------------------------------------------+ -// RNDIS-CDC Driver API -//--------------------------------------------------------------------+ -void rndish_init(void) -{ - tu_memclr(rndish_data, sizeof(rndish_data_t)*CFG_TUH_DEVICE_MAX); - - //------------- Task creation -------------// - - //------------- semaphore creation for notification pipe -------------// - for(uint8_t i=0; itype == RNDIS_MSG_INITIALIZE_CMPLT && p_init_cmpt->status == RNDIS_STATUS_SUCCESS && - p_init_cmpt->max_packet_per_xfer == 1 && p_init_cmpt->max_xfer_size <= RNDIS_MSG_PAYLOAD_MAX); - rndish_data[dev_addr-1].max_xfer_size = p_init_cmpt->max_xfer_size; - - //------------- Message Query 802.3 Permanent Address -------------// - memcpy(msg_payload, &msg_query_permanent_addr, sizeof(rndis_msg_query_t)); - tu_memclr(msg_payload + sizeof(rndis_msg_query_t), 6); // 6 bytes for MAC address - - STASK_INVOKE( - send_message_get_response_subtask( dev_addr, p_cdc, - msg_payload, sizeof(rndis_msg_query_t) + 6, - msg_payload), - error - ); - if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); - - rndis_msg_query_cmplt_t * const p_query_cmpt = (rndis_msg_query_cmplt_t *) msg_payload; - STASK_ASSERT(p_query_cmpt->type == RNDIS_MSG_QUERY_CMPLT && p_query_cmpt->status == RNDIS_STATUS_SUCCESS); - memcpy(rndish_data[dev_addr-1].mac_address, msg_payload + 8 + p_query_cmpt->buffer_offset, 6); - - //------------- Set OID_GEN_CURRENT_PACKET_FILTER to (DIRECTED | MULTICAST | BROADCAST) -------------// - memcpy(msg_payload, &msg_set_packet_filter, sizeof(rndis_msg_set_t)); - tu_memclr(msg_payload + sizeof(rndis_msg_set_t), 4); // 4 bytes for filter flags - ((rndis_msg_set_t*) msg_payload)->oid_buffer[0] = (RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_MULTICAST | RNDIS_PACKET_TYPE_BROADCAST); - - STASK_INVOKE( - send_message_get_response_subtask( dev_addr, p_cdc, - msg_payload, sizeof(rndis_msg_set_t) + 4, - msg_payload), - error - ); - if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); - - rndis_msg_set_cmplt_t * const p_set_cmpt = (rndis_msg_set_cmplt_t *) msg_payload; - STASK_ASSERT(p_set_cmpt->type == RNDIS_MSG_SET_CMPLT && p_set_cmpt->status == RNDIS_STATUS_SUCCESS); - - tusbh_cdc_rndis_mounted_cb(dev_addr); - - OSAL_SUBTASK_END -} - -void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes) -{ - if ( pipehandle_is_equal(pipe_hdl, p_cdc->pipe_notification) ) - { - osal_semaphore_post( rndish_data[pipe_hdl.dev_addr-1].sem_notification_hdl ); - } -} - -//--------------------------------------------------------------------+ -// INTERNAL & HELPER -//--------------------------------------------------------------------+ -static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_data_t *p_cdc, - uint8_t * p_mess, uint32_t mess_length, - uint8_t *p_response) -{ - tusb_error_t error; - - OSAL_SUBTASK_BEGIN - - //------------- Send RNDIS Control Message -------------// - STASK_INVOKE( - usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE), - CDC_REQUEST_SEND_ENCAPSULATED_COMMAND, 0, p_cdc->interface_number, - mess_length, p_mess), - error - ); - if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); - - //------------- waiting for Response Available notification -------------// - (void) usbh_edpt_xfer(p_cdc->pipe_notification, msg_notification[dev_addr-1], 8); - osal_semaphore_wait(rndish_data[dev_addr-1].sem_notification_hdl, OSAL_TIMEOUT_NORMAL, &error); - if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); - STASK_ASSERT(msg_notification[dev_addr-1][0] == 1); - - //------------- Get RNDIS Message Initialize Complete -------------// - STASK_INVOKE( - usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE), - CDC_REQUEST_GET_ENCAPSULATED_RESPONSE, 0, p_cdc->interface_number, - RNDIS_MSG_PAYLOAD_MAX, p_response), - error - ); - if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error); - - OSAL_SUBTASK_END -} - -//static tusb_error_t send_process_msg_initialize_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) -//{ -// tusb_error_t error; -// -// OSAL_SUBTASK_BEGIN -// -// *((rndis_msg_initialize_t*) msg_payload) = (rndis_msg_initialize_t) -// { -// .type = RNDIS_MSG_INITIALIZE, -// .length = sizeof(rndis_msg_initialize_t), -// .request_id = 1, // TODO should use some magic number -// .major_version = 1, -// .minor_version = 0, -// .max_xfer_size = 0x4000 // TODO mimic windows -// }; -// -// -// -// OSAL_SUBTASK_END -//} -#endif diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h deleted file mode 100644 index e70d27f79..000000000 --- a/src/class/cdc/cdc_rndis_host.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/** \ingroup CDC_RNDIS - * \defgroup CDC_RNSID_Host Host - * @{ */ - -#ifndef TUSB_CDC_RNDIS_HOST_H_ -#define TUSB_CDC_RNDIS_HOST_H_ - -#include "common/tusb_common.h" -#include "host/usbh.h" -#include "cdc_rndis.h" - -#ifdef __cplusplus - extern "C" { -#endif - -//--------------------------------------------------------------------+ -// INTERNAL RNDIS-CDC Driver API -//--------------------------------------------------------------------+ -typedef struct { - OSAL_SEM_DEF(semaphore_notification); - osal_semaphore_handle_t sem_notification_hdl; // used to wait on notification pipe - uint32_t max_xfer_size; // got from device's msg initialize complete - uint8_t mac_address[6]; -}rndish_data_t; - -void rndish_init(void); -bool rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc); -void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes); -void rndish_close(uint8_t dev_addr); - -#ifdef __cplusplus - } -#endif - -#endif /* TUSB_CDC_RNDIS_HOST_H_ */ - -/** @} */ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index fe9a90d33..98f9bf80b 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -512,19 +512,18 @@ void hidh_close(uint8_t daddr) { //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ - -bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) { +uint16_t hidh_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { (void) rhport; (void) max_len; - TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); + TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); TU_LOG_DRV("[%u] HID opening Interface %u\r\n", daddr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints - uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + - desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); - TU_ASSERT(max_len >= drv_len); - uint8_t const* p_desc = (uint8_t const*) desc_itf; + const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + TU_ASSERT(drv_len <= max_len, 0); + const uint8_t *p_desc = (const uint8_t *)desc_itf; // HID descriptor: mostly right after interface descriptor, in some rare case it might be after endpoint descriptors p_desc = tu_desc_next(p_desc); @@ -536,20 +535,20 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_ } else { // HID after endpoint desc_hid = (const tusb_hid_descriptor_hid_t *)(p_desc + sizeof(tusb_desc_endpoint_t) * desc_itf->bNumEndpoints); - TU_ASSERT(tu_desc_type(desc_hid) == HID_DESC_TYPE_HID); + TU_ASSERT(tu_desc_type(desc_hid) == HID_DESC_TYPE_HID, 0); } // Allocate new interface hidh_interface_t *p_hid = find_new_itf(); - TU_ASSERT(p_hid); // not enough interface, try to increase CFG_TUH_HID + TU_ASSERT(p_hid, 0); // not enough interface, try to increase CFG_TUH_HID p_hid->daddr = daddr; p_hid->itf_num = desc_itf->bInterfaceNumber; // Endpoint Descriptors for (uint8_t i = 0; i < desc_itf->bNumEndpoints; i++) { const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); - TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType, 0); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_hid->ep_in = desc_ep->bEndpointAddress; @@ -573,7 +572,7 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_ p_hid->itf_protocol = desc_itf->bInterfaceProtocol; } - return true; + return drv_len; } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 87f0e7dc9..d7a415485 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -39,22 +39,22 @@ extern "C" { // TODO Highspeed interrupt can be up to 512 bytes #ifndef CFG_TUH_HID_EPIN_BUFSIZE -#define CFG_TUH_HID_EPIN_BUFSIZE 64 + #define CFG_TUH_HID_EPIN_BUFSIZE 64 #endif #ifndef CFG_TUH_HID_EPOUT_BUFSIZE -#define CFG_TUH_HID_EPOUT_BUFSIZE 64 + #define CFG_TUH_HID_EPOUT_BUFSIZE 64 #endif typedef struct { - uint8_t report_id; - uint8_t usage; + uint8_t report_id; + uint8_t usage; uint16_t usage_page; // TODO still use the endpoint size for now -// uint8_t in_len; // length of IN report -// uint8_t out_len; // length of OUT report + // uint8_t in_len; // length of IN report + // uint8_t out_len; // length of OUT report } tuh_hid_report_info_t; //--------------------------------------------------------------------+ @@ -68,10 +68,10 @@ uint8_t tuh_hid_itf_get_count(uint8_t dev_addr); uint8_t tuh_hid_itf_get_total_count(void); // backward compatible rename -#define tuh_hid_instance_count tuh_hid_itf_get_count +#define tuh_hid_instance_count tuh_hid_itf_get_count // Get Interface information -bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* itf_info); +bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t *itf_info); // Get Interface index from device address + interface number // return TUSB_INDEX_INVALID_8 (0xFF) if not found @@ -85,8 +85,8 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t idx); // Parse report descriptor into array of report_info struct and return number of reports. // For complicated report, application should write its own parser. -TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, - uint8_t const* desc_report, uint16_t desc_len); +TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t *reports_info_arr, uint8_t arr_count, + const uint8_t *desc_report, uint16_t desc_len); //--------------------------------------------------------------------+ // Control Endpoint API @@ -107,12 +107,13 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol); // Get Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) -bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); +bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report, + uint16_t len); // Set Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) -bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, - void* report, uint16_t len); +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report, + uint16_t len); //--------------------------------------------------------------------+ // Interrupt Endpoint API @@ -133,8 +134,9 @@ bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx); bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx); // Send report using interrupt endpoint -// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is sent. -bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len); +// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is +// sent. +bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const void *report, uint16_t len); //--------------------------------------------------------------------+ // Callbacks (Weak is optional) @@ -145,25 +147,27 @@ bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 -void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report_desc, uint16_t desc_len); +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report_desc, uint16_t desc_len); // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t idx); // Invoked when received report from device via interrupt endpoint // Note: if there is report ID (composite), it is 1st byte of report -void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len); +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report, uint16_t len); // Invoked when sent report to device successfully via interrupt endpoint -void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len); +void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report, uint16_t len); // Invoked when Get Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response -void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); +void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, + uint16_t len); // Invoked when Sent Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response -void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); +void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, + uint16_t len); // Invoked when Set Protocol request is complete void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t protocol); @@ -171,12 +175,12 @@ void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t pro //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -bool hidh_init(void); -bool hidh_deinit(void); -bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); -bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); -bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -void hidh_close(uint8_t dev_addr); +bool hidh_init(void); +bool hidh_deinit(void); +uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len); +bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); +bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void hidh_close(uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index b4f5ac445..5548a0ba8 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -192,15 +192,16 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ -bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { +uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { (void) rhport; - TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass); - const uint8_t *p_end = ((const uint8_t *) desc_itf) + max_len; - const uint8_t *p_desc = (const uint8_t *) desc_itf; + TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0); + const uint8_t *desc_start = (const uint8_t *)desc_itf; + const uint8_t *p_desc = desc_start; + const uint8_t *desc_end = desc_start + max_len; const uint8_t idx = find_new_midi_index(); - TU_VERIFY(idx < CFG_TUH_MIDI); + TU_VERIFY(idx < CFG_TUH_MIDI, 0); midih_interface_t *p_midi = &_midi_host[idx]; p_midi->itf_count = 0; @@ -217,29 +218,30 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d // driver after parsing the audio control interface and then resume parsing // the streaming audio interface. if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) { - TU_VERIFY(max_len > 2*sizeof(tusb_desc_interface_t) + sizeof(midi10_desc_cs_ac_interface_t)); - + TU_VERIFY(max_len > 2 * sizeof(tusb_desc_interface_t) + sizeof(midi10_desc_cs_ac_interface_t), 0); p_desc = tu_desc_next(p_desc); TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && - tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_HEADER); + tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_HEADER, + 0); desc_cb.desc_audio_control = desc_itf; p_desc = tu_desc_next(p_desc); desc_itf = (const tusb_desc_interface_t *)p_desc; p_midi->itf_count = 1; // skip non-interface and non-midi streaming descriptors - while (tu_desc_in_bounds(p_desc, p_end) && - (desc_itf->bDescriptorType != TUSB_DESC_INTERFACE || (desc_itf->bInterfaceClass == TUSB_CLASS_AUDIO && desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING))) { + while (tu_desc_in_bounds(p_desc, desc_end) && (desc_itf->bDescriptorType != TUSB_DESC_INTERFACE || + (desc_itf->bInterfaceClass == TUSB_CLASS_AUDIO && + desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING))) { if (desc_itf->bDescriptorType == TUSB_DESC_INTERFACE && desc_itf->bAlternateSetting == 0) { p_midi->itf_count++; } p_desc = tu_desc_next(p_desc); - desc_itf = (tusb_desc_interface_t const *)p_desc; + desc_itf = (const tusb_desc_interface_t *)p_desc; } - TU_VERIFY(p_desc < p_end); // TODO: If MIDI interface comes after Audio Streaming, then max_len did not include the MIDI interface descriptor - TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass); + TU_VERIFY(p_desc < desc_end, 0); + TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0); } - TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass); + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, 0); TU_LOG_DRV("MIDI opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber; @@ -250,7 +252,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d p_desc = tu_desc_next(p_desc); // next to CS Header bool found_new_interface = false; - while (tu_desc_in_bounds(p_desc, p_end) && !found_new_interface) { + while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) { switch (tu_desc_type(p_desc)) { case TUSB_DESC_INTERFACE: found_new_interface = true; @@ -287,8 +289,9 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d case TUSB_DESC_ENDPOINT: { const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + p_desc = tu_desc_next(p_desc); // next to CS endpoint - TU_VERIFY(p_desc < p_end && tu_desc_next(p_desc) <= p_end); + TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0); const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress); @@ -302,7 +305,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d desc_cb.desc_epin = p_ep; ep_stream = &p_midi->ep_stream.rx; } - TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); + TU_ASSERT(tuh_edpt_open(dev_addr, p_ep), 0); tu_edpt_stream_open(ep_stream, dev_addr, p_ep); tu_edpt_stream_clear(ep_stream); @@ -313,12 +316,12 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d } p_desc = tu_desc_next(p_desc); } - desc_cb.desc_midi_total_len = (uint16_t) ((uintptr_t)p_desc - (uintptr_t) desc_itf); + desc_cb.desc_midi_total_len = (uint16_t)((uintptr_t)p_desc - (uintptr_t)desc_start); p_midi->daddr = dev_addr; tuh_midi_descriptor_cb(idx, &desc_cb); - return true; + return desc_cb.desc_midi_total_len; } bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) { diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 06554a03d..8a8dccab4 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -31,45 +31,45 @@ #include "midi.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE -#define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE -#define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE -#define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS #endif // Enable the MIDI stream read/write API. Some library can work with raw USB MIDI packet // Disable this can save driver footprint. #ifndef CFG_TUH_MIDI_STREAM_API -#define CFG_TUH_MIDI_STREAM_API 1 + #define CFG_TUH_MIDI_STREAM_API 1 #endif //--------------------------------------------------------------------+ // Application Types //--------------------------------------------------------------------+ typedef struct { - const tusb_desc_interface_t* desc_audio_control; - const tusb_desc_interface_t* desc_midi; // start of whole midi interface descriptor - uint16_t desc_midi_total_len; + const tusb_desc_interface_t *desc_audio_control; + const tusb_desc_interface_t *desc_midi; // start of whole midi interface descriptor + uint16_t desc_midi_total_len; - const uint8_t* desc_header; - const uint8_t* desc_element; - const tusb_desc_endpoint_t* desc_epin; // endpoint IN descriptor, CS_ENDPOINT is right after - const tusb_desc_endpoint_t* desc_epout; // endpoint OUT descriptor, CS_ENDPOINT is right after + const uint8_t *desc_header; + const uint8_t *desc_element; + const tusb_desc_endpoint_t *desc_epin; // endpoint IN descriptor, CS_ENDPOINT is right after + const tusb_desc_endpoint_t *desc_epout; // endpoint OUT descriptor, CS_ENDPOINT is right after - uint8_t jack_num; - const uint8_t* desc_jack[32]; // list of jack descriptors (embedded + external) + uint8_t jack_num; + const uint8_t *desc_jack[32]; // list of jack descriptors (embedded + external) } tuh_midi_descriptor_cb_t; typedef struct { @@ -92,7 +92,7 @@ uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num); // Get Interface information // return true if index is correct and interface is currently mounted -bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info); +bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t *info); // return the number of virtual midi cables on the device's IN endpoint uint8_t tuh_midi_get_rx_cable_count(uint8_t idx); @@ -115,24 +115,22 @@ uint32_t tuh_midi_write_flush(uint8_t idx); // Read all available MIDI packets from the connected device // Return number of bytes read (always multiple of 4) -uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t* buffer, uint32_t bufsize); +uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t *buffer, uint32_t bufsize); // Read a raw MIDI packet from the connected device // Return true if a packet was returned -TU_ATTR_ALWAYS_INLINE static inline -bool tuh_midi_packet_read (uint8_t idx, uint8_t packet[4]) { - return 4 == tuh_midi_packet_read_n(idx, packet, 4); +TU_ATTR_ALWAYS_INLINE static inline bool tuh_midi_packet_read(uint8_t idx, uint8_t packet[4]) { + return 4 == tuh_midi_packet_read_n(idx, packet, 4); } // Write all 4-byte packets, data is locally buffered and only transferred when buffered bytes // reach the endpoint packet size or tuh_midi_write_flush() is called -uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bufsize); +uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t *buffer, uint32_t bufsize); // Write a 4-bytes packet to the device. // Returns true if the packet was successfully queued. -TU_ATTR_ALWAYS_INLINE static inline -bool tuh_midi_packet_write (uint8_t idx, uint8_t const packet[4]) { - return 4 == tuh_midi_packet_write_n(idx, packet, 4); +TU_ATTR_ALWAYS_INLINE static inline bool tuh_midi_packet_write(uint8_t idx, const uint8_t packet[4]) { + return 4 == tuh_midi_packet_write_n(idx, packet, 4); } //--------------------------------------------------------------------+ @@ -143,7 +141,7 @@ bool tuh_midi_packet_write (uint8_t idx, uint8_t const packet[4]) { // Queue a message to the device using stream API. data is locally buffered and only transferred when buffered bytes // reach the endpoint packet size or tuh_midi_write_flush() is called // Returns number of bytes was successfully queued. -uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *p_buffer, uint32_t bufsize); +uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, const uint8_t *p_buffer, uint32_t bufsize); // Get the MIDI stream from the device. Set the value pointed // to by p_cable_num to the MIDI cable number intended to receive it. @@ -162,10 +160,10 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff // Invoked when MIDI interface is detected in enumeration. Application can copy/parse descriptor if needed. // Note: may be fired before tuh_midi_mount_cb(), therefore midi interface is not mounted/ready. -void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t * desc_cb_data); +void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t *desc_cb_data); // Invoked when device with MIDI interface is mounted. -void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data); +void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t *mount_cb_data); // Invoked when device with MIDI interface is un-mounted void tuh_midi_umount_cb(uint8_t idx); @@ -179,12 +177,12 @@ void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes); //--------------------------------------------------------------------+ // 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 daddr); +bool midih_init(void); +bool midih_deinit(void); +uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *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 daddr); #ifdef __cplusplus } diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index daff345c5..6a36c2820 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -379,22 +379,21 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); -bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) { +uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { (void) rhport; - TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && - MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); + TU_VERIFY(MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol, 0); // msc driver length is fixed - uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + - desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); - TU_ASSERT(drv_len <= max_len); + const uint16_t drv_len = + (uint16_t)(sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + TU_ASSERT(drv_len <= max_len, 0); - msch_interface_t* p_msc = get_itf(dev_addr); - tusb_desc_endpoint_t const* ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(desc_itf); + msch_interface_t *p_msc = get_itf(dev_addr); + const tusb_desc_endpoint_t *ep_desc = (const tusb_desc_endpoint_t *)tu_desc_next(desc_itf); for (uint32_t i = 0; i < 2; i++) { - TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); - TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc)); + TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer, 0); + TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc), 0); if (TUSB_DIR_IN == tu_edpt_dir(ep_desc->bEndpointAddress)) { p_msc->ep_in = ep_desc->bEndpointAddress; @@ -407,7 +406,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* de p_msc->itf_num = desc_itf->bInterfaceNumber; - return true; + return drv_len; } bool msch_set_config(uint8_t daddr, uint8_t itf_num) { diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index b5fd55547..5dc7c0b94 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -30,7 +30,7 @@ #include "msc.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ @@ -38,17 +38,17 @@ //--------------------------------------------------------------------+ #ifndef CFG_TUH_MSC_MAXLUN -#define CFG_TUH_MSC_MAXLUN 4 + #define CFG_TUH_MSC_MAXLUN 4 #endif typedef struct { - msc_cbw_t const* cbw; // SCSI command - msc_csw_t const* csw; // SCSI status - void* scsi_data; // SCSI Data - uintptr_t user_arg; // user argument -}tuh_msc_complete_data_t; + const msc_cbw_t *cbw; // SCSI command + const msc_csw_t *csw; // SCSI status + void *scsi_data; // SCSI Data + uintptr_t user_arg; // user argument +} tuh_msc_complete_data_t; -typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); +typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, const tuh_msc_complete_data_t *cb_data); //--------------------------------------------------------------------+ // Application API @@ -74,12 +74,14 @@ uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun); // Complete callback is invoked when SCSI op is complete. // return true if success, false if there is already pending operation. // NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled -bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_scsi_command(uint8_t daddr, const msc_cbw_t *cbw, void *data, tuh_msc_complete_cb_t complete_cb, + uintptr_t arg); // Perform SCSI Inquiry command // Complete callback is invoked when SCSI op is complete. // NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled -bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t *response, tuh_msc_complete_cb_t complete_cb, + uintptr_t arg); // Perform SCSI Test Unit Ready command // Complete callback is invoked when SCSI op is complete. @@ -88,23 +90,27 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_ // Perform SCSI Request Sense 10 command // Complete callback is invoked when SCSI op is complete. // NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled -bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, + uintptr_t arg); // Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer // Complete callback is invoked when SCSI op is complete. // NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled -bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void *buffer, uint32_t lba, uint16_t block_count, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Write 10 command. Write n blocks starting from LBA to device // Complete callback is invoked when SCSI op is complete. // NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled -bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, const void *buffer, uint32_t lba, uint16_t block_count, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Read Capacity 10 command // Complete callback is invoked when SCSI op is complete. // Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by // simply call tuh_msc_get_block_count() and tuh_msc_get_block_size() -bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t *response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg); //------------- Application Callback -------------// @@ -118,15 +124,15 @@ void tuh_msc_umount_cb(uint8_t dev_addr); // Internal Class Driver API //--------------------------------------------------------------------+ -bool msch_init (void); -bool msch_deinit (void); -bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); -bool msch_set_config (uint8_t daddr, uint8_t itf_num); -void msch_close (uint8_t dev_addr); -bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +bool msch_init(void); +bool msch_deinit(void); +uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len); +bool msch_set_config(uint8_t daddr, uint8_t itf_num); +void msch_close(uint8_t dev_addr); +bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus - } +} #endif #endif diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index b53fa5c02..d74760608 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -388,10 +388,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) { } TU_ATTR_ALWAYS_INLINE static inline bool tu_desc_in_bounds(const uint8_t *p_desc, const uint8_t *desc_end) { - if (p_desc >= desc_end) { - return false; - } - return tu_desc_next(p_desc) <= desc_end; + return p_desc < desc_end && tu_desc_next(p_desc) <= desc_end; } // find descriptor that match byte1 (type) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index a94470039..586250163 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -99,9 +99,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(tusb_desc_endpoint_t c bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max, const uint8_t *p_desc, uint16_t desc_len); -// Calculate total length of n interfaces (depending on IAD) -uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); - // Claim an endpoint with provided mutex bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex); diff --git a/src/host/hub.c b/src/host/hub.c index 0b172a596..3baaff30f 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -218,27 +218,27 @@ bool hub_deinit(void) { return true; } -bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { +uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && - 0 == itf_desc->bInterfaceSubClass); - TU_VERIFY(itf_desc->bInterfaceProtocol <= 1); // not support multiple TT yet + 0 == itf_desc->bInterfaceSubClass, 0); + TU_VERIFY(itf_desc->bInterfaceProtocol <= 1, 0); // not support multiple TT yet - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); - TU_ASSERT(drv_len <= max_len); + const uint16_t drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + TU_ASSERT(drv_len <= max_len, 0); // Interrupt Status endpoint tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); - TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep)); + TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep), 0); hub_interface_t* p_hub = get_hub_itf(dev_addr); p_hub->itf_num = itf_desc->bInterfaceNumber; p_hub->ep_in = desc_ep->bEndpointAddress; - return true; + return drv_len; } void hub_close(uint8_t dev_addr) { diff --git a/src/host/hub.h b/src/host/hub.h index 3587f0ee3..d9750f8a5 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -206,12 +206,12 @@ bool hub_clear_feature(uint8_t hub_addr, uint8_t feature, tuh_xfer_cb_t complete //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -bool hub_init (void); -bool hub_deinit (void); -bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); -bool hub_set_config (uint8_t daddr, uint8_t itf_num); -bool hub_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void hub_close (uint8_t dev_addr); +bool hub_init(void); +bool hub_deinit(void); +uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +bool hub_set_config(uint8_t daddr, uint8_t itf_num); +bool hub_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void hub_close(uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/host/usbh.c b/src/host/usbh.c index 734024771..7c4910af1 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1815,85 +1815,51 @@ static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configurat TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); // parse each interfaces - while( p_desc < desc_end ) { - if ( 0 == tu_desc_len(p_desc) ) { + while (tu_desc_in_bounds(p_desc, desc_end)) { + 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 %" PRIu32 " bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg); break; } - uint8_t assoc_itf_count = 1; - - // Class will always starts with Interface Association (if any) and then Interface descriptor - if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) { - tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; - assoc_itf_count = desc_iad->bInterfaceCount; - - p_desc = tu_desc_next(p_desc); // next to Interface - - // IAD's first interface number and class should match with opened interface - //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber && - // desc_iad->bFunctionClass == desc_itf->bInterfaceClass); - } - - TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); - tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; - -#if CFG_TUH_MIDI - // MIDI has 2 interfaces (Audio Control v1 + MIDIStreaming) but does not have IAD - // manually force associated count = 2 - if (1 == assoc_itf_count && - TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && - AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && - AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { - assoc_itf_count = 2; + // skip if not interface + if (TUSB_DESC_INTERFACE != tu_desc_type(p_desc)) { + p_desc = tu_desc_next(p_desc); + continue; } -#endif + const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc; -#if CFG_TUH_CDC - // Some legacy CDC device does not use IAD but rather use device class as hint to combine 2 interfaces - // manually force associated count = 2 - if (1 == assoc_itf_count && - TUSB_CLASS_CDC == desc_itf->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) { - assoc_itf_count = 2; - } -#endif - - uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end-p_desc)); - TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); + // uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) + // (desc_end-p_desc)); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - 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->open(dev->bus_info.rhport, dev_addr, desc_itf, drv_len) ) { - // open successfully - TU_LOG_USBH(" %s opened\r\n", driver->name); - - // bind (associated) interfaces to found driver - for(uint8_t i=0; ibInterfaceNumber+i; - - // Interface number must not be used already - TU_ASSERT( TUSB_INDEX_INVALID_8 == dev->itf2drv[itf_num] ); - dev->itf2drv[itf_num] = drv_id; + const uint16_t remaining_len = (uint16_t)(desc_end - p_desc); + uint8_t drv_id; + for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + const usbh_class_driver_t *driver = get_driver(drv_id); + if (driver) { + const uint16_t drv_len = driver->open(dev->bus_info.rhport, dev_addr, desc_itf, remaining_len); + if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) { + // open successfully + TU_LOG_USBH(" %s opened\r\n", driver->name); + + // bind found driver to all interfaces and endpoint within drv_len + tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, p_desc, drv_len); + + p_desc += drv_len; // next Interface + break; // exit driver find loop } - - // bind all endpoints to found driver - tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id); - - break; // exit driver find loop - } - - if (drv_id == TOTAL_DRIVER_COUNT - 1) { - TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", - dev->bus_info.rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } } - // next Interface or IAD descriptor - p_desc += drv_len; + // no driver found + if (drv_id == TOTAL_DRIVER_COUNT) { + p_desc = tu_desc_next(p_desc); // skip this interface + TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + dev->bus_info.rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, + desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); + } } return true; diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index d722bb7e8..57428e3c5 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -44,16 +44,15 @@ //--------------------------------------------------------------------+ // Class Driver API //--------------------------------------------------------------------+ - typedef struct { - char const* name; - bool (* const init )(void); - bool (* const deinit )(void); - bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); - bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); - bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* const close )(uint8_t dev_addr); -} usbh_class_driver_t; + const char *name; + bool (*const init)(void); + bool (*const deinit)(void); + uint16_t (*const open)(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); + bool (*const set_config)(uint8_t dev_addr, uint8_t itf_num); + bool (*const xfer_cb)(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + void (*const close)(uint8_t dev_addr); + } usbh_class_driver_t; // Invoked when initializing host stack to get additional class drivers. // Can be implemented by application to extend/overwrite class driver support. diff --git a/src/tusb.c b/src/tusb.c index de6ec0211..c62052c97 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -310,37 +310,6 @@ bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t it return true; } -uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) { - uint8_t const* p_desc = (uint8_t const*) desc_itf; - uint16_t len = 0; - - while ((itf_count--) > 0) { - // Next on interface desc - len += tu_desc_len(desc_itf); - p_desc = tu_desc_next(p_desc); - - while (len < max_len) { - if (tu_desc_len(p_desc) == 0) { - // Escape infinite loop - break; - } - // return on IAD regardless of itf count - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { - return len; - } - if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && - ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) { - break; - } - - len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } - } - - return len; -} - //--------------------------------------------------------------------+ // Endpoint Stream Helper for both Host and Device stack //--------------------------------------------------------------------+ -- cgit v1.3.1 From 2f5d4dbab3a4b051eda35c7026d2568c7355decd Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Dec 2025 00:51:57 +0700 Subject: fix edpt stream write/read to endpoint not yet opened --- src/class/cdc/cdc_device.c | 2 -- src/class/midi/midi_device.c | 3 --- src/common/tusb_fifo.c | 4 ++-- src/tusb.c | 2 ++ 4 files changed, 4 insertions(+), 7 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 8ea4080cc..e2819ae4b 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -43,8 +43,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) - typedef struct { uint8_t rhport; uint8_t itf_num; diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index e0a5aa9c3..023a81595 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -171,15 +171,12 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, ui bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); return 4 == tu_edpt_stream_read(ep_str, packet, 4); } uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - const uint32_t num_read = tu_edpt_stream_read(ep_str, packets, 4u * max_packets); return num_read >> 2u; } diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index ef787c6e6..2faf72ba8 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -289,7 +289,7 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd // Advance an absolute index // "absolute" index is only in the range of [0..2*depth) -TU_ATTR_ALWAYS_INLINE static inline uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { +static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index @@ -313,7 +313,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t id // Works on local copies of w // When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo -TU_ATTR_ALWAYS_INLINE static inline uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { +static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { uint16_t rd_idx; if (wr_idx >= f->depth) { rd_idx = wr_idx - f->depth; diff --git a/src/tusb.c b/src/tusb.c index f6ca3fabc..8ba9f0fff 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -332,6 +332,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove } static bool stream_claim(tu_edpt_stream_t *s) { + TU_VERIFY(s->ep_addr != 0); // must be opened if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_claim(s->hwid, s->ep_addr); @@ -446,6 +447,7 @@ uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) { #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode + TU_VERIFY(s->ep_addr > 0); // must be opened bool is_busy = true; if (s->is_host) { #if CFG_TUH_ENABLED -- cgit v1.3.1 From 135a130ba51d2e41b30f13fbd998f1db32a47470 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 11 Feb 2026 22:04:44 +0100 Subject: fix rx transfer length when high speed capable device/host working at full speed Signed-off-by: HiFiPhile --- src/class/cdc/cdc_device.c | 12 ++++++------ src/class/cdc/cdc_device.h | 2 ++ src/class/cdc/cdc_host.c | 8 ++++---- src/class/midi/midi_device.c | 8 ++++---- src/class/midi/midi_host.c | 6 +++--- src/class/vendor/vendor_device.c | 36 +++++++++++++++++++++--------------- src/class/vendor/vendor_device.h | 17 ++++++++++++++++- src/common/tusb_private.h | 7 ++++--- src/tusb.c | 7 +++---- 9 files changed, 63 insertions(+), 40 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index e2819ae4b..eca4d0ad6 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -74,7 +74,7 @@ typedef struct { } cdcd_epbuf_t; CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; -#endif + #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available @@ -267,14 +267,13 @@ void cdcd_init(void) { uint8_t *epin_buf = _cdcd_epbuf[i].epin; #endif - tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf, - CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, p_cdc->tx_ff_buf, - CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); + CFG_TUD_CDC_TX_BUFSIZE, epin_buf); } } @@ -349,7 +348,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, rhport, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_EP_BUFSIZE); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(stream_tx); // flush pending data } else { @@ -358,7 +357,8 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - tu_edpt_stream_open(stream_rx, rhport, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep, + _cdcd_cfg.rx_multiple_packet_transfer ? CFG_TUD_CDC_EP_BUFSIZE : tu_edpt_packet_size(desc_ep)); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 0809b578f..2d3a81f60 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -64,6 +64,7 @@ typedef struct TU_ATTR_PACKED { bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten + bool rx_multiple_packet_transfer : 1; // allow transfer more than one packet in a single transfer, increase throughput but requires host sending ZLP at the end of transfer } tud_cdc_configure_t; TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); @@ -71,6 +72,7 @@ TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); .rx_persistent = false, \ .tx_persistent = false, \ .tx_overwritabe_if_not_connected = true, \ + .rx_multiple_packet_transfer = false, \ } // Configure CDC driver behavior diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f19c4a327..8b5667aac 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -648,10 +648,10 @@ bool cdch_init(void) { 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_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - epbuf->tx, CFG_TUH_CDC_TX_EPSIZE)); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, + CFG_TUH_CDC_TX_BUFSIZE, epbuf->tx)); TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, - CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx, CFG_TUH_CDC_RX_EPSIZE)); + CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx)); } return true; @@ -735,7 +735,7 @@ 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)); const uint8_t ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress); tu_edpt_stream_t *stream = (ep_dir == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; - tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep, desc_ep->wMaxPacketSize); tu_edpt_stream_clear(stream); desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 023a81595..173baf53e 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -324,10 +324,10 @@ void midid_init(void) { #endif tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, - CFG_TUD_MIDI_RX_BUFSIZE, epout_buf, CFG_TUD_MIDI_EP_BUFSIZE); + CFG_TUD_MIDI_RX_BUFSIZE, epout_buf); tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, - epin_buf, CFG_TUD_MIDI_EP_BUFSIZE); + epin_buf); } } @@ -408,11 +408,11 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; - tu_edpt_stream_open(stream_tx, rhport, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_EP_BUFSIZE); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; - tu_edpt_stream_open(stream_rx, rhport, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(stream_rx); TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare to receive data } diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 5548a0ba8..a3d61a02f 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -121,9 +121,9 @@ bool midih_init(void) { for (int inst = 0; inst < CFG_TUH_MIDI; inst++) { midih_interface_t *p_midi_host = &_midi_host[inst]; 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); + p_midi_host->ep_stream.rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, _midi_epbuf->rx); 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); + p_midi_host->ep_stream.tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, _midi_epbuf->tx); } return true; } @@ -306,7 +306,7 @@ uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_ ep_stream = &p_midi->ep_stream.rx; } TU_ASSERT(tuh_edpt_open(dev_addr, p_ep), 0); - tu_edpt_stream_open(ep_stream, dev_addr, p_ep); + tu_edpt_stream_open(ep_stream, dev_addr, p_ep, p_ep->wMaxPacketSize); tu_edpt_stream_clear(ep_stream); break; diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index b917c8dc7..b2dd8f394 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -49,8 +49,7 @@ typedef struct { #else uint8_t ep_in; uint8_t ep_out; - uint16_t ep_in_mps; - uint16_t ep_out_mps; + uint16_t rx_xfer_len; #endif } vendord_interface_t; @@ -72,6 +71,8 @@ typedef struct { CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; #endif +static tud_vendor_configure_t _vendord_cfg = TUD_VENDOR_CONFIGURE_DEFAULT(); + //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -89,6 +90,12 @@ TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { //-------------------------------------------------------------------- // Application API //-------------------------------------------------------------------- +bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg) { + TU_VERIFY(driver_cfg != NULL); + _vendord_cfg = *driver_cfg; + return true; +} + bool tud_vendor_n_mounted(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; @@ -128,9 +135,9 @@ void tud_vendor_n_read_flush(uint8_t idx) { tu_edpt_stream_clear(&p_itf->rx_stream); tu_edpt_stream_read_xfer(&p_itf->rx_stream); } -#endif + #endif -#if CFG_TUD_VENDOR_RX_MANUAL_XFER + #if CFG_TUD_VENDOR_RX_MANUAL_XFER bool tud_vendor_n_read_xfer(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; @@ -141,7 +148,7 @@ bool tud_vendor_n_read_xfer(uint8_t idx) { #else // Non-FIFO mode TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_out)); - return usbd_edpt_xfer(p_itf->rhport, p_itf->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false); + return usbd_edpt_xfer(p_itf->rhport, p_itf->ep_out, _vendord_epbuf[idx].epout, p_itf->rx_xfer_len, false); #endif } #endif @@ -215,12 +222,10 @@ void vendord_init(void) { #endif uint8_t *rx_ff_buf = p_itf->rx_ff_buf; - tu_edpt_stream_init(&p_itf->rx_stream, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf, - CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_init(&p_itf->rx_stream, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf); uint8_t *tx_ff_buf = p_itf->tx_ff_buf; - tu_edpt_stream_init(&p_itf->tx_stream, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf, - CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_init(&p_itf->tx_stream, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf); } #endif } @@ -302,30 +307,31 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); + uint16_t rx_xfer_len = _vendord_cfg.rx_multiple_packet_transfer ? CFG_TUD_VENDOR_EPSIZE : tu_edpt_packet_size(desc_ep); + #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *tx_stream = &p_vendor->tx_stream; - tu_edpt_stream_open(tx_stream, rhport, desc_ep); + tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_EPSIZE); tu_edpt_stream_write_xfer(tx_stream); // flush pending data } else { tu_edpt_stream_t *rx_stream = &p_vendor->rx_stream; - tu_edpt_stream_open(rx_stream, rhport, desc_ep); + tu_edpt_stream_open(rx_stream, rhport, desc_ep, rx_xfer_len); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 TU_ASSERT(tu_edpt_stream_read_xfer(rx_stream) > 0, 0); // prepare for incoming data #endif } #else + p_vendor->rx_xfer_len = rx_xfer_len; // Non-FIFO mode: store endpoint info if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_vendor->ep_in = desc_ep->bEndpointAddress; - p_vendor->ep_in_mps = tu_edpt_packet_size(desc_ep); } else { p_vendor->ep_out = desc_ep->bEndpointAddress; - p_vendor->ep_out_mps = tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 // Prepare for incoming data - TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false), 0); + TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, rx_xfer_len, false), 0); #endif } #endif @@ -367,7 +373,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint // Non-FIFO mode: invoke callback with buffer tud_vendor_rx_cb(idx, _vendord_epbuf[idx].epout, xferred_bytes); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false); + usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, p_vendor->rx_xfer_len, false); #endif } else if (ep_addr == p_vendor->ep_in) { // Send complete diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 101765bb1..594da19cb 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -37,7 +37,7 @@ extern "C" { // Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_VENDOR_EPSIZE - #define CFG_TUD_VENDOR_EPSIZE 64 + #define CFG_TUD_VENDOR_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif // RX FIFO can be disabled by setting this value to 0 @@ -62,6 +62,21 @@ extern "C" { #define CFG_TUD_VENDOR_RX_MANUAL_XFER 0 #endif +//--------------------------------------------------------------------+ +// Driver Configuration +//--------------------------------------------------------------------+ +typedef struct TU_ATTR_PACKED { + bool rx_multiple_packet_transfer : 1; // allow transfer more than one packet in a single transfer, increase throughput but requires host sending ZLP at the end of transfer +} tud_vendor_configure_t; +TU_VERIFY_STATIC(sizeof(tud_vendor_configure_t) == 1, "size is not correct"); + +#define TUD_VENDOR_CONFIGURE_DEFAULT() { \ + .rx_multiple_packet_transfer = false, \ +} + +// Configure CDC driver behavior +bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg); + //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 43ce7a1df..7795d7122 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -62,7 +62,7 @@ typedef struct { uint8_t ep_addr; uint16_t mps; - uint16_t ep_bufsize; + uint16_t xfer_len; uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; @@ -101,7 +101,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Init an endpoint stream bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, - uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize); + uint16_t ff_bufsize, uint8_t *ep_buf); // Deinit an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) { @@ -118,10 +118,11 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t // Open an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid, - const tusb_desc_endpoint_t *desc_ep) { + const tusb_desc_endpoint_t *desc_ep, uint16_t xfer_len) { s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; s->mps = tu_edpt_packet_size(desc_ep); + s->xfer_len = xfer_len; } TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) { diff --git a/src/tusb.c b/src/tusb.c index 6075e9db4..27864cb51 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -306,7 +306,7 @@ bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t it //--------------------------------------------------------------------+ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, - uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize) { + uint16_t ff_bufsize, uint8_t *ep_buf) { (void) is_tx; if (ff_buf == NULL || ff_bufsize == 0) { @@ -324,7 +324,6 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove #endif s->ep_buf = ep_buf; - s->ep_bufsize = ep_bufsize; return true; } @@ -394,7 +393,7 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { if (s->ep_buf == NULL) { count = tu_fifo_count(&s->ff); // re-get count since fifo can be changed } else { - count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + count = tu_fifo_read_n(&s->ff, s->ep_buf, s->xfer_len); } if (count > 0) { @@ -441,7 +440,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { if (available >= s->mps) { // multiple of packet size limit by ep bufsize uint16_t count = (uint16_t) (available & ~(s->mps - 1)); - count = tu_min16(count, s->ep_bufsize); + count = tu_min16(count, s->xfer_len); TU_ASSERT(stream_xfer(s, count), 0); return count; } else { -- cgit v1.3.1 From 5efa72cd57325615efae6a26ff8c9fe8a9c7b3b5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 11 Feb 2026 22:24:34 +0100 Subject: fix ep size and midi buffer Signed-off-by: HiFiPhile --- src/class/cdc/cdc_host.c | 2 +- src/class/midi/midi_host.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 8b5667aac..57d497950 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -735,7 +735,7 @@ 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)); const uint8_t ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress); tu_edpt_stream_t *stream = (ep_dir == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; - tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep, desc_ep->wMaxPacketSize); + tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(stream); desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index a3d61a02f..bef4d46bf 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -121,9 +121,9 @@ bool midih_init(void) { for (int inst = 0; inst < CFG_TUH_MIDI; inst++) { midih_interface_t *p_midi_host = &_midi_host[inst]; 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); + p_midi_host->ep_stream.rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, _midi_epbuf[inst].rx); 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); + p_midi_host->ep_stream.tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, _midi_epbuf[inst].tx); } return true; } @@ -306,7 +306,7 @@ uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_ ep_stream = &p_midi->ep_stream.rx; } TU_ASSERT(tuh_edpt_open(dev_addr, p_ep), 0); - tu_edpt_stream_open(ep_stream, dev_addr, p_ep, p_ep->wMaxPacketSize); + tu_edpt_stream_open(ep_stream, dev_addr, p_ep, tu_edpt_packet_size(p_ep)); tu_edpt_stream_clear(ep_stream); break; -- cgit v1.3.1 From 4d402194dc506a98ed574233cd542ca7f27ff991 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Wed, 25 Feb 2026 12:38:44 -0300 Subject: midi device: add cable-aware stream read (tud_midi_n_demux_stream_read) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing tud_midi_n_stream_read() accepts a cable_num parameter but ignores it — all cables share a single FIFO and stream parser state, so data from different virtual cables is silently mixed together. Add tud_midi_n_demux_stream_read() which returns the cable number of the data that was actually read. It peeks at each USB-MIDI event packet header before consuming it and stops when the next packet belongs to a different cable, allowing callers to dispatch per-cable without losing data. Implementation details: - Mirrors the host-side tuh_midi_stream_read() approach: tu_edpt_stream_peek for cable inspection, CIN-based byte count (USB MIDI 1.0 Table 4-1), leftover handling via existing midi_driver_stream_t - *p_cable_num initialized to 0xff sentinel so callers can detect "no data" even when return value is 0 - Cable-change check (total_read > 0 guard) covers both leftover-originated reads and freshly consumed packets - TU_VERIFY uses explicit != NULL comparisons, consistent with codebase style - Note: shares stream->buffer with tud_midi_n_stream_read(); do not mix calls on the same interface - Adds single-interface convenience wrapper tud_midi_demux_stream_read() Closes #1838 --- src/class/midi/midi_device.c | 102 +++++++++++++++++++++++++++++++++++++++++++ src/class/midi/midi_device.h | 12 +++++ 2 files changed, 114 insertions(+) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 023a81595..a49cd725b 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -168,6 +168,108 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, ui return total_read; } +// Note: this function shares stream->buffer with tud_midi_n_stream_read(). +// Do not mix calls to both functions on the same interface. +uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize) { + TU_VERIFY(p_cable_num != NULL && buffer != NULL && bufsize > 0, 0); + + midid_interface_t *p_midi = &_midid_itf[itf]; + midi_driver_stream_t *stream = &p_midi->stream_read; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; + + uint8_t *buf8 = (uint8_t *)buffer; + uint32_t total_read = 0; + + // Initialize to invalid cable so callers can detect "no data" even when + // the return value is 0. + *p_cable_num = 0xff; + + // If there are leftover bytes from a previous partial read, return them first + if (stream->total > 0) { + *p_cable_num = (stream->buffer[0] >> 4) & 0x0f; + const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize); + TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)); + + total_read += count; + stream->index += count; + buf8 += count; + bufsize -= count; + + if (stream->total == stream->index) { + stream->index = 0; + stream->total = 0; + } + + if (bufsize == 0) { + return total_read; + } + } + + while (bufsize > 0) { + // Peek at next packet header to get cable number without consuming + uint8_t one_byte; + if (!tu_edpt_stream_peek(ep_str, &one_byte)) { + break; + } + + const uint8_t next_cable = (one_byte >> 4) & 0x0f; + + // Stop if cable changed (covers both leftover-originated reads and + // freshly consumed packets — total_read > 0 in either case) + if (total_read > 0 && next_cable != *p_cable_num) { + break; + } + *p_cable_num = next_cable; + + // Consume the packet + if (!tud_midi_n_packet_read(itf, stream->buffer)) { + break; + } + + const uint8_t code_index = stream->buffer[0] & 0x0f; + uint8_t msg_bytes; + + // MIDI 1.0 Table 4-1: Code Index Number Classifications + switch (code_index) { + case MIDI_CIN_MISC: + case MIDI_CIN_CABLE_EVENT: + // Reserved and unused, skip this packet + continue; + + case MIDI_CIN_SYSEX_END_1BYTE: + case MIDI_CIN_1BYTE_DATA: + msg_bytes = 1; + break; + + case MIDI_CIN_SYSCOM_2BYTE: + case MIDI_CIN_SYSEX_END_2BYTE: + case MIDI_CIN_PROGRAM_CHANGE: + case MIDI_CIN_CHANNEL_PRESSURE: + msg_bytes = 2; + break; + + default: + msg_bytes = 3; + break; + } + + const uint8_t count = (uint8_t)tu_min32((uint32_t)msg_bytes, bufsize); + TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1, count)); + + total_read += count; + buf8 += count; + bufsize -= count; + + if (count < msg_bytes) { + // Output buffer full, save remaining for next call + stream->total = msg_bytes; + stream->index = count; + } + } + + return total_read; +} + bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index ddbc2f9f0..b80ad544a 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -66,6 +66,13 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num); // Read byte stream (legacy) uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize); +// Read byte stream with cable demultiplexing: returns the cable number of the +// data that was read. Reads from a single cable per call; stops when the next +// packet belongs to a different cable so the caller can dispatch per-cable. +// Note: shares internal state with tud_midi_n_stream_read(); do not mix both +// on the same interface. +uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize); + // Write byte Stream (legacy) uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize); @@ -96,6 +103,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_read(void *buffer, return tud_midi_n_stream_read(0, 0, buffer, bufsize); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi_demux_stream_read(uint8_t *p_cable_num, void *buffer, uint32_t bufsize) { + return tud_midi_n_demux_stream_read(0, p_cable_num, buffer, bufsize); +} + TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_write(uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) { return tud_midi_n_stream_write(0, cable_num, buffer, bufsize); -- cgit v1.3.1 From 78bbc7dc2e80daba79351bc37e11b13243fd6f8c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 11:43:32 +0700 Subject: refactor(config): separate endpoint buffer sizes into RX and TX definitions for clarity and flexibility --- examples/device/cdc_dual_ports/src/tusb_config.h | 6 +-- examples/device/cdc_msc/src/tusb_config.h | 6 +-- examples/device/cdc_msc_freertos/src/tusb_config.h | 6 +-- examples/device/cdc_uac2/src/tusb_config.h | 6 +-- examples/device/printer_to_cdc/src/tusb_config.h | 6 ++- examples/dual/dynamic_switch/src/tusb_config.h | 3 +- .../dual/host_hid_to_device_cdc/src/tusb_config.h | 3 +- .../dual/host_info_to_device_cdc/src/tusb_config.h | 3 +- src/class/cdc/cdc_device.c | 14 +++--- src/class/cdc/cdc_device.h | 57 ++++++++++++---------- src/class/cdc/cdc_host.h | 8 +-- src/class/midi/midi_device.c | 6 +-- src/class/midi/midi_device.h | 17 +++++-- src/class/midi/midi_host.c | 4 +- src/class/midi/midi_host.h | 6 +-- src/class/printer/printer_device.c | 22 ++++----- src/class/printer/printer_device.h | 15 +++++- src/class/vendor/vendor_device.c | 18 +++---- src/class/vendor/vendor_device.h | 16 +++++- src/common/tusb_types.h | 4 ++ src/host/usbh.h | 3 +- test/fuzz/device/cdc/src/tusb_config.h | 3 +- test/fuzz/device/msc/src/tusb_config.h | 3 +- test/fuzz/device/net/src/tusb_config.h | 3 +- 24 files changed, 143 insertions(+), 95 deletions(-) (limited to 'src/class/midi') diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index 710c01ee2..f8c36a90d 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -104,9 +104,9 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 3f2f05f20..c4f4374a2 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -104,9 +104,9 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 8277b1604..33342819e 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -111,9 +111,9 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h index 5eb2e8f74..6724b83b3 100644 --- a/examples/device/cdc_uac2/src/tusb_config.h +++ b/examples/device/cdc_uac2/src/tusb_config.h @@ -160,9 +160,9 @@ extern "C" { #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/device/printer_to_cdc/src/tusb_config.h b/examples/device/printer_to_cdc/src/tusb_config.h index c38e8e1ee..d12313ce5 100644 --- a/examples/device/printer_to_cdc/src/tusb_config.h +++ b/examples/device/printer_to_cdc/src/tusb_config.h @@ -103,12 +103,14 @@ extern "C" { #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Printer buffer sizes #define CFG_TUD_PRINTER_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_PRINTER_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -#define CFG_TUD_PRINTER_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_PRINTER_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_PRINTER_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/dual/dynamic_switch/src/tusb_config.h b/examples/dual/dynamic_switch/src/tusb_config.h index af0d55f14..f9500f923 100644 --- a/examples/dual/dynamic_switch/src/tusb_config.h +++ b/examples/dual/dynamic_switch/src/tusb_config.h @@ -130,7 +130,8 @@ extern "C" { #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION diff --git a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h index 2843e0b83..0a7137d29 100644 --- a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h @@ -115,7 +115,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION diff --git a/examples/dual/host_info_to_device_cdc/src/tusb_config.h b/examples/dual/host_info_to_device_cdc/src/tusb_config.h index 601c27dae..8f3ed6357 100644 --- a/examples/dual/host_info_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_info_to_device_cdc/src/tusb_config.h @@ -115,7 +115,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2be3b8ade..3f207462e 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -63,10 +63,10 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) // Skip local EP buffer if dedicated hw FIFO is supported - #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_CDC_RX_EPSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_CDC_TX_EPSIZE); #if CFG_TUD_CDC_NOTIFY TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify); @@ -74,7 +74,7 @@ typedef struct { } cdcd_epbuf_t; CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; - #endif +#endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available @@ -347,7 +347,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_TX_EPSIZE); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(stream_tx); // flush pending data } else { @@ -356,7 +356,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; tu_edpt_stream_open(stream_rx, rhport, desc_ep, - _cdcd_cfg.rx_need_zlp ? CFG_TUD_CDC_EP_BUFSIZE : tu_edpt_packet_size(desc_ep)); + _cdcd_cfg.rx_need_zlp ? CFG_TUD_CDC_RX_EPSIZE : tu_edpt_packet_size(desc_ep)); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } @@ -511,7 +511,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } // Data sent to host, we continue to fetch from tx fifo to send. - // Note: This will cause incorrect baudrate set in line coding. Though maybe the baudrate is not really important ! + // Note: This will cause incorrect baudrate set in line coding. Though maybe the baudrate is not really important! if (ep_addr == stream_tx->ep_addr) { tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 64e58e5ec..3baf84d00 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -29,6 +29,10 @@ #include "cdc.h" +#ifdef __cplusplus + extern "C" { +#endif + //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ @@ -37,46 +41,49 @@ #endif #ifndef CFG_TUD_CDC_TX_BUFSIZE - #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + #define CFG_TUD_CDC_TX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif #ifndef CFG_TUD_CDC_RX_BUFSIZE - #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + #define CFG_TUD_CDC_RX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif -#if !defined(CFG_TUD_CDC_EP_BUFSIZE) && defined(CFG_TUD_CDC_EPSIZE) - #warning CFG_TUD_CDC_EPSIZE is renamed to CFG_TUD_CDC_EP_BUFSIZE, please update to use the new name - #define CFG_TUD_CDC_EP_BUFSIZE CFG_TUD_CDC_EPSIZE +// EP_BUFSIZE is separated to RX_EPSIZE and TX_EPSIZE +#ifndef CFG_TUD_CDC_RX_EPSIZE + #ifdef CFG_TUD_CDC_EP_BUFSIZE + #define CFG_TUD_CDC_RX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE + #else + #define CFG_TUD_CDC_RX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif -#ifndef CFG_TUD_CDC_EP_BUFSIZE - #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_CDC_TX_EPSIZE + #ifdef CFG_TUD_CDC_EP_BUFSIZE + #define CFG_TUD_CDC_TX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE + #else + #define CFG_TUD_CDC_TX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif -#ifdef __cplusplus - extern "C" { +#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT + #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ + { \ + .rx_persistent = false, \ + .tx_persistent = false, \ + .tx_overwritabe_if_not_connected = true, \ + .rx_need_zlp = false \ + } #endif //--------------------------------------------------------------------+ // Driver Configuration //--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED { - bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect - bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect - bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten - bool rx_need_zlp : 1; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. +typedef struct { + bool rx_persistent; // keep rx fifo data even with bus reset or disconnect + bool tx_persistent; // keep tx fifo data even with reset or disconnect + bool tx_overwritabe_if_not_connected; // if not connected, tx fifo can be overwritten + bool rx_need_zlp; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. } tud_cdc_configure_t; -TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); - -#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT - #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ - { \ - .rx_persistent = false, \ - .tx_persistent = false, \ - .tx_overwritabe_if_not_connected = true, \ - .rx_need_zlp = false \ - } -#endif // Configure CDC driver behavior bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 57919c7ff..1b1709b18 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -39,22 +39,22 @@ extern "C" { // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE - #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // RX Endpoint size #ifndef CFG_TUH_CDC_RX_EPSIZE - #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MAX #endif // TX FIFO size #ifndef CFG_TUH_CDC_TX_BUFSIZE - #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // TX Endpoint size #ifndef CFG_TUH_CDC_TX_EPSIZE - #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MAX #endif //--------------------------------------------------------------------+ diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index e5e0f52a5..de4ff5dd8 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -74,8 +74,8 @@ static midid_interface_t _midid_itf[CFG_TUD_MIDI]; #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 // Endpoint Transfer buffer: not used if dedicated hw FIFO is available typedef struct { - TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE); - TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_TX_EPSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_RX_EPSIZE); } midid_epbuf_t; CFG_TUD_MEM_SECTION static midid_epbuf_t _midid_epbuf[CFG_TUD_MIDI]; @@ -510,7 +510,7 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; - tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_EP_BUFSIZE); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_TX_EPSIZE); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index b80ad544a..57eabec1f 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -34,13 +34,20 @@ // Class Driver Configuration //--------------------------------------------------------------------+ -#if !defined(CFG_TUD_MIDI_EP_BUFSIZE) && defined(CFG_TUD_MIDI_EPSIZE) - #warning CFG_TUD_MIDI_EPSIZE is renamed to CFG_TUD_MIDI_EP_BUFSIZE, please update to use the new name - #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE +#ifndef CFG_TUD_MIDI_RX_EPSIZE + #ifdef CFG_TUD_MIDI_EP_BUFSIZE + #define CFG_TUD_MIDI_RX_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE + #else + #define CFG_TUD_MIDI_RX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif -#ifndef CFG_TUD_MIDI_EP_BUFSIZE - #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_MIDI_TX_EPSIZE + #ifdef CFG_TUD_MIDI_EP_BUFSIZE + #define CFG_TUD_MIDI_TX_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE + #else + #define CFG_TUD_MIDI_TX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif #ifdef __cplusplus diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index bef4d46bf..0feb5106d 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -83,8 +83,8 @@ typedef struct { }midih_interface_t; typedef struct { - TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MPS); - TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MPS); + TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MAX); + TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MAX); } midih_epbuf_t; static midih_interface_t _midi_host[CFG_TUH_MIDI]; diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 8a8dccab4..b9ab0130d 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -38,15 +38,15 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE - #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE - #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE - #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // Enable the MIDI stream read/write API. Some library can work with raw USB MIDI packet diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index f5bb33795..d2dc9b163 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -53,8 +53,8 @@ typedef struct { #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_RX_EPSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_TX_EPSIZE); } printer_epbuf_t; CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; @@ -173,12 +173,10 @@ void printerd_init(void) { #endif tu_edpt_stream_init(&p->rx_stream, false, false, false, - p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, - epout_buf, CFG_TUD_PRINTER_EP_BUFSIZE); + p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, epout_buf); tu_edpt_stream_init(&p->tx_stream, false, true, true, - p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, - epin_buf, CFG_TUD_PRINTER_EP_BUFSIZE); + p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, epin_buf); } } @@ -226,12 +224,14 @@ uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, ui TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p->tx_stream, rhport, desc_ep); - tu_edpt_stream_clear(&p->tx_stream); + tu_edpt_stream_t *stream_tx = &p->tx_stream; + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_PRINTER_TX_EPSIZE); + tu_edpt_stream_clear(stream_tx); } else { - tu_edpt_stream_open(&p->rx_stream, rhport, desc_ep); - tu_edpt_stream_clear(&p->rx_stream); - TU_ASSERT(tu_edpt_stream_read_xfer(&p->rx_stream) > 0, 0); + tu_edpt_stream_t *stream_rx = &p->rx_stream; + tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); + tu_edpt_stream_clear(stream_rx); + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); } drv_len += sizeof(tusb_desc_endpoint_t); diff --git a/src/class/printer/printer_device.h b/src/class/printer/printer_device.h index a6b7052cb..afde1f022 100644 --- a/src/class/printer/printer_device.h +++ b/src/class/printer/printer_device.h @@ -27,12 +27,23 @@ #ifndef TUSB_PRINTER_DEVICE_H_ #define TUSB_PRINTER_DEVICE_H_ -#include "printer.h" - #ifdef __cplusplus extern "C" { #endif +#include "printer.h" + +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ +#ifndef CFG_TUD_PRINTER_RX_EPSIZE + #define CFG_TUD_PRINTER_RX_EPSIZE TUD_EPSIZE_BULK_MAX +#endif + +#ifndef CFG_TUD_PRINTER_TX_EPSIZE + #define CFG_TUD_PRINTER_TX_EPSIZE TUD_EPSIZE_BULK_MAX +#endif + //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_PRINTER > 1 //--------------------------------------------------------------------+ diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c7ad8bd8c..c55cad627 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -61,15 +61,15 @@ typedef struct { static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; - // Skip local EP buffer if dedicated hw FIFO is supported or no fifo mode - #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || !CFG_TUD_VENDOR_TXRX_BUFFERED +// Skip local EP buffer if dedicated hw FIFO is supported or no fifo mode +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || !CFG_TUD_VENDOR_TXRX_BUFFERED typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_EPSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_EPSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_RX_EPSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_TX_EPSIZE); } vendord_epbuf_t; CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; - #endif +#endif static tud_vendor_configure_t _vendord_cfg = CFG_TUD_VENDOR_CONFIGURE_DEFAULT(); @@ -167,7 +167,7 @@ uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) { #else // non-fifo mode: direct transfer TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_in), 0); - const uint32_t xact_len = tu_min32(bufsize, CFG_TUD_VENDOR_EPSIZE); + const uint32_t xact_len = tu_min32(bufsize, CFG_TUD_VENDOR_TX_EPSIZE); memcpy(_vendord_epbuf[idx].epin, buffer, xact_len); TU_ASSERT(usbd_edpt_xfer(p_itf->rhport, p_itf->ep_in, _vendord_epbuf[idx].epin, (uint16_t)xact_len, false), 0); return xact_len; @@ -184,7 +184,7 @@ uint32_t tud_vendor_n_write_available(uint8_t idx) { #else // Non-FIFO mode TU_VERIFY(p_itf->ep_in > 0, 0); // must be opened - return usbd_edpt_busy(p_itf->rhport, p_itf->ep_in) ? 0 : CFG_TUD_VENDOR_EPSIZE; + return usbd_edpt_busy(p_itf->rhport, p_itf->ep_in) ? 0 : CFG_TUD_VENDOR_TX_EPSIZE; #endif } @@ -307,13 +307,13 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - uint16_t rx_xfer_len = _vendord_cfg.rx_need_zlp ? CFG_TUD_VENDOR_EPSIZE : tu_edpt_packet_size(desc_ep); + uint16_t rx_xfer_len = _vendord_cfg.rx_need_zlp ? CFG_TUD_VENDOR_RX_EPSIZE : tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *tx_stream = &p_vendor->tx_stream; - tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_TX_EPSIZE); tu_edpt_stream_write_xfer(tx_stream); // flush pending data } else { tu_edpt_stream_t *rx_stream = &p_vendor->rx_stream; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 54f3548c7..491a7d7fb 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -36,8 +36,20 @@ extern "C" { //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ -#ifndef CFG_TUD_VENDOR_EPSIZE - #define CFG_TUD_VENDOR_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_VENDOR_RX_EPSIZE + #ifdef CFG_TUD_VENDOR_EPSIZE + #define CFG_TUD_VENDOR_RX_EPSIZE CFG_TUD_VENDOR_EPSIZE + #else + #define CFG_TUD_VENDOR_RX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif +#endif + +#ifndef CFG_TUD_VENDOR_TX_EPSIZE + #ifdef CFG_TUD_VENDOR_EPSIZE + #define CFG_TUD_VENDOR_TX_EPSIZE CFG_TUD_VENDOR_EPSIZE + #else + #define CFG_TUD_VENDOR_TX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif // RX FIFO can be disabled by setting this value to 0 diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 8a48a0f04..a18f9feb7 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -115,6 +115,10 @@ enum { TUSB_EPSIZE_ISO_HS_MAX = 1024, }; +// Endpoint Bulk size depending on host/device max speed +#define TUD_EPSIZE_BULK_MAX (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define TUH_EPSIZE_BULK_MAX (TUH_OPT_HIGH_SPEED ? 512 : 64) + /// Isochronous Endpoint Attributes typedef enum { TUSB_ISO_EP_ATT_NO_SYNC = 0x00, diff --git a/src/host/usbh.h b/src/host/usbh.h index 143d36f8c..7ddec35b7 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -41,8 +41,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -// Endpoint Bulk size depending on host mx speed -#define TUH_EPSIZE_BULK_MPS (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) + // forward declaration struct tuh_xfer_s; diff --git a/test/fuzz/device/cdc/src/tusb_config.h b/test/fuzz/device/cdc/src/tusb_config.h index 76f44619e..b4b45d798 100644 --- a/test/fuzz/device/cdc/src/tusb_config.h +++ b/test/fuzz/device/cdc/src/tusb_config.h @@ -102,7 +102,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/test/fuzz/device/msc/src/tusb_config.h b/test/fuzz/device/msc/src/tusb_config.h index abd8cd4ce..3400c141d 100644 --- a/test/fuzz/device/msc/src/tusb_config.h +++ b/test/fuzz/device/msc/src/tusb_config.h @@ -102,7 +102,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/test/fuzz/device/net/src/tusb_config.h b/test/fuzz/device/net/src/tusb_config.h index 4fe98e043..46fc10cdb 100644 --- a/test/fuzz/device/net/src/tusb_config.h +++ b/test/fuzz/device/net/src/tusb_config.h @@ -107,7 +107,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 -- cgit v1.3.1 From cca3e7e346d67554597ca5706fc9266c4767266e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 17 Mar 2026 11:28:46 +0700 Subject: fix midi host issue 3544 --- src/class/midi/midi_host.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 0feb5106d..8d59dfc66 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -57,7 +57,7 @@ typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; // interface number of MIDI streaming uint8_t iInterface; - uint8_t itf_count; // number of interface including Audio Control + MIDI streaming + uint8_t itf_count; // number of interfaces including Audio Control + MIDI streaming uint8_t rx_cable_count; // IN endpoint CS descriptor bNumEmbMIDIJack value uint8_t tx_cable_count; // OUT endpoint CS descriptor bNumEmbMIDIJack value @@ -249,10 +249,12 @@ uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_ p_midi->itf_count++; desc_cb.desc_midi = desc_itf; - p_desc = tu_desc_next(p_desc); // next to CS Header - bool found_new_interface = false; - while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) { + do { + p_desc = tu_desc_next(p_desc); + if (!tu_desc_in_bounds(p_desc, desc_end)) { + break; + } switch (tu_desc_type(p_desc)) { case TUSB_DESC_INTERFACE: found_new_interface = true; @@ -314,8 +316,8 @@ uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_ default: break; // skip unknown descriptor } - p_desc = tu_desc_next(p_desc); - } + } while (!found_new_interface); + desc_cb.desc_midi_total_len = (uint16_t)((uintptr_t)p_desc - (uintptr_t)desc_start); p_midi->daddr = dev_addr; @@ -332,7 +334,7 @@ bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) { const tuh_midi_mount_cb_t mount_cb_data = { .daddr = dev_addr, - .bInterfaceNumber = itf_num, + .bInterfaceNumber = p_midi->bInterfaceNumber, .rx_cable_count = p_midi->rx_cable_count, .tx_cable_count = p_midi->tx_cable_count, }; -- cgit v1.3.1 From 88196051e8bd89b282fda8d395f4c333425a91b1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 18 Mar 2026 19:04:13 +0700 Subject: fix bugs in fsdev hcd, dcd and midi host stream write - hcd_edpt_clear_stall: use ep_addr instead of hardcoded 0 (control endpoint) - hcd: add TUP_USBIP_FSDEV_DRD define for MCUs with host support (C0, G0, H5, U3, U5) and use it in hcd compile guard instead of enumerating MCUs - dcd_edpt_close_all: use FSDEV_EP_COUNT instead of CFG_TUD_ENDPPOINT_MAX for PMA btable offset to match handle_bus_reset - midi host tuh_midi_stream_write: add missing cable_num to system messages, SysEx, and real-time MIDI packets. Add 0xF mask for SysEx CIN checks. Aligns with midi_device.c tud_midi_n_stream_write implementation. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/class/midi/midi_host.c | 11 ++++++----- src/common/tusb_mcu.h | 5 +++++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c | 7 ++----- 4 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 8d59dfc66..a53546404 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -461,7 +461,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) { // real-time messages need to be sent right away midi_driver_stream_t streamrt; - streamrt.buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; + streamrt.buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); streamrt.buffer[1] = data; streamrt.index = 2; streamrt.total = 2; @@ -476,9 +476,9 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu stream->buffer[1] = data; // Check to see if we're still in a SysEx transmit. - if (stream->buffer[0] == MIDI_CIN_SYSEX_START) { + if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START) { if (data == MIDI_STATUS_SYSEX_END) { - stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; + stream->buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); stream->total = 2; } else { stream->total = 4; @@ -506,6 +506,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; stream->total = 2; } + stream->buffer[0] |= (uint8_t)(cable_num << 4); } else { // Pack individual bytes if we don't support packing them into words. stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf); @@ -520,8 +521,8 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu 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) { - stream->buffer[0] = MIDI_CIN_SYSEX_START + (stream->index - 1); + if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { + stream->buffer[0] = (uint8_t)((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1))); stream->total = stream->index; } } diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 34dd6af8d..b12a3177e 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -202,6 +202,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32C0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32F0) @@ -278,6 +279,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32G0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32G4) @@ -293,6 +295,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32H5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -366,6 +369,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32U3) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32U5) @@ -373,6 +377,7 @@ #if defined(STM32U535xx) || defined(STM32U545xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #else #define TUP_USBIP_DWC2 diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 13d1a6cb4..8b4719b21 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -612,7 +612,7 @@ void dcd_edpt_close_all(uint8_t rhport) { dcd_int_enable(rhport); // Reset PMA allocation - ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c index dd86b052a..18685dbdc 100644 --- a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c @@ -38,8 +38,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && defined(TUP_USBIP_FSDEV) && \ - TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32G0, OPT_MCU_STM32H5, OPT_MCU_STM32U5) +#if CFG_TUH_ENABLED && defined(TUP_USBIP_FSDEV) && defined(TUP_USBIP_FSDEV_DRD) #include "host/hcd.h" #include "host/usbh.h" @@ -672,10 +671,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet // Clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; - (void) dev_addr; - (void) ep_addr; - uint8_t const ep_id = endpoint_find(dev_addr, 0); + uint8_t const ep_id = endpoint_find(dev_addr, ep_addr); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; -- cgit v1.3.1 From 9c49c0eb215057885ae0aec46172778b9cf9b9a5 Mon Sep 17 00:00:00 2001 From: Hakan Lindestaf Date: Wed, 22 Apr 2026 17:48:07 -0500 Subject: midi host: raise default RX FIFO above EP size, document drain requirement Follow-up to #3239. tuh_midi_stream_read terminates on cable-number transitions, leaving residue in the FIFO. With the default RX FIFO sized equal to one bulk packet, the next bulk IN transfer fails to queue and the driver silently stops receiving. Raising the default to 2x bulk gives single-call apps a full packet of headroom and documents the drain-loop expectation. Reproduced with Akai LPD8 mk1 (VID 09E8 PID 0075) on STM32H753 DWC2 host; fixed with this patch. See #3613 for full repro + captures. --- src/class/midi/midi_host.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index b9ab0130d..4eefed4ba 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -38,11 +38,16 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE - #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX + // Default sized to 2x the bulk endpoint to absorb residue left in the FIFO + // when tuh_midi_stream_read() stops early on a cable-number transition. + // Sizing this equal to the endpoint packet size (the historical default) + // can cause the next bulk IN transfer to fail to queue silently, wedging + // the stream. See the drain-loop note on tuh_midi_stream_read() below. + #define CFG_TUH_MIDI_RX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE - #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX + #define CFG_TUH_MIDI_TX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE @@ -150,6 +155,13 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, const uint8_t *p_ // Note that this function ignores the CIN field of the MIDI packet // because a number of commercial devices out there do not encode // it properly. +// +// NOTE: this function terminates when it encounters an event whose cable +// number differs from the one being returned. Applications should invoke +// it in a loop until it returns 0 (or until tuh_midi_read_available() +// returns 0) to guarantee the stream FIFO is fully drained per callback. +// Leaving bytes in the FIFO across callbacks can prevent subsequent bulk +// IN transfers from landing. uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buffer, uint16_t bufsize); #endif -- cgit v1.3.1 From d24cf89e4896ee959c034818bd4ecb6210714042 Mon Sep 17 00:00:00 2001 From: Hakan Lindestaf Date: Wed, 22 Apr 2026 23:32:05 +0000 Subject: Revert MIDI TX buffer size definition --- src/class/midi/midi_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 4eefed4ba..000d815c4 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -47,7 +47,7 @@ extern "C" { #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE - #define CFG_TUH_MIDI_TX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE -- cgit v1.3.1 From e557f94c721871246ee7ac0761d74e5f8794300f Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Thu, 7 May 2026 11:17:57 +0200 Subject: revert RX buffer size as it's not related to issue Even if CFG_TUH_MIDI_RX_BUFSIZE=100*TUH_EPSIZE_BULK_MAX, calling tuh_midi_stream_read without a loop can return only one 4-byte packet and preventing subsequent transfer. Signed-off-by: Zixun LI --- src/class/midi/midi_host.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 000d815c4..8fdfd8966 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -38,12 +38,7 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE - // Default sized to 2x the bulk endpoint to absorb residue left in the FIFO - // when tuh_midi_stream_read() stops early on a cable-number transition. - // Sizing this equal to the endpoint packet size (the historical default) - // can cause the next bulk IN transfer to fail to queue silently, wedging - // the stream. See the drain-loop note on tuh_midi_stream_read() below. - #define CFG_TUH_MIDI_RX_BUFSIZE (2 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE -- cgit v1.3.1 From bc8ce76ae800b312b4d3ef591cc42e8726e68d7f Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Tue, 24 Mar 2026 23:37:48 -0300 Subject: feat: add MIDI 2.0 Device class driver (USB-MIDI 2.0) Add native USB-MIDI 2.0 Device class driver to TinyUSB. Implements the USB-MIDI 2.0 specification with both Alt Setting 0 (MIDI 1.0 fallback) and Alt Setting 1 (UMP native) descriptor support. Driver features: - UMP (Universal MIDI Packet) read/write with atomic message framing - Protocol negotiation: Endpoint Discovery, Config Request/Notify, Function Block Discovery (embedded in driver) - Group Terminal Block descriptor via GET_DESCRIPTOR - Alt Setting switch handler with endpoint re-arm - Static allocation, no dynamic memory, ISR-safe Build system: - Register midi2d_* in usbd.c driver table - Add TUD_MIDI2_DESCRIPTOR macros to usbd.h - Add config defaults (CFG_TUD_MIDI2_*) to tusb_option.h - Add midi2_ump_word_count() to midi.h (shared by Device and Host) - Add midi2_device.c/h to family.cmake and CMakeLists.txt - Add midi2_device.h include to tusb.h All changes guarded by #if CFG_TUD_MIDI2 (default 0). Zero impact on existing drivers and examples. Tested: Raspberry Pi Pico (RP2040), Linux ALSA, Windows MIDI Services --- hw/bsp/rp2040/family.cmake | 2 + src/CMakeLists.txt | 2 + src/class/midi/midi.h | 18 ++ src/class/midi/midi2_device.c | 604 ++++++++++++++++++++++++++++++++++++++++++ src/class/midi/midi2_device.h | 125 +++++++++ src/device/usbd.c | 14 + src/device/usbd.h | 37 +++ src/tusb.h | 8 + src/tusb_option.h | 52 ++++ 9 files changed, 862 insertions(+) create mode 100644 src/class/midi/midi2_device.c create mode 100644 src/class/midi/midi2_device.h (limited to 'src/class/midi') diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 075582554..aab9a4fae 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -99,6 +99,7 @@ target_sources(tinyusb_device_base INTERFACE ${TOP}/src/class/dfu/dfu_rt_device.c ${TOP}/src/class/hid/hid_device.c ${TOP}/src/class/midi/midi_device.c + ${TOP}/src/class/midi/midi2_device.c ${TOP}/src/class/msc/msc_device.c ${TOP}/src/class/mtp/mtp_device.c ${TOP}/src/class/net/ecm_rndis_device.c @@ -121,6 +122,7 @@ target_sources(tinyusb_host_base INTERFACE ${TOP}/src/class/cdc/cdc_host.c ${TOP}/src/class/hid/hid_host.c ${TOP}/src/class/midi/midi_host.c + ${TOP}/src/class/midi/midi2_host.c ${TOP}/src/class/msc/msc_host.c ${TOP}/src/class/vendor/vendor_host.c ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7a5184c5..b3e05f60f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ function(tinyusb_sources_get OUTPUT_VAR) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/dfu/dfu_rt_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/hid/hid_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi_device.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi2_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/mtp/mtp_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/net/ecm_rndis_device.c @@ -28,6 +29,7 @@ function(tinyusb_sources_get OUTPUT_VAR) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/cdc/cdc_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/hid/hid_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi_host.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi2_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_host.c # typec diff --git a/src/class/midi/midi.h b/src/class/midi/midi.h index cd67640e4..8121ec016 100644 --- a/src/class/midi/midi.h +++ b/src/class/midi/midi.h @@ -185,6 +185,24 @@ typedef midi_desc_cs_endpoint_n_t(1) midi_desc_cs_endpoint_1jack_t; TU_VERIFY_STATIC(sizeof(midi_desc_cs_endpoint_1jack_t) == 4+1, "size is not correct"); +//--------------------------------------------------------------------+ +// MIDI 2.0 UMP Helpers +//--------------------------------------------------------------------+ + +// Return the number of 32-bit words for a UMP message given its Message Type +static inline uint8_t midi2_ump_word_count(uint8_t mt) { + switch (mt) { + case 0x0: case 0x1: case 0x2: case 0x6: case 0x7: + return 1; + case 0x3: case 0x4: case 0x8: case 0x9: case 0xA: + return 2; + case 0xB: case 0xC: + return 3; + default: // 0x5, 0xD, 0xE, 0xF + return 4; + } +} + //--------------------------------------------------------------------+ // For Internal Driver Use //--------------------------------------------------------------------+ diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c new file mode 100644 index 000000000..9363aac11 --- /dev/null +++ b/src/class/midi/midi2_device.c @@ -0,0 +1,604 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Saulo Verissimo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && CFG_TUD_MIDI2 + +#include + +#include "device/usbd.h" +#include "device/usbd_pvt.h" +#include "midi2_device.h" + +//--------------------------------------------------------------------+ +// Weak stubs +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_midi2_rx_cb(uint8_t itf) { (void) itf; } +TU_ATTR_WEAK void tud_midi2_set_itf_cb(uint8_t itf, uint8_t alt) { (void) itf; (void) alt; } +TU_ATTR_WEAK bool tud_midi2_get_req_itf_cb(uint8_t rhport, const tusb_control_request_t* request) { + (void) rhport; (void) request; return false; +} + +//--------------------------------------------------------------------+ +// UMP Stream Message Constants +//--------------------------------------------------------------------+ +// UMP Message Type for Stream messages (bits 31:28) +enum { + MT_STREAM = 0x0F, +}; + +// UMP Stream Status values (10-bit, bits 25:16) +enum { + STREAM_ENDPOINT_DISCOVERY = 0x000, + STREAM_ENDPOINT_INFO = 0x001, + STREAM_EP_NAME = 0x003, + STREAM_PROD_INSTANCE_ID = 0x004, + STREAM_CONFIG_REQUEST = 0x005, + STREAM_CONFIG_NOTIFY = 0x006, + STREAM_FB_DISCOVERY = 0x010, + STREAM_FB_INFO = 0x011, +}; + +// MIDI Protocol values (per USB-MIDI 2.0 spec) +enum { + MIDI_PROTOCOL_MIDI1 = 0x01, + MIDI_PROTOCOL_MIDI2 = 0x02, +}; + +enum { + UMP_VER_MAJOR = 1, + UMP_VER_MINOR = 1, +}; + +// Group Terminal Block descriptor types (USB-MIDI 2.0) +enum { + MIDI2_CS_GRP_TRM_BLOCK = 0x26, + MIDI2_GRP_TRM_BLOCK_HEADER = 0x01, + MIDI2_GRP_TRM_BLOCK_ENTRY = 0x02, +}; + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +typedef struct { + uint8_t rhport; + uint8_t itf_num; + uint8_t alt_setting; + uint8_t protocol; + bool negotiated; + + /*------------- From this point, data is not cleared by bus reset -------------*/ + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; + + uint8_t rx_ff_buf[CFG_TUD_MIDI2_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_MIDI2_TX_BUFSIZE]; + } ep_stream; +} midi2d_interface_t; + +TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_GROUPS >= 1 && CFG_TUD_MIDI2_NUM_GROUPS <= 16, + "CFG_TUD_MIDI2_NUM_GROUPS must be 1..16"); +TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS <= 32, + "CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS must be 1..32"); + +#define ITF_MEM_RESET_SIZE offsetof(midi2d_interface_t, ep_stream) + +static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 +typedef struct { + TUD_EPBUF_DEF(epin, CFG_TUD_MIDI2_TX_EPSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_MIDI2_RX_EPSIZE); +} midi2d_epbuf_t; + +CFG_TUD_MEM_SECTION static midi2d_epbuf_t _midi2d_epbuf[CFG_TUD_MIDI2]; +#endif + +// Default Group Terminal Block descriptor (USB-MIDI 2.0 spec, Table 5-5/5-6) +static const uint8_t _default_gtb_desc[] = { + // GTB Header (5 bytes) + 5, // bLength + MIDI2_CS_GRP_TRM_BLOCK, // bDescriptorType + MIDI2_GRP_TRM_BLOCK_HEADER, // bDescriptorSubtype + U16_TO_U8S_LE(18), // wTotalLength (5 + 13 = 18) + + // GTB Entry (13 bytes) + 13, // bLength + MIDI2_CS_GRP_TRM_BLOCK, // bDescriptorType + MIDI2_GRP_TRM_BLOCK_ENTRY, // bDescriptorSubtype + 1, // bGrpTrmBlkID + 0x00, // bGrpTrmBlkType: bidirectional + 0x00, // nGroupTrm: first group (0) + CFG_TUD_MIDI2_NUM_GROUPS, // nNumGroupTrm + 0, // iBlockItem: no string + 0x00, // bMIDIProtocol: unknown/not fixed + 0, 0, // wMaxInputBandwidth: unknown + 0, 0 // wMaxOutputBandwidth: unknown +}; + +//--------------------------------------------------------------------+ +// Protocol Negotiation +//--------------------------------------------------------------------+ +static void _nego_send_ump(midi2d_interface_t* p_midi, const uint32_t* words, uint8_t count) { + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + if (!tu_edpt_stream_is_opened(ep_tx)) return; + if (tu_edpt_stream_write_available(ep_tx) < count * 4) return; + tu_edpt_stream_write(ep_tx, words, count * 4); + tu_edpt_stream_write_xfer(ep_tx); +} + +static void _nego_send_endpoint_info(midi2d_interface_t* p_midi) { + uint32_t msg[4] = {0}; + msg[0] = ((uint32_t) MT_STREAM << 28) + | ((uint32_t) STREAM_ENDPOINT_INFO << 16) + | ((uint32_t) UMP_VER_MAJOR << 8) + | (uint32_t) UMP_VER_MINOR; + msg[1] = (1u << 31) // Static Function Blocks flag + | ((uint32_t)(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS & 0x7F) << 24) + | (1u << 9) // MIDI 2.0 Protocol capability + | (1u << 8); // MIDI 1.0 Protocol capability + _nego_send_ump(p_midi, msg, 4); +} + +static void _nego_send_stream_text(midi2d_interface_t* p_midi, uint16_t status, const char* str) { + if (!str || str[0] == '\0') return; + + uint16_t total_len = (uint16_t) strlen(str); + uint16_t offset = 0; + + while (offset < total_len) { + uint16_t remaining = total_len - offset; + uint8_t n = (uint8_t)((remaining > 14) ? 14 : remaining); + bool is_first = (offset == 0); + bool is_last = (remaining <= 14); + + uint8_t form; + if (is_first && is_last) form = 0; + else if (is_first) form = 1; + else if (is_last) form = 3; + else form = 2; + + uint32_t msg[4] = {0}; + msg[0] = ((uint32_t) MT_STREAM << 28) + | ((uint32_t) form << 26) + | ((uint32_t) status << 16); + + const char* p = str + offset; + if (n > 0) msg[0] |= ((uint32_t)(uint8_t) p[0] << 8); + if (n > 1) msg[0] |= (uint32_t)(uint8_t) p[1]; + for (uint8_t i = 2; i < n; i++) { + uint8_t word_idx = (uint8_t)(1 + (i - 2) / 4); + uint8_t shift = (uint8_t)(24 - ((i - 2) % 4) * 8); + msg[word_idx] |= ((uint32_t)(uint8_t) p[i] << shift); + } + + _nego_send_ump(p_midi, msg, 4); + offset += n; + } +} + +static void _nego_send_config_notify(midi2d_interface_t* p_midi, uint8_t protocol) { + uint32_t msg[4] = {0}; + msg[0] = ((uint32_t) MT_STREAM << 28) + | ((uint32_t) STREAM_CONFIG_NOTIFY << 16) + | ((uint32_t) protocol << 8); + _nego_send_ump(p_midi, msg, 4); +} + +static void _nego_send_fb_info(midi2d_interface_t* p_midi, uint8_t fb_idx) { + uint32_t msg[4] = {0}; + msg[0] = ((uint32_t) MT_STREAM << 28) + | ((uint32_t) STREAM_FB_INFO << 16) + | (1u << 15) + | ((uint32_t) fb_idx << 8) + | 0x02; // bDirection: bidirectional + msg[1] = ((uint32_t) 0 << 24) // bFirstGroup + | ((uint32_t) CFG_TUD_MIDI2_NUM_GROUPS << 16); + _nego_send_ump(p_midi, msg, 4); +} + +static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t* words) { + uint16_t status = (words[0] >> 16) & 0x3FF; + + switch (status) { + case STREAM_ENDPOINT_DISCOVERY: + _nego_send_endpoint_info(p_midi); + _nego_send_stream_text(p_midi, STREAM_EP_NAME, CFG_TUD_MIDI2_EP_NAME); + _nego_send_stream_text(p_midi, STREAM_PROD_INSTANCE_ID, CFG_TUD_MIDI2_PRODUCT_ID); + break; + + case STREAM_CONFIG_REQUEST: { + uint8_t req_proto = (words[0] >> 8) & 0xFF; + if (req_proto == MIDI_PROTOCOL_MIDI1 || req_proto == MIDI_PROTOCOL_MIDI2) { + p_midi->protocol = req_proto; + } + _nego_send_config_notify(p_midi, p_midi->protocol); + p_midi->negotiated = true; + break; + } + + case STREAM_FB_DISCOVERY: { + uint8_t fb_idx = (words[0] >> 8) & 0xFF; + if (fb_idx == 0xFF) { + for (uint8_t f = 0; f < CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS; f++) { + _nego_send_fb_info(p_midi, f); + } + } else if (fb_idx < CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS) { + _nego_send_fb_info(p_midi, fb_idx); + } + break; + } + + default: + break; + } +} + +static void _nego_process_rx(midi2d_interface_t* p_midi) { + tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; + uint8_t first_byte; + + while (tu_edpt_stream_peek(ep_rx, &first_byte)) { + uint8_t mt = (first_byte >> 4) & 0x0F; + uint8_t pkt_words = midi2_ump_word_count(mt); + uint32_t pkt_bytes = (uint32_t)pkt_words * 4; + + if (mt != MT_STREAM) break; + if (tu_edpt_stream_read_available(ep_rx) < pkt_bytes) break; + + uint32_t buf[4] = {0}; + tu_edpt_stream_read(ep_rx, buf, pkt_bytes); + _nego_handle_stream_msg(p_midi, buf); + } +} + +//--------------------------------------------------------------------+ +// READ API +//--------------------------------------------------------------------+ +bool tud_midi2_n_mounted(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_MIDI2, false); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + return tu_edpt_stream_is_opened(&p_midi->ep_stream.tx) && + tu_edpt_stream_is_opened(&p_midi->ep_stream.rx); +} + +uint32_t tud_midi2_n_available(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_MIDI2, 0); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + return tu_edpt_stream_read_available(&p_midi->ep_stream.rx) / 4; +} + +uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words) { + TU_VERIFY(itf < CFG_TUD_MIDI2 && words != NULL && max_words > 0, 0); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; + + uint32_t total_read = 0; + while (total_read < max_words) { + uint8_t first_byte; + if (!tu_edpt_stream_peek(ep_rx, &first_byte)) break; + + uint8_t mt = (first_byte >> 4) & 0x0F; + uint8_t pkt_words = midi2_ump_word_count(mt); + + if (total_read + pkt_words > max_words) break; + if (tu_edpt_stream_read_available(ep_rx) < (uint32_t)pkt_words * 4) break; + + tu_edpt_stream_read(ep_rx, &words[total_read], pkt_words * 4); + total_read += pkt_words; + } + + return total_read; +} + +bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]) { + TU_VERIFY(itf < CFG_TUD_MIDI2, false); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + return 4 == tu_edpt_stream_read(&p_midi->ep_stream.rx, packet, 4); +} + +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ +uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t count) { + TU_VERIFY(itf < CFG_TUD_MIDI2 && words != NULL && count > 0, 0); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), 0); + + uint32_t written = 0; + while (written < count) { + uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + + if (written + pkt_words > count) break; + if (tu_edpt_stream_write_available(ep_tx) < pkt_words * 4) break; + + tu_edpt_stream_write(ep_tx, &words[written], pkt_words * 4); + written += pkt_words; + } + + (void) tu_edpt_stream_write_xfer(ep_tx); + return written; +} + +bool tud_midi2_n_packet_write(uint8_t itf, const uint8_t packet[4]) { + TU_VERIFY(itf < CFG_TUD_MIDI2, false); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), false); + TU_VERIFY(tu_edpt_stream_write_available(ep_tx) >= 4, false); + TU_VERIFY(tu_edpt_stream_write(ep_tx, packet, 4) > 0, false); + (void) tu_edpt_stream_write_xfer(ep_tx); + return true; +} + +//--------------------------------------------------------------------+ +// STATE GETTERS +//--------------------------------------------------------------------+ +uint8_t tud_midi2_n_alt_setting(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_MIDI2, 0); + return _midi2d_itf[itf].alt_setting; +} + +bool tud_midi2_n_negotiated(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_MIDI2, false); + return _midi2d_itf[itf].negotiated; +} + +uint8_t tud_midi2_n_protocol(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_MIDI2, 0); + return _midi2d_itf[itf].protocol; +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ +void midi2d_init(void) { + tu_memclr(_midi2d_itf, sizeof(_midi2d_itf)); + for (uint8_t i = 0; i < CFG_TUD_MIDI2; i++) { + midi2d_interface_t* p_midi = &_midi2d_itf[i]; + p_midi->protocol = MIDI_PROTOCOL_MIDI2; + + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + uint8_t* epout_buf = NULL; + uint8_t* epin_buf = NULL; + #else + midi2d_epbuf_t* p_epbuf = &_midi2d_epbuf[i]; + uint8_t* epout_buf = p_epbuf->epout; + uint8_t* epin_buf = p_epbuf->epin; + #endif + + tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, + p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI2_RX_BUFSIZE, epout_buf); + tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, + p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI2_TX_BUFSIZE, epin_buf); + } +} + +bool midi2d_deinit(void) { + for (uint8_t i = 0; i < CFG_TUD_MIDI2; i++) { + midi2d_interface_t* p_midi = &_midi2d_itf[i]; + tu_edpt_stream_deinit(&p_midi->ep_stream.rx); + tu_edpt_stream_deinit(&p_midi->ep_stream.tx); + } + return true; +} + +void midi2d_reset(uint8_t rhport) { + (void) rhport; + for (uint8_t i = 0; i < CFG_TUD_MIDI2; i++) { + midi2d_interface_t* p_midi = &_midi2d_itf[i]; + tu_memclr(p_midi, ITF_MEM_RESET_SIZE); + + tu_edpt_stream_clear(&p_midi->ep_stream.rx); + tu_edpt_stream_close(&p_midi->ep_stream.rx); + + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + tu_edpt_stream_close(&p_midi->ep_stream.tx); + } +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t find_midi2_itf(uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUD_MIDI2; idx++) { + const midi2d_interface_t* p_midi = &_midi2d_itf[idx]; + if (ep_addr == p_midi->ep_stream.rx.ep_addr || ep_addr == p_midi->ep_stream.tx.ep_addr) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; +} + +static uint8_t find_midi2_itf_by_num(uint8_t itf_num) { + for (uint8_t idx = 0; idx < CFG_TUD_MIDI2; idx++) { + if (_midi2d_itf[idx].itf_num == itf_num) return idx; + } + return TUSB_INDEX_INVALID_8; +} + +uint16_t midi2d_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) { + const uint8_t* p_desc = (const uint8_t*) desc_itf; + const uint8_t* desc_end = p_desc + max_len; + + // 1st Interface: Audio Control v1 (optional) + if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { + p_desc = tu_desc_next(desc_itf); + while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { + p_desc = tu_desc_next(p_desc); + } + } + + // 2nd Interface: MIDI Streaming + TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + const tusb_desc_interface_t* desc_midi = (const tusb_desc_interface_t*) p_desc; + + TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && + AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, + 0); + + uint8_t idx = find_midi2_itf(0); + TU_ASSERT(idx < CFG_TUD_MIDI2, 0); + midi2d_interface_t* p_midi = &_midi2d_itf[idx]; + + p_midi->rhport = rhport; + p_midi->itf_num = desc_midi->bInterfaceNumber; + p_midi->alt_setting = 0; + p_midi->protocol = MIDI_PROTOCOL_MIDI2; + p_midi->negotiated = false; + + p_desc = tu_desc_next(p_desc); + + // Skip class-specific descriptors + while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { + p_desc = tu_desc_next(p_desc); + } + + // Find and open endpoint descriptors + uint8_t found_ep = 0; + while ((found_ep < desc_midi->bNumEndpoints) && tu_desc_in_bounds(p_desc, desc_end)) { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { + const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + const uint8_t ep_addr = desc_ep->bEndpointAddress; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p_midi->ep_stream.tx, rhport, desc_ep, CFG_TUD_MIDI2_TX_EPSIZE); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + } else { + tu_edpt_stream_open(&p_midi->ep_stream.rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.rx); + TU_ASSERT(tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx) > 0, 0); + } + + found_ep++; + } + + p_desc = tu_desc_next(p_desc); + } + + // Skip remaining descriptors (alt setting 1, CS endpoints, GTB) + while (tu_desc_in_bounds(p_desc, desc_end)) { + uint8_t dtype = tu_desc_type(p_desc); + if (dtype != TUSB_DESC_CS_INTERFACE && dtype != TUSB_DESC_CS_ENDPOINT && + dtype != TUSB_DESC_INTERFACE && dtype != TUSB_DESC_ENDPOINT) { + break; + } + p_desc = tu_desc_next(p_desc); + } + + return (uint16_t)(p_desc - (const uint8_t*) desc_itf); +} + +bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { + TU_LOG2("MIDI2 ctrl: stage=%u bRequest=0x%02X wValue=0x%04X wIndex=0x%04X wLength=%u\r\n", + stage, request->bRequest, request->wValue, request->wIndex, request->wLength); + + if (stage != CONTROL_STAGE_SETUP) return true; + + switch (request->bRequest) { + case TUSB_REQ_SET_INTERFACE: { + uint8_t itf_num = tu_u16_low(request->wIndex); + uint8_t alt = tu_u16_low(request->wValue); + + uint8_t idx = find_midi2_itf_by_num(itf_num); + if (idx >= CFG_TUD_MIDI2) return false; + + midi2d_interface_t* p_midi = &_midi2d_itf[idx]; + p_midi->alt_setting = alt; + + tu_edpt_stream_clear(&p_midi->ep_stream.rx); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + + if (alt == 1) { + p_midi->negotiated = false; + p_midi->protocol = MIDI_PROTOCOL_MIDI2; + } + + // Re-arm RX endpoint for receiving data after alt setting change + tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); + + tud_midi2_set_itf_cb(idx, alt); + tud_control_status(rhport, request); + return true; + } + + case TUSB_REQ_GET_DESCRIPTOR: { + // wValue: descriptor type (high) | index (low) + // 0x26 = CS_GRP_TRM_BLOCK, index 0x01 + if (request->wValue == ((uint16_t)MIDI2_CS_GRP_TRM_BLOCK << 8 | 0x01)) { + if (tud_midi2_get_req_itf_cb(rhport, request)) return true; + + uint16_t len = request->wLength; + if (len > sizeof(_default_gtb_desc)) { + len = sizeof(_default_gtb_desc); + } + tud_control_xfer(rhport, request, (void*)(uintptr_t) _default_gtb_desc, len); + return true; + } + return false; + } + + default: + return false; + } +} + +bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) rhport; + + uint8_t idx = find_midi2_itf(ep_addr); + TU_ASSERT(idx < CFG_TUD_MIDI2); + midi2d_interface_t* p_midi = &_midi2d_itf[idx]; + + tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + + if (ep_addr == ep_rx->ep_addr) { + if (result == XFER_RESULT_SUCCESS) { + tu_edpt_stream_read_xfer_complete(ep_rx, xferred_bytes); + if (p_midi->alt_setting == 1) { + _nego_process_rx(p_midi); + } + tud_midi2_rx_cb(idx); + } + tu_edpt_stream_read_xfer(ep_rx); + } else if (ep_addr == ep_tx->ep_addr && result == XFER_RESULT_SUCCESS) { + if (0 == tu_edpt_stream_write_xfer(ep_tx)) { + (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, xferred_bytes); + } + } else { + return false; + } + + return true; +} + +#endif diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h new file mode 100644 index 000000000..dac1f0124 --- /dev/null +++ b/src/class/midi/midi2_device.h @@ -0,0 +1,125 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Saulo Verissimo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_MIDI2_DEVICE_H_ +#define TUSB_MIDI2_DEVICE_H_ + +#include "class/audio/audio.h" +#include "midi.h" + +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +// Config defaults are in tusb_option.h: +// CFG_TUD_MIDI2_RX_EPSIZE, CFG_TUD_MIDI2_TX_EPSIZE, +// CFG_TUD_MIDI2_RX_BUFSIZE, CFG_TUD_MIDI2_TX_BUFSIZE, +// CFG_TUD_MIDI2_NUM_GROUPS, CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS, +// CFG_TUD_MIDI2_EP_NAME, CFG_TUD_MIDI2_PRODUCT_ID + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application Callback API (weak, optional) +//--------------------------------------------------------------------+ +void tud_midi2_rx_cb(uint8_t itf); +void tud_midi2_set_itf_cb(uint8_t itf, uint8_t alt); +bool tud_midi2_get_req_itf_cb(uint8_t rhport, const tusb_control_request_t* request); + +//--------------------------------------------------------------------+ +// Application API (Multiple Interfaces) +//--------------------------------------------------------------------+ + +bool tud_midi2_n_mounted(uint8_t itf); +uint32_t tud_midi2_n_available(uint8_t itf); +uint8_t tud_midi2_n_alt_setting(uint8_t itf); +bool tud_midi2_n_negotiated(uint8_t itf); +uint8_t tud_midi2_n_protocol(uint8_t itf); + +uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words); +uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t count); + +bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]); +bool tud_midi2_n_packet_write(uint8_t itf, const uint8_t packet[4]); + +//--------------------------------------------------------------------+ +// Application API (Single Interface) +//--------------------------------------------------------------------+ +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_mounted(void) { + return tud_midi2_n_mounted(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi2_available(void) { + return tud_midi2_n_available(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_midi2_alt_setting(void) { + return tud_midi2_n_alt_setting(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_negotiated(void) { + return tud_midi2_n_negotiated(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_midi2_protocol(void) { + return tud_midi2_n_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi2_ump_read(uint32_t* words, uint32_t max_words) { + return tud_midi2_n_ump_read(0, words, max_words); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi2_ump_write(const uint32_t* words, uint32_t count) { + return tud_midi2_n_ump_write(0, words, count); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_packet_read(uint8_t packet[4]) { + return tud_midi2_n_packet_read(0, packet); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_packet_write(const uint8_t packet[4]) { + return tud_midi2_n_packet_write(0, packet); +} + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void midi2d_init(void); +bool midi2d_deinit(void); +void midi2d_reset(uint8_t rhport); +uint16_t midi2d_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len); +bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request); +bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 0e58f70bf..55ad330c1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -254,6 +254,20 @@ static const usbd_class_driver_t _usbd_driver[] = { }, #endif + #if CFG_TUD_MIDI2 + { + .name = DRIVER_NAME("MIDI2"), + .init = midi2d_init, + .deinit = midi2d_deinit, + .open = midi2d_open, + .reset = midi2d_reset, + .control_xfer_cb = midi2d_control_xfer_cb, + .xfer_cb = midi2d_xfer_cb, + .xfer_isr = NULL, + .sof = NULL + }, + #endif + #if CFG_TUD_VENDOR { .name = DRIVER_NAME("VENDOR"), diff --git a/src/device/usbd.h b/src/device/usbd.h index 473e697ac..af37eff56 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -424,6 +424,43 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ TUD_MIDI_JACKID_OUT_EMB(1) +//--------------------------------------------------------------------+ +// MIDI 2.0 Descriptor Templates (USB-MIDI 2.0) +//--------------------------------------------------------------------+ + +// Alt Setting 1: MS Interface + MS Header (bcdMSC=0x0200) +#define TUD_MIDI2_DESC_ALT1_HEAD_LEN (9 + 7) +#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx) \ + /* MIDI Streaming Interface, Alt Setting 1 */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 1, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, _stridx,\ + /* MS Header (MIDI 2.0) */\ + 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(7) + +// Alt Setting 1: Standard USB Endpoint (7 bytes) + CS Endpoint (subtype 0x02) +#define TUD_MIDI2_DESC_ALT1_EP_LEN(_numgtbs) (7 + 4 + (_numgtbs)) +#define TUD_MIDI2_DESC_ALT1_EP(_ep, _epsize, _numgtbs) \ + 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, \ + (uint8_t)(4 + (_numgtbs)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL_2_0, _numgtbs + +// Total length: Alt 0 (MIDI 1.0) + Alt 1 (UMP) +#define TUD_MIDI2_DESC_LEN (TUD_MIDI_DESC_LEN + TUD_MIDI2_DESC_ALT1_HEAD_LEN + TUD_MIDI2_DESC_ALT1_EP_LEN(1) * 2) + +// Complete MIDI 2.0 descriptor with both alternate settings (single cable/GTB) +#define TUD_MIDI2_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ + /* Alt Setting 0 (MIDI 1.0) */\ + TUD_MIDI_DESC_HEAD(_itfnum, _stridx, 1),\ + TUD_MIDI_DESC_JACK_DESC(1, 0),\ + TUD_MIDI_DESC_EP(_epout, _epsize, 1),\ + TUD_MIDI_JACKID_IN_EMB(1),\ + TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ + TUD_MIDI_JACKID_OUT_EMB(1),\ + /* Alt Setting 1 (UMP) */\ + TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx),\ + TUD_MIDI2_DESC_ALT1_EP(_epout, _epsize, 1),\ + 1, /* bAssoGrpTrmBlkID = 1 */\ + TUD_MIDI2_DESC_ALT1_EP(_epin, _epsize, 1),\ + 1 /* bAssoGrpTrmBlkID = 1 */ + //--------------------------------------------------------------------+ // Audio Descriptor Templates //--------------------------------------------------------------------+ diff --git a/src/tusb.h b/src/tusb.h index c80c8433c..aa6b461e5 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -63,6 +63,10 @@ #include "class/midi/midi_host.h" #endif + #if CFG_TUH_MIDI2 + #include "class/midi/midi2_host.h" + #endif + #if CFG_TUH_VENDOR #include "class/vendor/vendor_host.h" #endif @@ -108,6 +112,10 @@ #include "class/midi/midi_device.h" #endif + #if CFG_TUD_MIDI2 + #include "class/midi/midi2_device.h" + #endif + #if CFG_TUD_VENDOR #include "class/vendor/vendor_device.h" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 154f8e2a4..4483c2200 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -646,6 +646,42 @@ #define CFG_TUD_MIDI 0 #endif +#ifndef CFG_TUD_MIDI2 + #define CFG_TUD_MIDI2 0 +#endif + +#ifndef CFG_TUD_MIDI2_TX_BUFSIZE + #define CFG_TUD_MIDI2_TX_BUFSIZE 256 +#endif + +#ifndef CFG_TUD_MIDI2_RX_BUFSIZE + #define CFG_TUD_MIDI2_RX_BUFSIZE 256 +#endif + +#ifndef CFG_TUD_MIDI2_TX_EPSIZE + #define CFG_TUD_MIDI2_TX_EPSIZE 64 +#endif + +#ifndef CFG_TUD_MIDI2_RX_EPSIZE + #define CFG_TUD_MIDI2_RX_EPSIZE 64 +#endif + +#ifndef CFG_TUD_MIDI2_NUM_GROUPS + #define CFG_TUD_MIDI2_NUM_GROUPS 1 +#endif + +#ifndef CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS + #define CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS 1 +#endif + +#ifndef CFG_TUD_MIDI2_EP_NAME + #define CFG_TUD_MIDI2_EP_NAME "TinyUSB MIDI 2.0" +#endif + +#ifndef CFG_TUD_MIDI2_PRODUCT_ID + #define CFG_TUD_MIDI2_PRODUCT_ID "TinyUSB-MIDI2" +#endif + #ifndef CFG_TUD_VENDOR #define CFG_TUD_VENDOR 0 #endif @@ -815,6 +851,22 @@ #define CFG_TUH_MIDI 0 #endif +#ifndef CFG_TUH_MIDI2 + #define CFG_TUH_MIDI2 0 +#endif + +#ifndef CFG_TUH_MIDI2_RX_BUFSIZE + #define CFG_TUH_MIDI2_RX_BUFSIZE (4 * TUH_EPSIZE_BULK_MAX) +#endif + +#ifndef CFG_TUH_MIDI2_TX_BUFSIZE + #define CFG_TUH_MIDI2_TX_BUFSIZE (4 * TUH_EPSIZE_BULK_MAX) +#endif + +#ifndef CFG_TUH_MIDI2_LOG_LEVEL + #define CFG_TUH_MIDI2_LOG_LEVEL CFG_TUH_LOG_LEVEL +#endif + #ifndef CFG_TUH_MSC #define CFG_TUH_MSC 0 #endif -- cgit v1.3.1 From 7750e51ce1b64bd4d2f0ba6d9671303b96ba80ce Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Tue, 24 Mar 2026 23:38:02 -0300 Subject: feat: add MIDI 2.0 Host class driver (USB-MIDI 2.0) Add native USB-MIDI 2.0 Host class driver to TinyUSB. Implements reactive architecture: enumerate, detect MIDI 2.0 capability, inform application via callbacks. Driver features: - Parse both Alt Setting 0 (MIDI 1.0) and Alt Setting 1 (UMP) - Detect bcdMSC version from descriptor - Auto-select highest protocol (Alt 1 preferred if available) - UMP read/write via endpoint streams - Proper Audio Control interface skip (loop-based, following midi_host.c pattern) - Endpoint open with tuh_edpt_open/tu_edpt_stream_open/clear - usbh_driver_set_config_complete for USBH state machine - Handle Audio Control itf_num in set_config gracefully - 5 weak callback stubs (descriptor, mount, unmount, rx, tx) Build system: - Register midih2_* in usbh.c driver table - Add midi2_host.h include to tusb.h - Add CFG_TUH_MIDI2_LOG_LEVEL to tusb_option.h All changes guarded by #if CFG_TUH_MIDI2 (default 0). Zero impact on existing drivers and examples. Tested: Waveshare RP2350-USB-A (Host) receiving UMP from Raspberry Pi Pico (Device) via PIO-USB, board-to-board --- src/class/midi/midi2_host.c | 502 ++++++++++++++++++++++++++++++++++++++++++++ src/class/midi/midi2_host.h | 99 +++++++++ src/host/usbh.c | 12 ++ 3 files changed, 613 insertions(+) create mode 100644 src/class/midi/midi2_host.c create mode 100644 src/class/midi/midi2_host.h (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c new file mode 100644 index 000000000..beb441b56 --- /dev/null +++ b/src/class/midi/midi2_host.c @@ -0,0 +1,502 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Saulo Verissimo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUH_ENABLED && CFG_TUH_MIDI2) + +#include "host/usbh.h" +#include "host/usbh_pvt.h" +#include "midi2_host.h" + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_MIDI2_LOG_LEVEL, __VA_ARGS__) + +//--------------------------------------------------------------------+ +// Weak stubs for application callbacks +//--------------------------------------------------------------------+ + +TU_ATTR_WEAK void tuh_midi2_descriptor_cb(uint8_t idx, const tuh_midi2_descriptor_cb_t *desc_cb_data) { + (void) idx; (void) desc_cb_data; +} + +TU_ATTR_WEAK void tuh_midi2_mount_cb(uint8_t idx, const tuh_midi2_mount_cb_t *mount_cb_data) { + (void) idx; (void) mount_cb_data; +} + +TU_ATTR_WEAK void tuh_midi2_rx_cb(uint8_t idx, uint32_t xferred_bytes) { + (void) idx; (void) xferred_bytes; +} + +TU_ATTR_WEAK void tuh_midi2_tx_cb(uint8_t idx, uint32_t xferred_bytes) { + (void) idx; (void) xferred_bytes; +} + +TU_ATTR_WEAK void tuh_midi2_umount_cb(uint8_t idx) { + (void) idx; +} + +//--------------------------------------------------------------------+ +// Internal structure and state +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t daddr; + uint8_t bInterfaceNumber; + + uint8_t alt_setting_current; + + uint8_t protocol_version; + uint8_t bcdMSC_hi, bcdMSC_lo; + uint8_t rx_cable_count_alt0; + uint8_t tx_cable_count_alt0; + uint8_t rx_cable_count_alt1; + uint8_t tx_cable_count_alt1; + + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; + + uint8_t rx_ff_buf[CFG_TUH_MIDI2_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUH_MIDI2_TX_BUFSIZE]; + } ep_stream; + + bool mounted; +} midih2_interface_t; + +static midih2_interface_t _midi2_host[CFG_TUH_MIDI2]; + +#if CFG_TUH_EDPT_DEDICATED_HWFIFO == 0 +typedef struct { + TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MAX); + TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MAX); +} midih2_epbuf_t; + +CFG_TUH_MEM_SECTION static midih2_epbuf_t _midi2_epbuf[CFG_TUH_MIDI2]; +#endif + +//--------------------------------------------------------------------+ +// Helper functions +//--------------------------------------------------------------------+ + +static inline uint8_t find_new_midi2_index(void) { + for (uint8_t idx = 0; idx < CFG_TUH_MIDI2; idx++) { + if (_midi2_host[idx].daddr == 0) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; +} + +static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUH_MIDI2; idx++) { + const midih2_interface_t *p_midi = &_midi2_host[idx]; + if ((p_midi->daddr == daddr) && + (ep_addr == p_midi->ep_stream.rx.ep_addr || ep_addr == p_midi->ep_stream.tx.ep_addr)) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; +} + +//--------------------------------------------------------------------+ +// Descriptor parsing +//--------------------------------------------------------------------+ + +static void midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, + const tusb_desc_interface_t *desc_itf, const uint8_t *desc_end) { + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass,); + + p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber; + + const uint8_t *p_desc = (const uint8_t *) desc_itf; + p_desc = tu_desc_next(p_desc); + + uint8_t rx_cable_count = 0; + uint8_t tx_cable_count = 0; + + while (tu_desc_in_bounds(p_desc, desc_end)) { + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { + break; + } + + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { + const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + + // Open endpoint and stream + TU_ASSERT(tuh_edpt_open(p_midi->daddr, p_ep),); + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p_midi->ep_stream.rx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.rx); + } else { + tu_edpt_stream_open(&p_midi->ep_stream.tx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + } + + p_desc = tu_desc_next(p_desc); + + if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { + const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; + + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { + tx_cable_count = p_csep->bNumEmbMIDIJack; + } else { + rx_cable_count = p_csep->bNumEmbMIDIJack; + } + } + } + + p_desc = tu_desc_next(p_desc); + } + + p_midi->rx_cable_count_alt0 = rx_cable_count; + p_midi->tx_cable_count_alt0 = tx_cable_count; +} + +static void midih2_parse_descriptors_alt1(midih2_interface_t *p_midi, + const tusb_desc_interface_t *desc_itf, const uint8_t *desc_end) { + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass,); + TU_VERIFY(desc_itf->bAlternateSetting == 1,); + + const uint8_t *p_desc = (const uint8_t *) desc_itf; + p_desc = tu_desc_next(p_desc); + + uint8_t rx_cable_count = 0; + uint8_t tx_cable_count = 0; + + while (tu_desc_in_bounds(p_desc, desc_end)) { + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { + break; + } + + if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE) { + if (tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_HEADER) { + const uint8_t *bcd_ptr = p_desc + 3; + p_midi->bcdMSC_lo = bcd_ptr[0]; + p_midi->bcdMSC_hi = bcd_ptr[1]; + + if (p_midi->bcdMSC_hi == 0x02) { + p_midi->protocol_version = 1; + } + } + } + + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { + const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + p_desc = tu_desc_next(p_desc); + + if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { + const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; + + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { + tx_cable_count = p_csep->bNumEmbMIDIJack; + } else { + rx_cable_count = p_csep->bNumEmbMIDIJack; + } + } + } + + p_desc = tu_desc_next(p_desc); + } + + p_midi->rx_cable_count_alt1 = rx_cable_count; + p_midi->tx_cable_count_alt1 = tx_cable_count; +} + +//--------------------------------------------------------------------+ +// Auto-selection logic +//--------------------------------------------------------------------+ + +static void midih2_auto_select_alt_setting(midih2_interface_t *p_midi) { + p_midi->alt_setting_current = 0; + if (p_midi->protocol_version == 1) { + p_midi->alt_setting_current = 1; + } +} + +//--------------------------------------------------------------------+ +// Init/Deinit +//--------------------------------------------------------------------+ + +bool midih2_init(void) { + tu_memclr(&_midi2_host, sizeof(_midi2_host)); + for (int inst = 0; inst < CFG_TUH_MIDI2; inst++) { + midih2_interface_t *p_midi = &_midi2_host[inst]; + + #if CFG_TUH_EDPT_DEDICATED_HWFIFO + uint8_t* rx_buf = NULL; + uint8_t* tx_buf = NULL; + #else + uint8_t* rx_buf = _midi2_epbuf[inst].rx; + uint8_t* tx_buf = _midi2_epbuf[inst].tx; + #endif + + tu_edpt_stream_init(&p_midi->ep_stream.rx, true, false, false, + p_midi->ep_stream.rx_ff_buf, CFG_TUH_MIDI2_RX_BUFSIZE, rx_buf); + tu_edpt_stream_init(&p_midi->ep_stream.tx, true, true, false, + p_midi->ep_stream.tx_ff_buf, CFG_TUH_MIDI2_TX_BUFSIZE, tx_buf); + } + return true; +} + +bool midih2_deinit(void) { + for (size_t i = 0; i < CFG_TUH_MIDI2; i++) { + midih2_interface_t* p_midi = &_midi2_host[i]; + tu_edpt_stream_deinit(&p_midi->ep_stream.rx); + tu_edpt_stream_deinit(&p_midi->ep_stream.tx); + } + return true; +} + +//--------------------------------------------------------------------+ +// Class driver callbacks +//--------------------------------------------------------------------+ + +uint16_t midih2_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { + (void) rhport; + + TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0); + + // For Alt Setting 1, reuse existing slot for same device+interface + uint8_t idx = TUSB_INDEX_INVALID_8; + if (desc_itf->bAlternateSetting > 0) { + for (uint8_t i = 0; i < CFG_TUH_MIDI2; i++) { + if (_midi2_host[i].daddr == dev_addr && + _midi2_host[i].bInterfaceNumber == desc_itf->bInterfaceNumber) { + idx = i; + break; + } + } + } + if (idx == TUSB_INDEX_INVALID_8) { + idx = find_new_midi2_index(); + } + TU_VERIFY(idx < CFG_TUH_MIDI2, 0); + + midih2_interface_t *p_midi = &_midi2_host[idx]; + p_midi->daddr = dev_addr; + + const uint8_t *desc_start = (const uint8_t *) desc_itf; + const uint8_t *desc_end = desc_start + max_len; + + // Skip Audio Control interface and any non-MIDI-Streaming descriptors + // (following midi_host.c pattern from Ha Thach) + if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) { + const uint8_t *p_desc = tu_desc_next((const uint8_t *)desc_itf); + // Skip CS_INTERFACE header + TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE, 0); + p_desc = tu_desc_next(p_desc); + desc_itf = (const tusb_desc_interface_t *) p_desc; + // Skip until we find MIDI Streaming interface + while (tu_desc_in_bounds(p_desc, desc_end) && + (desc_itf->bDescriptorType != TUSB_DESC_INTERFACE || + (desc_itf->bInterfaceClass == TUSB_CLASS_AUDIO && + desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING))) { + p_desc = tu_desc_next(p_desc); + desc_itf = (const tusb_desc_interface_t *) p_desc; + } + TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0); + TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0); + } + + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, 0); + + TU_LOG_DRV("MIDI2 opening Interface %u Alt %u (addr = %u)\r\n", + desc_itf->bInterfaceNumber, desc_itf->bAlternateSetting, dev_addr); + + // Dispatch to appropriate parser based on Alt Setting + if (desc_itf->bAlternateSetting == 0) { + midih2_parse_descriptors_alt0(p_midi, desc_itf, desc_end); + } else if (desc_itf->bAlternateSetting == 1) { + midih2_parse_descriptors_alt1(p_midi, desc_itf, desc_end); + } + + return max_len; +} + +bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { + uint8_t idx = 0; + for (idx = 0; idx < CFG_TUH_MIDI2; idx++) { + if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { + break; + } + } + + if (idx >= CFG_TUH_MIDI2) { + // Not our interface (e.g. Audio Control) - pass through to next + usbh_driver_set_config_complete(dev_addr, itf_num); + return true; + } + + midih2_interface_t *p_midi = &_midi2_host[idx]; + + // Auto-select alt setting + midih2_auto_select_alt_setting(p_midi); + + // Invoke descriptor_cb + tuh_midi2_descriptor_cb_t desc_cb = { + .protocol_version = p_midi->protocol_version, + .bcdMSC_hi = p_midi->bcdMSC_hi, + .bcdMSC_lo = p_midi->bcdMSC_lo, + .rx_cable_count = (p_midi->alt_setting_current == 0) ? + p_midi->rx_cable_count_alt0 : p_midi->rx_cable_count_alt1, + .tx_cable_count = (p_midi->alt_setting_current == 0) ? + p_midi->tx_cable_count_alt0 : p_midi->tx_cable_count_alt1, + }; + tuh_midi2_descriptor_cb(idx, &desc_cb); + + // Mark as mounted + TU_LOG_DRV("MIDI2 mounted addr = %u, alt = %u, protocol = %u\r\n", + dev_addr, p_midi->alt_setting_current, p_midi->protocol_version); + p_midi->mounted = true; + + // Invoke mount_cb + tuh_midi2_mount_cb_t mount_cb = { + .daddr = p_midi->daddr, + .bInterfaceNumber = p_midi->bInterfaceNumber, + .protocol_version = p_midi->protocol_version, + .alt_setting_active = p_midi->alt_setting_current, + .rx_cable_count = desc_cb.rx_cable_count, + .tx_cable_count = desc_cb.tx_cable_count, + }; + tuh_midi2_mount_cb(idx, &mount_cb); + + // Prepare RX transfer + tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); + + // Signal USBH that configuration is complete + usbh_driver_set_config_complete(dev_addr, itf_num); + + return true; +} + +void midih2_close(uint8_t dev_addr) { + for (uint8_t idx = 0; idx < CFG_TUH_MIDI2; idx++) { + midih2_interface_t *p_midi = &_midi2_host[idx]; + if (p_midi->daddr == dev_addr) { + TU_LOG_DRV(" MIDI2 close addr = %u index = %u\r\n", dev_addr, idx); + tu_edpt_stream_close(&p_midi->ep_stream.rx); + tu_edpt_stream_close(&p_midi->ep_stream.tx); + tuh_midi2_umount_cb(idx); + tu_memclr(p_midi, sizeof(midih2_interface_t)); + } + } +} + +bool midih2_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + uint8_t idx = get_idx_by_ep_addr(dev_addr, ep_addr); + TU_VERIFY(idx < CFG_TUH_MIDI2); + + midih2_interface_t *p_midi = &_midi2_host[idx]; + + if (ep_addr == p_midi->ep_stream.rx.ep_addr) { + if (result == XFER_RESULT_SUCCESS && xferred_bytes > 0) { + tu_edpt_stream_read_xfer_complete(&p_midi->ep_stream.rx, xferred_bytes); + tuh_midi2_rx_cb(idx, xferred_bytes); + } + tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); + } else if (ep_addr == p_midi->ep_stream.tx.ep_addr) { + tuh_midi2_tx_cb(idx, xferred_bytes); + if (0 == tu_edpt_stream_write_xfer(&p_midi->ep_stream.tx)) { + tu_edpt_stream_write_zlp_if_needed(&p_midi->ep_stream.tx, xferred_bytes); + } + } + + return true; +} + +//--------------------------------------------------------------------+ +// Public API +//--------------------------------------------------------------------+ + +bool tuh_midi2_mounted(uint8_t idx) { + TU_VERIFY(idx < CFG_TUH_MIDI2); + return _midi2_host[idx].mounted; +} + +uint8_t tuh_midi2_get_protocol_version(uint8_t idx) { + TU_VERIFY(idx < CFG_TUH_MIDI2); + return _midi2_host[idx].protocol_version; +} + +uint8_t tuh_midi2_get_alt_setting_active(uint8_t idx) { + TU_VERIFY(idx < CFG_TUH_MIDI2); + return _midi2_host[idx].alt_setting_current; +} + +uint8_t tuh_midi2_get_cable_count(uint8_t idx) { + TU_VERIFY(idx < CFG_TUH_MIDI2); + return (_midi2_host[idx].alt_setting_current == 0) ? + _midi2_host[idx].rx_cable_count_alt0 : _midi2_host[idx].rx_cable_count_alt1; +} + +uint32_t tuh_midi2_ump_read(uint8_t idx, uint32_t* words, uint32_t max_words) { + TU_VERIFY(idx < CFG_TUH_MIDI2 && words && max_words); + + midih2_interface_t *p_midi = &_midi2_host[idx]; + tu_edpt_stream_t *ep_rx = &p_midi->ep_stream.rx; + + uint32_t n_words = 0; + for (uint32_t i = 0; i < max_words; i++) { + if (tu_edpt_stream_read_available(ep_rx) >= 4) { + tu_edpt_stream_read(ep_rx, (uint8_t *) &words[i], 4); + n_words++; + } else { + break; + } + } + + return n_words; +} + +uint32_t tuh_midi2_ump_write(uint8_t idx, const uint32_t* words, uint32_t count) { + TU_VERIFY(idx < CFG_TUH_MIDI2 && words && count); + + midih2_interface_t *p_midi = &_midi2_host[idx]; + tu_edpt_stream_t *ep_tx = &p_midi->ep_stream.tx; + + uint32_t n_words = 0; + for (uint32_t i = 0; i < count; i++) { + if (tu_edpt_stream_write_available(ep_tx) >= 4) { + tu_edpt_stream_write(ep_tx, (const uint8_t *) &words[i], 4); + n_words++; + } else { + break; + } + } + + return n_words; +} + +uint32_t tuh_midi2_write_flush(uint8_t idx) { + TU_VERIFY(idx < CFG_TUH_MIDI2); + + midih2_interface_t *p_midi = &_midi2_host[idx]; + tu_edpt_stream_t *ep_tx = &p_midi->ep_stream.tx; + + return tu_edpt_stream_write_xfer(ep_tx); +} + +#endif // CFG_TUH_ENABLED && CFG_TUH_MIDI2 diff --git a/src/class/midi/midi2_host.h b/src/class/midi/midi2_host.h new file mode 100644 index 000000000..d2de55270 --- /dev/null +++ b/src/class/midi/midi2_host.h @@ -0,0 +1,99 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Saulo Verissimo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_MIDI2_HOST_H_ +#define TUSB_MIDI2_HOST_H_ + +#include "class/audio/audio.h" +#include "midi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Callback Type Definitions +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t protocol_version; // 0 = MIDI 1.0 only, 1 = MIDI 2.0 + uint8_t bcdMSC_hi, bcdMSC_lo; // MIDI version from descriptor + uint8_t rx_cable_count; // For both alt settings (same for Alt 0 and Alt 1) + uint8_t tx_cable_count; +} tuh_midi2_descriptor_cb_t; + +typedef struct { + uint8_t daddr; + uint8_t bInterfaceNumber; + uint8_t protocol_version; // 0 = MIDI 1.0, 1 = MIDI 2.0 + uint8_t alt_setting_active; // 0 or 1 + uint8_t rx_cable_count; + uint8_t tx_cable_count; +} tuh_midi2_mount_cb_t; + +//--------------------------------------------------------------------+ +// Application Callback API (weak, optional) +//--------------------------------------------------------------------+ + +void tuh_midi2_descriptor_cb(uint8_t idx, const tuh_midi2_descriptor_cb_t *desc_cb_data); +void tuh_midi2_mount_cb(uint8_t idx, const tuh_midi2_mount_cb_t *mount_cb_data); +void tuh_midi2_rx_cb(uint8_t idx, uint32_t xferred_bytes); +void tuh_midi2_tx_cb(uint8_t idx, uint32_t xferred_bytes); +void tuh_midi2_umount_cb(uint8_t idx); + +//--------------------------------------------------------------------+ +// Application API - Query +//--------------------------------------------------------------------+ + +bool tuh_midi2_mounted(uint8_t idx); +uint8_t tuh_midi2_get_protocol_version(uint8_t idx); +uint8_t tuh_midi2_get_alt_setting_active(uint8_t idx); +uint8_t tuh_midi2_get_cable_count(uint8_t idx); + +//--------------------------------------------------------------------+ +// Application API - I/O +//--------------------------------------------------------------------+ + +uint32_t tuh_midi2_ump_read(uint8_t idx, uint32_t* words, uint32_t max_words); +uint32_t tuh_midi2_ump_write(uint8_t idx, const uint32_t* words, uint32_t count); +uint32_t tuh_midi2_write_flush(uint8_t idx); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ + +bool midih2_init(void); +bool midih2_deinit(void); +bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num); +void midih2_close(uint8_t dev_addr); +uint16_t midih2_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len); +bool midih2_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 490724b02..2e3c93c5e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -278,6 +278,18 @@ static usbh_class_driver_t const usbh_class_drivers[] = { }, #endif + #if CFG_TUH_MIDI2 + { + .name = DRIVER_NAME("MIDI2"), + .init = midih2_init, + .deinit = midih2_deinit, + .open = midih2_open, + .set_config = midih2_set_config, + .xfer_cb = midih2_xfer_cb, + .close = midih2_close + }, + #endif + #if CFG_TUH_HUB { .name = DRIVER_NAME("HUB"), -- cgit v1.3.1 From fa9edeff9c00ee1fc4ee7ab9938b1a5955a6281a Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Wed, 25 Mar 2026 07:05:56 -0300 Subject: fix: address PR review feedback for MIDI 2.0 drivers Host driver (midi2_host.c): - midih2_open() now returns actual parsed length instead of max_len, preventing composite device interface conflicts - Parsers (alt0/alt1) refactored to return const uint8_t* end pointer following midi_host.c switch/case pattern - Alt 1 CS Endpoint now parses MIDI 2.0 layout (bNumGrpTrmBlk at offset 3 with MIDI_CS_ENDPOINT_GENERAL_2_0 subtype check) instead of reusing MIDI 1.0 struct (bNumEmbMIDIJack) - midih2_set_config() now issues SET_INTERFACE control request via tuh_interface_set() before completing configuration. Falls back to alt 0 if SET_INTERFACE fails - Extracted midih2_set_config_complete() and midih2_set_interface_cb() for async SET_INTERFACE handling Device driver (midi2_device.c): - midi2d_open() skip loop now checks bInterfaceNumber, stopping at interfaces that belong to other functions in composite devices - SET_INTERFACE handler now rejects alt > 1 (returns false/stall) - Named constants for GTB descriptor types and MIDI protocol values Descriptor macros (usbd.h): - TUD_MIDI2_DESC_ALT1_HEAD: iInterface set to 0 (consistent with Alt 0), wTotalLength now uses TUD_MIDI2_DESC_ALT1_CS_LEN to cover all Alt 1 class-specific descriptors - TUD_MIDI2_DESC_ALT1_EP: now accepts GTB ID list via variadic args, emitting complete CS endpoint descriptor Host example: - CMakeLists.txt restricted to rp2040 family (display.c requires Pico SDK headers) - display.c: null terminator after strncpy in log scroll Documentation: - class_drivers.rst updated to reflect SET_INTERFACE behavior and auto-select with fallback Addresses: Codex P1 (#1, #2, #3), Copilot (#4-#9) --- docs/reference/class_drivers.rst | 8 +- examples/host/midi2_host/CMakeLists.txt | 3 +- examples/host/midi2_host/src/display.c | 1 + src/class/midi/midi2_device.c | 14 ++- src/class/midi/midi2_host.c | 213 ++++++++++++++++++++------------ src/device/usbd.h | 24 ++-- 6 files changed, 166 insertions(+), 97 deletions(-) (limited to 'src/class/midi') diff --git a/docs/reference/class_drivers.rst b/docs/reference/class_drivers.rst index 9ed332acb..3ac0d8d4e 100644 --- a/docs/reference/class_drivers.rst +++ b/docs/reference/class_drivers.rst @@ -87,7 +87,7 @@ The MIDI 2.0 Host driver enables TinyUSB to enumerate and communicate with USB M **Key Features:** - **Reactive Architecture**: Auto-detects Alt Setting 1 (MIDI 2.0) capability during enumeration -- **Auto-Selection**: Automatically selects the highest available protocol (MIDI 2.0 preferred) +- **Auto-Selection**: Automatically selects the highest available protocol and issues SET_INTERFACE to activate Alt Setting 1 when MIDI 2.0 is detected - **Transparent Stream Messages**: All data (UMP packets + Stream Messages) flow through callbacks - **Memory Safe**: No dynamic allocation, fixed-size instances per device @@ -271,9 +271,9 @@ Architecture The MIDI 2.0 Host driver uses a **reactive, callback-driven architecture** that mirrors the proven patterns in TinyUSB's existing device drivers (CDC, HID, etc.): - **Auto-Detection**: Host automatically detects Alt Setting 1 capability -- **Auto-Selection**: Selects highest protocol available (MIDI 2.0 preferred) -- **Application Control**: App makes protocol behavior decisions via callbacks -- **Transparent I/O**: Stream Messages and UMP packets flow transparently +- **Auto-Selection**: Selects highest protocol available and issues SET_INTERFACE +- **Transparent I/O**: Stream Messages and UMP packets flow through callbacks +- **Callback-Driven**: App receives events via callbacks (descriptor, mount, rx, tx, unmount) Differences from MIDI 1.0 Host ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/host/midi2_host/CMakeLists.txt b/examples/host/midi2_host/CMakeLists.txt index 221de7adf..cd70d122a 100644 --- a/examples/host/midi2_host/CMakeLists.txt +++ b/examples/host/midi2_host/CMakeLists.txt @@ -6,7 +6,8 @@ project(midi2_host C CXX ASM) family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) -if(FAMILY STREQUAL "espressif") +# This example requires PIO-USB and Pico SDK (I2C, SSD1306 display) +if(NOT FAMILY STREQUAL "rp2040") return() endif() diff --git a/examples/host/midi2_host/src/display.c b/examples/host/midi2_host/src/display.c index 6d81bcd5c..4745c2961 100644 --- a/examples/host/midi2_host/src/display.c +++ b/examples/host/midi2_host/src/display.c @@ -190,6 +190,7 @@ void display_log(const char* text, uint16_t color) { if (log_count >= LOG_LINES) { for (int i = 0; i < LOG_LINES - 1; i++) { strncpy(log_lines[i], log_lines[i + 1], CHARS_PER_LINE); + log_lines[i][CHARS_PER_LINE] = '\0'; } log_count = LOG_LINES - 1; } diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 9363aac11..aecbda4c5 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -505,12 +505,19 @@ uint16_t midi2d_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint } // Skip remaining descriptors (alt setting 1, CS endpoints, GTB) + // Stop at any interface descriptor that is not our MIDI Streaming alt setting while (tu_desc_in_bounds(p_desc, desc_end)) { uint8_t dtype = tu_desc_type(p_desc); - if (dtype != TUSB_DESC_CS_INTERFACE && dtype != TUSB_DESC_CS_ENDPOINT && - dtype != TUSB_DESC_INTERFACE && dtype != TUSB_DESC_ENDPOINT) { + + if (dtype == TUSB_DESC_INTERFACE) { + const tusb_desc_interface_t* next_itf = (const tusb_desc_interface_t*) p_desc; + // Continue only if this is an alternate setting of our own interface + if (next_itf->bInterfaceNumber != desc_midi->bInterfaceNumber) break; + } else if (dtype != TUSB_DESC_CS_INTERFACE && dtype != TUSB_DESC_CS_ENDPOINT && + dtype != TUSB_DESC_ENDPOINT) { break; } + p_desc = tu_desc_next(p_desc); } @@ -528,6 +535,9 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re uint8_t itf_num = tu_u16_low(request->wIndex); uint8_t alt = tu_u16_low(request->wValue); + // Only Alt Setting 0 (MIDI 1.0) and 1 (UMP) are valid + if (alt > 1) return false; + uint8_t idx = find_midi2_itf_by_num(itf_num); if (idx >= CFG_TUD_MIDI2) return false; diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c index beb441b56..5b9f98f8b 100644 --- a/src/class/midi/midi2_host.c +++ b/src/class/midi/midi2_host.c @@ -125,9 +125,10 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { // Descriptor parsing //--------------------------------------------------------------------+ -static void midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, +// Parse Alt Setting 0 (MIDI 1.0) descriptors. Returns pointer past last consumed descriptor. +static const uint8_t* midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, const tusb_desc_interface_t *desc_itf, const uint8_t *desc_end) { - TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass,); + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, NULL); p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber; @@ -136,93 +137,113 @@ static void midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, uint8_t rx_cable_count = 0; uint8_t tx_cable_count = 0; + bool found_new_interface = false; - while (tu_desc_in_bounds(p_desc, desc_end)) { - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { - break; - } - - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { - const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; - - // Open endpoint and stream - TU_ASSERT(tuh_edpt_open(p_midi->daddr, p_ep),); - if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_midi->ep_stream.rx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); - tu_edpt_stream_clear(&p_midi->ep_stream.rx); - } else { - tu_edpt_stream_open(&p_midi->ep_stream.tx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); - } - - p_desc = tu_desc_next(p_desc); + while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) { + switch (tu_desc_type(p_desc)) { + case TUSB_DESC_INTERFACE: + found_new_interface = true; + break; - if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { - const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; + case TUSB_DESC_ENDPOINT: { + const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; - if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { - tx_cable_count = p_csep->bNumEmbMIDIJack; + TU_ASSERT(tuh_edpt_open(p_midi->daddr, p_ep), NULL); + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p_midi->ep_stream.rx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.rx); } else { - rx_cable_count = p_csep->bNumEmbMIDIJack; + tu_edpt_stream_open(&p_midi->ep_stream.tx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + } + + p_desc = tu_desc_next(p_desc); + if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { + const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { + tx_cable_count = p_csep->bNumEmbMIDIJack; + } else { + rx_cable_count = p_csep->bNumEmbMIDIJack; + } } + break; } + + default: + break; } - p_desc = tu_desc_next(p_desc); + if (!found_new_interface) { + p_desc = tu_desc_next(p_desc); + } } p_midi->rx_cable_count_alt0 = rx_cable_count; p_midi->tx_cable_count_alt0 = tx_cable_count; + return p_desc; } -static void midih2_parse_descriptors_alt1(midih2_interface_t *p_midi, +// Parse Alt Setting 1 (MIDI 2.0 UMP) descriptors. Returns pointer past last consumed descriptor. +static const uint8_t* midih2_parse_descriptors_alt1(midih2_interface_t *p_midi, const tusb_desc_interface_t *desc_itf, const uint8_t *desc_end) { - TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass,); - TU_VERIFY(desc_itf->bAlternateSetting == 1,); + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, NULL); + TU_VERIFY(desc_itf->bAlternateSetting == 1, NULL); const uint8_t *p_desc = (const uint8_t *) desc_itf; p_desc = tu_desc_next(p_desc); uint8_t rx_cable_count = 0; uint8_t tx_cable_count = 0; + bool found_new_interface = false; - while (tu_desc_in_bounds(p_desc, desc_end)) { - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { - break; - } + while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) { + switch (tu_desc_type(p_desc)) { + case TUSB_DESC_INTERFACE: + found_new_interface = true; + break; - if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE) { - if (tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_HEADER) { - const uint8_t *bcd_ptr = p_desc + 3; - p_midi->bcdMSC_lo = bcd_ptr[0]; - p_midi->bcdMSC_hi = bcd_ptr[1]; + case TUSB_DESC_CS_INTERFACE: + if (tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_HEADER) { + // bcdMSC at offset 3-4 in CS Interface Header + const uint8_t *bcd_ptr = p_desc + 3; + p_midi->bcdMSC_lo = bcd_ptr[0]; + p_midi->bcdMSC_hi = bcd_ptr[1]; + if (p_midi->bcdMSC_hi == 0x02) { // bcdMSC 0x0200 = USB-MIDI 2.0 + p_midi->protocol_version = 1; + } + } + break; - if (p_midi->bcdMSC_hi == 0x02) { - p_midi->protocol_version = 1; + case TUSB_DESC_ENDPOINT: { + const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + p_desc = tu_desc_next(p_desc); + + if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { + // MIDI 2.0 CS Endpoint General 2.0: bNumGrpTrmBlk at offset 3 + if (p_desc[0] >= 4 && p_desc[2] == MIDI_CS_ENDPOINT_GENERAL_2_0) { + uint8_t num_grp_trm_blk = p_desc[3]; + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { + tx_cable_count = num_grp_trm_blk; + } else { + rx_cable_count = num_grp_trm_blk; + } + } } + break; } + + default: + break; } - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { - const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + if (!found_new_interface) { p_desc = tu_desc_next(p_desc); - - if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { - const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; - - if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { - tx_cable_count = p_csep->bNumEmbMIDIJack; - } else { - rx_cable_count = p_csep->bNumEmbMIDIJack; - } - } } - - p_desc = tu_desc_next(p_desc); } p_midi->rx_cable_count_alt1 = rx_cable_count; p_midi->tx_cable_count_alt1 = tx_cable_count; + return p_desc; } //--------------------------------------------------------------------+ @@ -327,33 +348,20 @@ uint16_t midih2_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface desc_itf->bInterfaceNumber, desc_itf->bAlternateSetting, dev_addr); // Dispatch to appropriate parser based on Alt Setting + const uint8_t *p_end = NULL; if (desc_itf->bAlternateSetting == 0) { - midih2_parse_descriptors_alt0(p_midi, desc_itf, desc_end); + p_end = midih2_parse_descriptors_alt0(p_midi, desc_itf, desc_end); } else if (desc_itf->bAlternateSetting == 1) { - midih2_parse_descriptors_alt1(p_midi, desc_itf, desc_end); + p_end = midih2_parse_descriptors_alt1(p_midi, desc_itf, desc_end); } - return max_len; + // Return number of bytes consumed (following midi_host.c pattern) + uint16_t const parsed_len = (p_end != NULL) ? (uint16_t)(p_end - desc_start) : 0; + return parsed_len; } -bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { - uint8_t idx = 0; - for (idx = 0; idx < CFG_TUH_MIDI2; idx++) { - if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { - break; - } - } - - if (idx >= CFG_TUH_MIDI2) { - // Not our interface (e.g. Audio Control) - pass through to next - usbh_driver_set_config_complete(dev_addr, itf_num); - return true; - } - - midih2_interface_t *p_midi = &_midi2_host[idx]; - - // Auto-select alt setting - midih2_auto_select_alt_setting(p_midi); +static void midih2_set_config_complete(midih2_interface_t *p_midi, uint8_t idx) { + uint8_t dev_addr = p_midi->daddr; // Invoke descriptor_cb tuh_midi2_descriptor_cb_t desc_cb = { @@ -374,7 +382,7 @@ bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { // Invoke mount_cb tuh_midi2_mount_cb_t mount_cb = { - .daddr = p_midi->daddr, + .daddr = dev_addr, .bInterfaceNumber = p_midi->bInterfaceNumber, .protocol_version = p_midi->protocol_version, .alt_setting_active = p_midi->alt_setting_current, @@ -387,7 +395,56 @@ bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); // Signal USBH that configuration is complete - usbh_driver_set_config_complete(dev_addr, itf_num); + usbh_driver_set_config_complete(dev_addr, p_midi->bInterfaceNumber); +} + +static void midih2_set_interface_cb(tuh_xfer_t *xfer) { + uint8_t const dev_addr = xfer->daddr; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + + // Find our interface + for (uint8_t idx = 0; idx < CFG_TUH_MIDI2; idx++) { + if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { + if (xfer->result == XFER_RESULT_SUCCESS) { + midih2_set_config_complete(&_midi2_host[idx], idx); + } else { + // SET_INTERFACE failed, fall back to alt 0 + TU_LOG_DRV("MIDI2 SET_INTERFACE failed, falling back to alt 0\r\n"); + _midi2_host[idx].alt_setting_current = 0; + midih2_set_config_complete(&_midi2_host[idx], idx); + } + return; + } + } +} + +bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { + uint8_t idx = 0; + for (idx = 0; idx < CFG_TUH_MIDI2; idx++) { + if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { + break; + } + } + + if (idx >= CFG_TUH_MIDI2) { + // Not our interface (e.g. Audio Control) - pass through to next + usbh_driver_set_config_complete(dev_addr, itf_num); + return true; + } + + midih2_interface_t *p_midi = &_midi2_host[idx]; + + // Auto-select alt setting + midih2_auto_select_alt_setting(p_midi); + + // If MIDI 2.0 detected, issue SET_INTERFACE to activate Alt Setting 1 + if (p_midi->alt_setting_current == 1) { + TU_LOG_DRV("MIDI2 requesting SET_INTERFACE alt 1 for itf %u\r\n", itf_num); + TU_ASSERT(tuh_interface_set(dev_addr, itf_num, 1, midih2_set_interface_cb, 0)); + } else { + // MIDI 1.0 only, complete immediately + midih2_set_config_complete(p_midi, idx); + } return true; } diff --git a/src/device/usbd.h b/src/device/usbd.h index af37eff56..a9f4c5f08 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -429,18 +429,20 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ //--------------------------------------------------------------------+ // Alt Setting 1: MS Interface + MS Header (bcdMSC=0x0200) +// wTotalLength covers MS Header + all CS Endpoint descriptors +#define TUD_MIDI2_DESC_ALT1_CS_LEN(_numgtbs) (7 + (4 + (_numgtbs)) * 2) #define TUD_MIDI2_DESC_ALT1_HEAD_LEN (9 + 7) -#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx) \ +#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx, _numgtbs) \ /* MIDI Streaming Interface, Alt Setting 1 */\ - 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 1, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, _stridx,\ - /* MS Header (MIDI 2.0) */\ - 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(7) + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 1, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, 0,\ + /* MS Header (MIDI 2.0): wTotalLength = header + 2x CS Endpoint */\ + 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(TUD_MIDI2_DESC_ALT1_CS_LEN(_numgtbs)) -// Alt Setting 1: Standard USB Endpoint (7 bytes) + CS Endpoint (subtype 0x02) +// Alt Setting 1: Standard USB Endpoint (7 bytes) + CS Endpoint General 2.0 #define TUD_MIDI2_DESC_ALT1_EP_LEN(_numgtbs) (7 + 4 + (_numgtbs)) -#define TUD_MIDI2_DESC_ALT1_EP(_ep, _epsize, _numgtbs) \ +#define TUD_MIDI2_DESC_ALT1_EP(_ep, _epsize, _numgtbs, ...) \ 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, \ - (uint8_t)(4 + (_numgtbs)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL_2_0, _numgtbs + (uint8_t)(4 + (_numgtbs)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL_2_0, _numgtbs, ## __VA_ARGS__ // Total length: Alt 0 (MIDI 1.0) + Alt 1 (UMP) #define TUD_MIDI2_DESC_LEN (TUD_MIDI_DESC_LEN + TUD_MIDI2_DESC_ALT1_HEAD_LEN + TUD_MIDI2_DESC_ALT1_EP_LEN(1) * 2) @@ -455,11 +457,9 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ TUD_MIDI_JACKID_OUT_EMB(1),\ /* Alt Setting 1 (UMP) */\ - TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx),\ - TUD_MIDI2_DESC_ALT1_EP(_epout, _epsize, 1),\ - 1, /* bAssoGrpTrmBlkID = 1 */\ - TUD_MIDI2_DESC_ALT1_EP(_epin, _epsize, 1),\ - 1 /* bAssoGrpTrmBlkID = 1 */ + TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx, 1),\ + TUD_MIDI2_DESC_ALT1_EP(_epout, _epsize, 1, 1 /* bAssoGrpTrmBlkID */),\ + TUD_MIDI2_DESC_ALT1_EP(_epin, _epsize, 1, 1 /* bAssoGrpTrmBlkID */) //--------------------------------------------------------------------+ // Audio Descriptor Templates -- cgit v1.3.1 From f8a5fc37f3472cb2e3eb584d58e9cf4588dc4329 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Wed, 25 Mar 2026 07:29:10 -0300 Subject: fix: CI build failures on non-RP2040 platforms - Use UINT32_C(1) instead of 1u for bit shifts >= 16 in midi2_device.c to avoid shift-count-overflow on 16-bit platforms (MSP430) - Add Makefiles for midi2_device and midi2_host examples with family guard (skip if FAMILY != rp2040). These examples require Pico SDK and board-specific hardware - Restrict midi2_device CMakeLists.txt to rp2040 family (matching midi2_host) --- examples/device/midi2_device/CMakeLists.txt | 4 ++-- examples/device/midi2_device/Makefile | 27 +++++++++++++++++++++++++++ examples/host/midi2_host/Makefile | 27 +++++++++++++++++++++++++++ src/class/midi/midi2_device.c | 8 ++++---- 4 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 examples/device/midi2_device/Makefile create mode 100644 examples/host/midi2_host/Makefile (limited to 'src/class/midi') diff --git a/examples/device/midi2_device/CMakeLists.txt b/examples/device/midi2_device/CMakeLists.txt index 295af6550..3f4a876c9 100644 --- a/examples/device/midi2_device/CMakeLists.txt +++ b/examples/device/midi2_device/CMakeLists.txt @@ -7,8 +7,8 @@ project(midi2_device C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) -# Espressif has its own cmake build system -if(FAMILY STREQUAL "espressif") +# This example requires RP2040/RP2350 (USB descriptors and config are board-specific) +if(NOT FAMILY STREQUAL "rp2040") return() endif() diff --git a/examples/device/midi2_device/Makefile b/examples/device/midi2_device/Makefile new file mode 100644 index 000000000..09f069c4f --- /dev/null +++ b/examples/device/midi2_device/Makefile @@ -0,0 +1,27 @@ +# This example requires RP2040/RP2350 (USB descriptors and config are board-specific) +ifeq (,$(findstring rp2040,$(FAMILY))) +$(info Skipping midi2_device: requires FAMILY=rp2040) +all: + @: +.DEFAULT: + @: +else + +include ../../../hw/bsp/family_support.mk + +INC += \ + src \ + +# Example source +EXAMPLE_SOURCE += \ + src/main.c \ + src/usb_descriptors.c \ + +SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) + +# Suppress pre-existing warning in usbd.c +CFLAGS_GCC += -Wno-type-limits + +include ../../../hw/bsp/family_rules.mk + +endif diff --git a/examples/host/midi2_host/Makefile b/examples/host/midi2_host/Makefile new file mode 100644 index 000000000..2b4660516 --- /dev/null +++ b/examples/host/midi2_host/Makefile @@ -0,0 +1,27 @@ +# This example requires RP2040/RP2350 (PIO-USB, Pico SDK I2C, SSD1306 display) +ifeq (,$(findstring rp2040,$(FAMILY))) +$(info Skipping midi2_host: requires FAMILY=rp2040) +all: + @: +.DEFAULT: + @: +else + +include ../../../hw/bsp/family_support.mk + +INC += \ + src \ + +# Example source +EXAMPLE_SOURCE += \ + src/main.c \ + src/display.c \ + +SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) + +# Suppress pre-existing warning +CFLAGS_GCC += -Wno-type-limits + +include ../../../hw/bsp/family_rules.mk + +endif diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index aecbda4c5..0029737ce 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -158,10 +158,10 @@ static void _nego_send_endpoint_info(midi2d_interface_t* p_midi) { | ((uint32_t) STREAM_ENDPOINT_INFO << 16) | ((uint32_t) UMP_VER_MAJOR << 8) | (uint32_t) UMP_VER_MINOR; - msg[1] = (1u << 31) // Static Function Blocks flag + msg[1] = (UINT32_C(1) << 31) // Static Function Blocks flag | ((uint32_t)(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS & 0x7F) << 24) - | (1u << 9) // MIDI 2.0 Protocol capability - | (1u << 8); // MIDI 1.0 Protocol capability + | (UINT32_C(1) << 9) // MIDI 2.0 Protocol capability + | (UINT32_C(1) << 8); // MIDI 1.0 Protocol capability _nego_send_ump(p_midi, msg, 4); } @@ -214,7 +214,7 @@ static void _nego_send_fb_info(midi2d_interface_t* p_midi, uint8_t fb_idx) { uint32_t msg[4] = {0}; msg[0] = ((uint32_t) MT_STREAM << 28) | ((uint32_t) STREAM_FB_INFO << 16) - | (1u << 15) + | (UINT32_C(1) << 15) | ((uint32_t) fb_idx << 8) | 0x02; // bDirection: bidirectional msg[1] = ((uint32_t) 0 << 24) // bFirstGroup -- cgit v1.3.1 From 0c68ca8c1de45e24ae022ab58934c6930bad7b4b Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Tue, 21 Apr 2026 20:42:24 -0300 Subject: midi2: align ep_buf allocation with other stream-based classes Keep the MIDI 2.0 drivers fully self-contained, with no changes to shared or generic stack code. Allocate the per-endpoint buffer in both midi2_host and midi2_device, following the convention used by cdc, midi, vendor, and printer. The class buffer struct is declared unconditionally and passed to tu_edpt_stream_init on every init, so the streaming helpers operate on the same shape across all classes. --- src/class/midi/midi2_device.c | 7 ------- src/class/midi/midi2_host.c | 7 ------- 2 files changed, 14 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 0029737ce..34e467fc6 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -110,14 +110,12 @@ TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUN static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; -#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUD_EPBUF_DEF(epin, CFG_TUD_MIDI2_TX_EPSIZE); TUD_EPBUF_DEF(epout, CFG_TUD_MIDI2_RX_EPSIZE); } midi2d_epbuf_t; CFG_TUD_MEM_SECTION static midi2d_epbuf_t _midi2d_epbuf[CFG_TUD_MIDI2]; -#endif // Default Group Terminal Block descriptor (USB-MIDI 2.0 spec, Table 5-5/5-6) static const uint8_t _default_gtb_desc[] = { @@ -385,14 +383,9 @@ void midi2d_init(void) { midi2d_interface_t* p_midi = &_midi2d_itf[i]; p_midi->protocol = MIDI_PROTOCOL_MIDI2; - #if CFG_TUD_EDPT_DEDICATED_HWFIFO - uint8_t* epout_buf = NULL; - uint8_t* epin_buf = NULL; - #else midi2d_epbuf_t* p_epbuf = &_midi2d_epbuf[i]; uint8_t* epout_buf = p_epbuf->epout; uint8_t* epin_buf = p_epbuf->epin; - #endif tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI2_RX_BUFSIZE, epout_buf); diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c index 5b9f98f8b..90d632a8e 100644 --- a/src/class/midi/midi2_host.c +++ b/src/class/midi/midi2_host.c @@ -88,14 +88,12 @@ typedef struct { static midih2_interface_t _midi2_host[CFG_TUH_MIDI2]; -#if CFG_TUH_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MAX); TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MAX); } midih2_epbuf_t; CFG_TUH_MEM_SECTION static midih2_epbuf_t _midi2_epbuf[CFG_TUH_MIDI2]; -#endif //--------------------------------------------------------------------+ // Helper functions @@ -266,13 +264,8 @@ bool midih2_init(void) { for (int inst = 0; inst < CFG_TUH_MIDI2; inst++) { midih2_interface_t *p_midi = &_midi2_host[inst]; - #if CFG_TUH_EDPT_DEDICATED_HWFIFO - uint8_t* rx_buf = NULL; - uint8_t* tx_buf = NULL; - #else uint8_t* rx_buf = _midi2_epbuf[inst].rx; uint8_t* tx_buf = _midi2_epbuf[inst].tx; - #endif tu_edpt_stream_init(&p_midi->ep_stream.rx, true, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUH_MIDI2_RX_BUFSIZE, rx_buf); -- cgit v1.3.1 From 97852816e873bf7f91f3a81f093ad08f96179656 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Wed, 22 Apr 2026 18:04:56 -0300 Subject: midi2: align descriptors with USB-MIDI 2.0 spec Brings the MIDI 2.0 device driver into full conformance with USB Device Class Definition for MIDI Devices v2.0 (USB-IF, May 2020). - Alt 1 MS Interface Header wTotalLength now reports 0x0007 per Table 5-2 ("set to match bLength"), replacing the prior 0x0011 carried over from USB-MIDI 1.0 conventions. - GET_DESCRIPTOR class request now validates bmRequestType direction, type and recipient plus wIndex and wValue high byte per Section 6. - iBlockItem in the default Group Terminal Block is driven by CFG_TUD_MIDI2_BLOCK_STRIDX so applications can attach a UI string descriptor to the block per Table 5-6. - UMP word byte order assumption (little-endian host per Section 3.2.2) is documented inline so future big-endian ports know where to wrap access with tu_htole32 / tu_le32toh. Validated on RP2040 and ESP32-P4 under Linux kernel 6.17: lsusb -v reports wTotalLength = 0x0007 on Alt 1 MS Header (raw bytes 07 24 01 00 02 07 00). amidi -l enumerates Group Terminals exposed via the class-specific GET_DESCRIPTOR response. --- src/class/midi/midi2_device.c | 47 ++++++++++++++++------ src/device/usbd.h | 12 +++--- src/tusb_option.h | 6 +++ .../test/device/midi2/test_midi2_device.c | 3 ++ 4 files changed, 49 insertions(+), 19 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 34e467fc6..15daad096 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -43,6 +43,16 @@ TU_ATTR_WEAK bool tud_midi2_get_req_itf_cb(uint8_t rhport, const tusb_control_re (void) rhport; (void) request; return false; } +//--------------------------------------------------------------------+ +// Byte order note +//--------------------------------------------------------------------+ +// Per USB-MIDI 2.0 Section 3.2.2, each 32-bit UMP word is transmitted with the +// least significant byte first. This driver reads and writes UMP words as +// native uint32_t through tu_edpt_stream_read/write. All TinyUSB targets are +// little-endian, so the in-memory layout already matches the wire order and no +// swap is needed. If a big-endian target is ever supported, wrap access with +// tu_htole32 / tu_le32toh at the buffer boundary. + //--------------------------------------------------------------------+ // UMP Stream Message Constants //--------------------------------------------------------------------+ @@ -133,7 +143,7 @@ static const uint8_t _default_gtb_desc[] = { 0x00, // bGrpTrmBlkType: bidirectional 0x00, // nGroupTrm: first group (0) CFG_TUD_MIDI2_NUM_GROUPS, // nNumGroupTrm - 0, // iBlockItem: no string + CFG_TUD_MIDI2_BLOCK_STRIDX, // iBlockItem: string descriptor index (0 = none) 0x00, // bMIDIProtocol: unknown/not fixed 0, 0, // wMaxInputBandwidth: unknown 0, 0 // wMaxOutputBandwidth: unknown @@ -554,19 +564,30 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re } case TUSB_REQ_GET_DESCRIPTOR: { - // wValue: descriptor type (high) | index (low) - // 0x26 = CS_GRP_TRM_BLOCK, index 0x01 - if (request->wValue == ((uint16_t)MIDI2_CS_GRP_TRM_BLOCK << 8 | 0x01)) { - if (tud_midi2_get_req_itf_cb(rhport, request)) return true; - - uint16_t len = request->wLength; - if (len > sizeof(_default_gtb_desc)) { - len = sizeof(_default_gtb_desc); - } - tud_control_xfer(rhport, request, (void*)(uintptr_t) _default_gtb_desc, len); - return true; + // USB-MIDI 2.0 Section 6: GTB descriptor retrieval + // bmRequestType = 0x81 (Device-to-Host, Standard, Interface) + // wValue = CS_GR_TRM_BLOCK (0x26) in high byte, alt setting in low byte + // wIndex = interface number + if (request->bmRequestType_bit.direction != TUSB_DIR_IN) return false; + if (request->bmRequestType_bit.type != TUSB_REQ_TYPE_STANDARD) return false; + if (request->bmRequestType_bit.recipient != TUSB_REQ_RCPT_INTERFACE) return false; + if (tu_u16_high(request->wValue) != MIDI2_CS_GRP_TRM_BLOCK) return false; + + uint8_t itf_num = tu_u16_low(request->wIndex); + uint8_t idx = find_midi2_itf_by_num(itf_num); + if (idx >= CFG_TUD_MIDI2) return false; + + // Only Alt Setting 1 exposes Group Terminal Block descriptors. + if (tu_u16_low(request->wValue) != 0x01) return false; + + if (tud_midi2_get_req_itf_cb(rhport, request)) return true; + + uint16_t len = request->wLength; + if (len > sizeof(_default_gtb_desc)) { + len = sizeof(_default_gtb_desc); } - return false; + tud_control_xfer(rhport, request, (void*)(uintptr_t) _default_gtb_desc, len); + return true; } default: diff --git a/src/device/usbd.h b/src/device/usbd.h index a9f4c5f08..abce5a887 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -429,14 +429,14 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ //--------------------------------------------------------------------+ // Alt Setting 1: MS Interface + MS Header (bcdMSC=0x0200) -// wTotalLength covers MS Header + all CS Endpoint descriptors -#define TUD_MIDI2_DESC_ALT1_CS_LEN(_numgtbs) (7 + (4 + (_numgtbs)) * 2) +// Per USB-MIDI 2.0 Table 5-2: wTotalLength in the MS Header is not used in 2.0 +// and shall be set to match bLength (= 0x0007) for conformity with USB-MIDI 1.0. #define TUD_MIDI2_DESC_ALT1_HEAD_LEN (9 + 7) -#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx, _numgtbs) \ +#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx) \ /* MIDI Streaming Interface, Alt Setting 1 */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 1, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, 0,\ - /* MS Header (MIDI 2.0): wTotalLength = header + 2x CS Endpoint */\ - 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(TUD_MIDI2_DESC_ALT1_CS_LEN(_numgtbs)) + /* MS Header (MIDI 2.0): wTotalLength = bLength per spec */\ + 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(0x0007) // Alt Setting 1: Standard USB Endpoint (7 bytes) + CS Endpoint General 2.0 #define TUD_MIDI2_DESC_ALT1_EP_LEN(_numgtbs) (7 + 4 + (_numgtbs)) @@ -457,7 +457,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ TUD_MIDI_JACKID_OUT_EMB(1),\ /* Alt Setting 1 (UMP) */\ - TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx, 1),\ + TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx),\ TUD_MIDI2_DESC_ALT1_EP(_epout, _epsize, 1, 1 /* bAssoGrpTrmBlkID */),\ TUD_MIDI2_DESC_ALT1_EP(_epin, _epsize, 1, 1 /* bAssoGrpTrmBlkID */) diff --git a/src/tusb_option.h b/src/tusb_option.h index 4483c2200..2614110fc 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -682,6 +682,12 @@ #define CFG_TUD_MIDI2_PRODUCT_ID "TinyUSB-MIDI2" #endif +// String descriptor index for the Group Terminal Block (iBlockItem, Table 5-6). +// 0 = no string descriptor (default, spec-allowed). +#ifndef CFG_TUD_MIDI2_BLOCK_STRIDX + #define CFG_TUD_MIDI2_BLOCK_STRIDX 0 +#endif + #ifndef CFG_TUD_VENDOR #define CFG_TUD_VENDOR 0 #endif diff --git a/test/unit-test/test/device/midi2/test_midi2_device.c b/test/unit-test/test/device/midi2/test_midi2_device.c index 9d716d93b..1314c2585 100644 --- a/test/unit-test/test/device/midi2/test_midi2_device.c +++ b/test/unit-test/test/device/midi2/test_midi2_device.c @@ -147,6 +147,9 @@ void test_midi2_descriptor_bytes(void) { TEST_ASSERT_EQUAL(MIDI_CS_INTERFACE_HEADER, desc[ms2_offset + 2]); TEST_ASSERT_EQUAL(0x00, desc[ms2_offset + 3]); TEST_ASSERT_EQUAL(0x02, desc[ms2_offset + 4]); + // USB-MIDI 2.0 Table 5-2: wTotalLength shall match bLength (= 0x0007) + TEST_ASSERT_EQUAL(0x07, desc[ms2_offset + 5]); + TEST_ASSERT_EQUAL(0x00, desc[ms2_offset + 6]); } void test_midi2_descriptor_alt1_cs_endpoint_subtype(void) { -- cgit v1.3.1 From 0af0665ed65ef9574a4c3c2da83c1c502cb713de Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Sat, 16 May 2026 12:59:03 -0300 Subject: midi2: reject UMP read/write API on alt setting 0 Alt 0 carries USB-MIDI 1.0 32-bit Event Packets, not UMP words; calling the UMP API there would misinterpret the stream. Expose MIDI_PROTOCOL_MIDI1 and MIDI_PROTOCOL_MIDI2 in the public header so applications can branch on the negotiated protocol. Ref #3571 --- src/class/midi/midi2_device.c | 16 ++++++++++------ src/class/midi/midi2_device.h | 9 +++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 15daad096..f7d338ede 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -73,12 +73,6 @@ enum { STREAM_FB_INFO = 0x011, }; -// MIDI Protocol values (per USB-MIDI 2.0 spec) -enum { - MIDI_PROTOCOL_MIDI1 = 0x01, - MIDI_PROTOCOL_MIDI2 = 0x02, -}; - enum { UMP_VER_MAJOR = 1, UMP_VER_MINOR = 1, @@ -304,6 +298,11 @@ uint32_t tud_midi2_n_available(uint8_t itf) { uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words) { TU_VERIFY(itf < CFG_TUD_MIDI2 && words != NULL && max_words > 0, 0); midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + + // UMP API is only valid on Alt Setting 1 (USB-MIDI 2.0). + // Alt 0 carries USB-MIDI 1.0 32-bit Event Packets, not UMP words. + if (p_midi->alt_setting != 1) { return 0; } + tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; uint32_t total_read = 0; @@ -336,6 +335,11 @@ bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]) { uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t count) { TU_VERIFY(itf < CFG_TUD_MIDI2 && words != NULL && count > 0, 0); midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + + // UMP API is only valid on Alt Setting 1 (USB-MIDI 2.0). + // Alt 0 carries USB-MIDI 1.0 32-bit Event Packets, not UMP words. + if (p_midi->alt_setting != 1) { return 0; } + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), 0); diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index dac1f0124..8c64729c3 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -44,6 +44,15 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// MIDI Protocol Values (returned by tud_midi2_n_protocol) +//--------------------------------------------------------------------+ +// Per USB-MIDI 2.0 spec, UMP Stream Configuration messages. +enum { + MIDI_PROTOCOL_MIDI1 = 0x01, + MIDI_PROTOCOL_MIDI2 = 0x02, +}; + //--------------------------------------------------------------------+ // Application Callback API (weak, optional) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 840f3e0a628e69a2b7fb4136b2dca8ab5b350f83 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Sat, 16 May 2026 12:59:44 -0300 Subject: midi2: prevent UMP packet split across USB transfers The edpt_stream auto-flush is byte-oriented and could cut an UMP message in half when the FIFO reached wMaxPacketSize, corrupting the peer's RX context. Pre-flush whole packets before writing one that would cross the boundary on both device (tud_midi2_n_ump_write) and host (tuh_midi2_ump_write) paths. Host write also becomes packet-aware instead of word-by-word. Ref #3571 --- src/class/midi/midi2_device.c | 13 +++++++++++-- src/class/midi/midi2_host.c | 27 +++++++++++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index f7d338ede..a005c8e51 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -347,11 +347,20 @@ uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t coun while (written < count) { uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); uint8_t pkt_words = midi2_ump_word_count(mt); + uint32_t pkt_bytes = (uint32_t)pkt_words * 4; if (written + pkt_words > count) break; - if (tu_edpt_stream_write_available(ep_tx) < pkt_words * 4) break; + if (tu_edpt_stream_write_available(ep_tx) < pkt_bytes) break; + + // Flush whole packets already queued before adding one that would cross + // the wMaxPacketSize boundary. Prevents an UMP message from being split + // across two USB transfers, which would corrupt the host RX context. + uint16_t ff_count = tu_fifo_count(&ep_tx->ff); + if (ff_count > 0 && ff_count + pkt_bytes > ep_tx->mps) { + tu_edpt_stream_write_xfer(ep_tx); + } - tu_edpt_stream_write(ep_tx, &words[written], pkt_words * 4); + tu_edpt_stream_write(ep_tx, &words[written], pkt_bytes); written += pkt_words; } diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c index 90d632a8e..2046fdb67 100644 --- a/src/class/midi/midi2_host.c +++ b/src/class/midi/midi2_host.c @@ -527,17 +527,28 @@ uint32_t tuh_midi2_ump_write(uint8_t idx, const uint32_t* words, uint32_t count) midih2_interface_t *p_midi = &_midi2_host[idx]; tu_edpt_stream_t *ep_tx = &p_midi->ep_stream.tx; - uint32_t n_words = 0; - for (uint32_t i = 0; i < count; i++) { - if (tu_edpt_stream_write_available(ep_tx) >= 4) { - tu_edpt_stream_write(ep_tx, (const uint8_t *) &words[i], 4); - n_words++; - } else { - break; + uint32_t written = 0; + while (written < count) { + uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint32_t pkt_bytes = (uint32_t)pkt_words * 4; + + if (written + pkt_words > count) break; + if (tu_edpt_stream_write_available(ep_tx) < pkt_bytes) break; + + // Flush whole packets already queued before adding one that would cross + // the wMaxPacketSize boundary. Prevents an UMP message from being split + // across two USB transfers, which would corrupt the peer RX context. + uint16_t ff_count = tu_fifo_count(&ep_tx->ff); + if (ff_count > 0 && ff_count + pkt_bytes > ep_tx->mps) { + tu_edpt_stream_write_xfer(ep_tx); } + + tu_edpt_stream_write(ep_tx, (const uint8_t *) &words[written], pkt_bytes); + written += pkt_words; } - return n_words; + return written; } uint32_t tuh_midi2_write_flush(uint8_t idx) { -- cgit v1.3.1 From 3f209e2a00538726992ba908fe905213c78a9f6e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 17 May 2026 14:11:53 +0200 Subject: midi2: move config to class header Signed-off-by: HiFiPhile --- src/class/midi/midi2_device.h | 43 +++++++++++++++++++++++++++++++++++++++++++ src/tusb_option.h | 38 -------------------------------------- 2 files changed, 43 insertions(+), 38 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index 8c64729c3..b7caf97a3 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -44,9 +44,52 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Class Driver Configuration +//--------------------------------------------------------------------+ + +#ifndef CFG_TUD_MIDI2_TX_BUFSIZE + #define CFG_TUD_MIDI2_TX_BUFSIZE TUD_EPSIZE_BULK_MAX +#endif + +#ifndef CFG_TUD_MIDI2_RX_BUFSIZE + #define CFG_TUD_MIDI2_RX_BUFSIZE TUD_EPSIZE_BULK_MAX +#endif + +#ifndef CFG_TUD_MIDI2_TX_EPSIZE + #define CFG_TUD_MIDI2_TX_EPSIZE TUD_EPSIZE_BULK_MAX +#endif + +#ifndef CFG_TUD_MIDI2_RX_EPSIZE + #define CFG_TUD_MIDI2_RX_EPSIZE TUD_EPSIZE_BULK_MAX +#endif + +#ifndef CFG_TUD_MIDI2_NUM_GROUPS + #define CFG_TUD_MIDI2_NUM_GROUPS 1 +#endif + +#ifndef CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS + #define CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS 1 +#endif + +#ifndef CFG_TUD_MIDI2_EP_NAME + #define CFG_TUD_MIDI2_EP_NAME "TinyUSB MIDI 2.0" +#endif + +#ifndef CFG_TUD_MIDI2_PRODUCT_ID + #define CFG_TUD_MIDI2_PRODUCT_ID "TinyUSB-MIDI2" +#endif + +// String descriptor index for the Group Terminal Block (iBlockItem, Table 5-6). +// 0 = no string descriptor (default, spec-allowed). +#ifndef CFG_TUD_MIDI2_BLOCK_STRIDX + #define CFG_TUD_MIDI2_BLOCK_STRIDX 0 +#endif + //--------------------------------------------------------------------+ // MIDI Protocol Values (returned by tud_midi2_n_protocol) //--------------------------------------------------------------------+ + // Per USB-MIDI 2.0 spec, UMP Stream Configuration messages. enum { MIDI_PROTOCOL_MIDI1 = 0x01, diff --git a/src/tusb_option.h b/src/tusb_option.h index 2614110fc..0114b86ee 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -650,44 +650,6 @@ #define CFG_TUD_MIDI2 0 #endif -#ifndef CFG_TUD_MIDI2_TX_BUFSIZE - #define CFG_TUD_MIDI2_TX_BUFSIZE 256 -#endif - -#ifndef CFG_TUD_MIDI2_RX_BUFSIZE - #define CFG_TUD_MIDI2_RX_BUFSIZE 256 -#endif - -#ifndef CFG_TUD_MIDI2_TX_EPSIZE - #define CFG_TUD_MIDI2_TX_EPSIZE 64 -#endif - -#ifndef CFG_TUD_MIDI2_RX_EPSIZE - #define CFG_TUD_MIDI2_RX_EPSIZE 64 -#endif - -#ifndef CFG_TUD_MIDI2_NUM_GROUPS - #define CFG_TUD_MIDI2_NUM_GROUPS 1 -#endif - -#ifndef CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS - #define CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS 1 -#endif - -#ifndef CFG_TUD_MIDI2_EP_NAME - #define CFG_TUD_MIDI2_EP_NAME "TinyUSB MIDI 2.0" -#endif - -#ifndef CFG_TUD_MIDI2_PRODUCT_ID - #define CFG_TUD_MIDI2_PRODUCT_ID "TinyUSB-MIDI2" -#endif - -// String descriptor index for the Group Terminal Block (iBlockItem, Table 5-6). -// 0 = no string descriptor (default, spec-allowed). -#ifndef CFG_TUD_MIDI2_BLOCK_STRIDX - #define CFG_TUD_MIDI2_BLOCK_STRIDX 0 -#endif - #ifndef CFG_TUD_VENDOR #define CFG_TUD_VENDOR 0 #endif -- cgit v1.3.1 From e00ac15b7f31be28ff888a5220cbde93a61c17f4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 17 May 2026 14:35:34 +0200 Subject: midi2: use hwfifo if supported Signed-off-by: HiFiPhile --- src/class/midi/midi2_device.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index a005c8e51..360d70967 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -114,12 +114,15 @@ TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUN static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; +// Skip local EP buffer if dedicated hw FIFO is supported +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUD_EPBUF_DEF(epin, CFG_TUD_MIDI2_TX_EPSIZE); TUD_EPBUF_DEF(epout, CFG_TUD_MIDI2_RX_EPSIZE); } midi2d_epbuf_t; CFG_TUD_MEM_SECTION static midi2d_epbuf_t _midi2d_epbuf[CFG_TUD_MIDI2]; +#endif // Default Group Terminal Block descriptor (USB-MIDI 2.0 spec, Table 5-5/5-6) static const uint8_t _default_gtb_desc[] = { @@ -406,9 +409,13 @@ void midi2d_init(void) { midi2d_interface_t* p_midi = &_midi2d_itf[i]; p_midi->protocol = MIDI_PROTOCOL_MIDI2; - midi2d_epbuf_t* p_epbuf = &_midi2d_epbuf[i]; - uint8_t* epout_buf = p_epbuf->epout; - uint8_t* epin_buf = p_epbuf->epin; + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + uint8_t *epout_buf = NULL; + uint8_t *epin_buf = NULL; + #else + uint8_t *epout_buf = _midi2d_epbuf[i].epout; + uint8_t *epin_buf = _midi2d_epbuf[i].epin; + #endif tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI2_RX_BUFSIZE, epout_buf); -- cgit v1.3.1 From 5ac6346dd4980af75973e53dd130e7ee2a9af32d Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Sun, 17 May 2026 11:31:12 -0300 Subject: midi2: peek 4 bytes for MT, restore 256 buffers MT is in byte 3 of the UMP word in LE memory, not byte 0. Buffers at mps blocked RX xfer re-arm on partial packets. --- src/class/midi/midi2_device.c | 15 +++++++++------ src/class/midi/midi2_device.h | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 360d70967..48cb3d388 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -266,10 +266,12 @@ static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t* static void _nego_process_rx(midi2d_interface_t* p_midi) { tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; - uint8_t first_byte; + uint8_t word_bytes[4]; - while (tu_edpt_stream_peek(ep_rx, &first_byte)) { - uint8_t mt = (first_byte >> 4) & 0x0F; + while (tu_fifo_peek_n(&ep_rx->ff, word_bytes, 4) == 4) { + // UMP words travel LSB-first on the wire and in LE memory, so MT is in + // the high nibble of byte 3, not byte 0. + uint8_t mt = (word_bytes[3] >> 4) & 0x0F; uint8_t pkt_words = midi2_ump_word_count(mt); uint32_t pkt_bytes = (uint32_t)pkt_words * 4; @@ -310,10 +312,11 @@ uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words) uint32_t total_read = 0; while (total_read < max_words) { - uint8_t first_byte; - if (!tu_edpt_stream_peek(ep_rx, &first_byte)) break; + uint8_t word_bytes[4]; + if (tu_fifo_peek_n(&ep_rx->ff, word_bytes, 4) < 4) break; - uint8_t mt = (first_byte >> 4) & 0x0F; + // UMP words travel LSB-first; MT is the high nibble of byte 3, not byte 0. + uint8_t mt = (word_bytes[3] >> 4) & 0x0F; uint8_t pkt_words = midi2_ump_word_count(mt); if (total_read + pkt_words > max_words) break; diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index b7caf97a3..a1c51f047 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -49,11 +49,11 @@ extern "C" { //--------------------------------------------------------------------+ #ifndef CFG_TUD_MIDI2_TX_BUFSIZE - #define CFG_TUD_MIDI2_TX_BUFSIZE TUD_EPSIZE_BULK_MAX + #define CFG_TUD_MIDI2_TX_BUFSIZE 256 #endif #ifndef CFG_TUD_MIDI2_RX_BUFSIZE - #define CFG_TUD_MIDI2_RX_BUFSIZE TUD_EPSIZE_BULK_MAX + #define CFG_TUD_MIDI2_RX_BUFSIZE 256 #endif #ifndef CFG_TUD_MIDI2_TX_EPSIZE -- cgit v1.3.1 From 4b729bfb9274af44f8edfba2134893a6889cfd03 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Sun, 17 May 2026 12:19:45 -0300 Subject: midi2: per-interface weak callbacks for UMP Stream config Lets each instance return different NUM_GROUPS, NUM_FUNCTION_BLOCKS, EP_NAME and PRODUCT_ID. Defaults fall back to the macros. --- src/class/midi/midi2_device.c | 29 +++++++++++++++++++++++------ src/class/midi/midi2_device.h | 6 ++++++ 2 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 48cb3d388..534458a24 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -42,6 +42,18 @@ TU_ATTR_WEAK void tud_midi2_set_itf_cb(uint8_t itf, uint8_t alt) { (void) itf; ( TU_ATTR_WEAK bool tud_midi2_get_req_itf_cb(uint8_t rhport, const tusb_control_request_t* request) { (void) rhport; (void) request; return false; } +TU_ATTR_WEAK uint8_t tud_midi2_num_groups_cb(uint8_t itf) { + (void) itf; return CFG_TUD_MIDI2_NUM_GROUPS; +} +TU_ATTR_WEAK uint8_t tud_midi2_num_function_blocks_cb(uint8_t itf) { + (void) itf; return CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS; +} +TU_ATTR_WEAK const char* tud_midi2_ep_name_cb(uint8_t itf) { + (void) itf; return CFG_TUD_MIDI2_EP_NAME; +} +TU_ATTR_WEAK const char* tud_midi2_product_id_cb(uint8_t itf) { + (void) itf; return CFG_TUD_MIDI2_PRODUCT_ID; +} //--------------------------------------------------------------------+ // Byte order note @@ -114,6 +126,10 @@ TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUN static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; +static inline uint8_t _itf_idx(const midi2d_interface_t* p_midi) { + return (uint8_t)(p_midi - _midi2d_itf); +} + // Skip local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { @@ -164,7 +180,7 @@ static void _nego_send_endpoint_info(midi2d_interface_t* p_midi) { | ((uint32_t) UMP_VER_MAJOR << 8) | (uint32_t) UMP_VER_MINOR; msg[1] = (UINT32_C(1) << 31) // Static Function Blocks flag - | ((uint32_t)(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS & 0x7F) << 24) + | ((uint32_t)(tud_midi2_num_function_blocks_cb(_itf_idx(p_midi)) & 0x7F) << 24) | (UINT32_C(1) << 9) // MIDI 2.0 Protocol capability | (UINT32_C(1) << 8); // MIDI 1.0 Protocol capability _nego_send_ump(p_midi, msg, 4); @@ -223,7 +239,7 @@ static void _nego_send_fb_info(midi2d_interface_t* p_midi, uint8_t fb_idx) { | ((uint32_t) fb_idx << 8) | 0x02; // bDirection: bidirectional msg[1] = ((uint32_t) 0 << 24) // bFirstGroup - | ((uint32_t) CFG_TUD_MIDI2_NUM_GROUPS << 16); + | ((uint32_t) tud_midi2_num_groups_cb(_itf_idx(p_midi)) << 16); _nego_send_ump(p_midi, msg, 4); } @@ -233,8 +249,8 @@ static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t* switch (status) { case STREAM_ENDPOINT_DISCOVERY: _nego_send_endpoint_info(p_midi); - _nego_send_stream_text(p_midi, STREAM_EP_NAME, CFG_TUD_MIDI2_EP_NAME); - _nego_send_stream_text(p_midi, STREAM_PROD_INSTANCE_ID, CFG_TUD_MIDI2_PRODUCT_ID); + _nego_send_stream_text(p_midi, STREAM_EP_NAME, tud_midi2_ep_name_cb(_itf_idx(p_midi))); + _nego_send_stream_text(p_midi, STREAM_PROD_INSTANCE_ID, tud_midi2_product_id_cb(_itf_idx(p_midi))); break; case STREAM_CONFIG_REQUEST: { @@ -249,11 +265,12 @@ static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t* case STREAM_FB_DISCOVERY: { uint8_t fb_idx = (words[0] >> 8) & 0xFF; + uint8_t fb_count = tud_midi2_num_function_blocks_cb(_itf_idx(p_midi)); if (fb_idx == 0xFF) { - for (uint8_t f = 0; f < CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS; f++) { + for (uint8_t f = 0; f < fb_count; f++) { _nego_send_fb_info(p_midi, f); } - } else if (fb_idx < CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS) { + } else if (fb_idx < fb_count) { _nego_send_fb_info(p_midi, fb_idx); } break; diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index a1c51f047..cb47bdf3c 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -103,6 +103,12 @@ void tud_midi2_rx_cb(uint8_t itf); void tud_midi2_set_itf_cb(uint8_t itf, uint8_t alt); bool tud_midi2_get_req_itf_cb(uint8_t rhport, const tusb_control_request_t* request); +// Per-interface UMP Stream config (override for per-itf values). +uint8_t tud_midi2_num_groups_cb(uint8_t itf); +uint8_t tud_midi2_num_function_blocks_cb(uint8_t itf); +const char* tud_midi2_ep_name_cb(uint8_t itf); +const char* tud_midi2_product_id_cb(uint8_t itf); + //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 287096f7333aa10b6aaaf75337ccd3de9b06b95d Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Sun, 17 May 2026 13:07:21 -0300 Subject: midi2: scale device buffers with EPSIZE Match midi2_host pattern. Literal 256 underran HS endpoints (512B). --- src/class/midi/midi2_device.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index cb47bdf3c..b0bbd7572 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -48,14 +48,6 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ -#ifndef CFG_TUD_MIDI2_TX_BUFSIZE - #define CFG_TUD_MIDI2_TX_BUFSIZE 256 -#endif - -#ifndef CFG_TUD_MIDI2_RX_BUFSIZE - #define CFG_TUD_MIDI2_RX_BUFSIZE 256 -#endif - #ifndef CFG_TUD_MIDI2_TX_EPSIZE #define CFG_TUD_MIDI2_TX_EPSIZE TUD_EPSIZE_BULK_MAX #endif @@ -64,6 +56,14 @@ extern "C" { #define CFG_TUD_MIDI2_RX_EPSIZE TUD_EPSIZE_BULK_MAX #endif +#ifndef CFG_TUD_MIDI2_TX_BUFSIZE + #define CFG_TUD_MIDI2_TX_BUFSIZE (4 * CFG_TUD_MIDI2_TX_EPSIZE) +#endif + +#ifndef CFG_TUD_MIDI2_RX_BUFSIZE + #define CFG_TUD_MIDI2_RX_BUFSIZE (4 * CFG_TUD_MIDI2_RX_EPSIZE) +#endif + #ifndef CFG_TUD_MIDI2_NUM_GROUPS #define CFG_TUD_MIDI2_NUM_GROUPS 1 #endif -- cgit v1.3.1 From b31e7cdbbedec4a3286700f3ec24bb63fd7c224f Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Sun, 17 May 2026 19:56:04 -0300 Subject: midi2: drain pattern for RX FIFO Default RX/TX buffers to EPSIZE for both device and host. Document drain-in-loop on ump_read; example device callback drains until empty. --- examples/device/midi2_device/src/main.c | 8 +++++++- src/class/midi/midi2_device.h | 12 ++++++++++-- src/class/midi/midi2_host.h | 8 ++++++++ src/tusb_option.h | 4 ++-- 4 files changed, 27 insertions(+), 5 deletions(-) (limited to 'src/class/midi') diff --git a/examples/device/midi2_device/src/main.c b/examples/device/midi2_device/src/main.c index cc918e198..d5f9bae24 100644 --- a/examples/device/midi2_device/src/main.c +++ b/examples/device/midi2_device/src/main.c @@ -529,7 +529,13 @@ void send_initial_setup(void); //--------------------------------------------------------------------+ void tud_midi2_rx_cb(uint8_t itf) { - (void)itf; + // Drain the RX FIFO in a loop until empty. Leaving words in the FIFO + // across callbacks can prevent subsequent bulk OUT transfers from landing. + uint32_t words[8]; + uint32_t n; + while ((n = tud_midi2_n_ump_read(itf, words, TU_ARRAY_SIZE(words))) > 0) { + (void) n; + } } // Reset playback state and re-send setup when host switches alt setting or diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index b0bbd7572..6c29b8ddf 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -57,11 +57,11 @@ extern "C" { #endif #ifndef CFG_TUD_MIDI2_TX_BUFSIZE - #define CFG_TUD_MIDI2_TX_BUFSIZE (4 * CFG_TUD_MIDI2_TX_EPSIZE) + #define CFG_TUD_MIDI2_TX_BUFSIZE CFG_TUD_MIDI2_TX_EPSIZE #endif #ifndef CFG_TUD_MIDI2_RX_BUFSIZE - #define CFG_TUD_MIDI2_RX_BUFSIZE (4 * CFG_TUD_MIDI2_RX_EPSIZE) + #define CFG_TUD_MIDI2_RX_BUFSIZE CFG_TUD_MIDI2_RX_EPSIZE #endif #ifndef CFG_TUD_MIDI2_NUM_GROUPS @@ -119,6 +119,14 @@ uint8_t tud_midi2_n_alt_setting(uint8_t itf); bool tud_midi2_n_negotiated(uint8_t itf); uint8_t tud_midi2_n_protocol(uint8_t itf); +// Read up to max_words UMP words from the RX FIFO. Returns the number of +// words actually read (0 if FIFO is empty). +// +// NOTE: this function returns when max_words is reached or when the FIFO is +// empty, whichever comes first. Applications should invoke it in a loop +// until it returns 0 to guarantee the RX FIFO is fully drained per +// tud_midi2_rx_cb callback. Leaving words in the FIFO across callbacks can +// prevent subsequent bulk OUT transfers from landing. uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words); uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t count); diff --git a/src/class/midi/midi2_host.h b/src/class/midi/midi2_host.h index d2de55270..47039eb85 100644 --- a/src/class/midi/midi2_host.h +++ b/src/class/midi/midi2_host.h @@ -77,6 +77,14 @@ uint8_t tuh_midi2_get_cable_count(uint8_t idx); // Application API - I/O //--------------------------------------------------------------------+ +// Read up to max_words UMP words from the RX FIFO. Returns the number of +// words actually read (0 if FIFO is empty). +// +// NOTE: this function returns when max_words is reached or when the FIFO is +// empty, whichever comes first. Applications should invoke it in a loop +// until it returns 0 to guarantee the RX FIFO is fully drained per +// tuh_midi2_rx_cb callback. Leaving words in the FIFO across callbacks can +// prevent subsequent bulk IN transfers from landing. uint32_t tuh_midi2_ump_read(uint8_t idx, uint32_t* words, uint32_t max_words); uint32_t tuh_midi2_ump_write(uint8_t idx, const uint32_t* words, uint32_t count); uint32_t tuh_midi2_write_flush(uint8_t idx); diff --git a/src/tusb_option.h b/src/tusb_option.h index 0114b86ee..74eb8cc06 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -824,11 +824,11 @@ #endif #ifndef CFG_TUH_MIDI2_RX_BUFSIZE - #define CFG_TUH_MIDI2_RX_BUFSIZE (4 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI2_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI2_TX_BUFSIZE - #define CFG_TUH_MIDI2_TX_BUFSIZE (4 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI2_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI2_LOG_LEVEL -- cgit v1.3.1 From aaca323bd34945178e88de51acf67c4d0443a726 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Mon, 18 May 2026 11:42:34 -0300 Subject: midi2: boundary-aware drain in xfer_cb to keep UMP packets intact --- src/class/midi/midi2_device.c | 51 ++++++++++++++++++++++++++++++++++++++++--- src/class/midi/midi2_host.c | 42 +++++++++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 5 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 534458a24..c61884689 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -635,6 +635,53 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re } } +// Drain whole UMP packets from the TX FIFO into the EP buffer, capped at +// wMaxPacketSize. Needed when CFG_TUD_MIDI2_TX_BUFSIZE > mps: the FIFO can +// then hold more bytes than fit in a single USB transfer, and a blind +// tu_edpt_stream_write_xfer would split a UMP across two transfers. +static void midi2d_flush_tx_boundary_aware(midi2d_interface_t* p_midi, uint32_t last_xferred) { + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + const uint16_t mps = ep_tx->mps; + const uint16_t ff_count = tu_fifo_count(&ep_tx->ff); + + if (ff_count == 0) { + (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, last_xferred); + return; + } + if (ff_count <= mps) { + // Whole FIFO fits in one transfer; the stream API drain is safe. + (void) tu_edpt_stream_write_xfer(ep_tx); + return; + } + if (ep_tx->ep_buf == NULL) { + // HWFIFO mode: relies on CFG_TUD_MIDI2_TX_BUFSIZE <= mps for UMP integrity. + (void) tu_edpt_stream_write_xfer(ep_tx); + return; + } + + // ff_count > mps and a local EP buffer is available: drain only whole UMP + // packets up to mps to preserve packet boundaries on the USB wire. + uint8_t word_bytes[4]; + uint8_t* buf = ep_tx->ep_buf; + uint16_t bytes = 0; + while (bytes < mps) { + if (tu_fifo_count(&ep_tx->ff) < 4) break; + if (4 != tu_fifo_peek_n(&ep_tx->ff, word_bytes, 4)) break; + uint8_t mt = (uint8_t)((word_bytes[3] >> 4) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); + if (tu_fifo_count(&ep_tx->ff) < pkt_bytes) break; + if (bytes + pkt_bytes > mps) break; + tu_fifo_read_n(&ep_tx->ff, buf + bytes, pkt_bytes); + bytes = (uint16_t)(bytes + pkt_bytes); + } + if (bytes == 0) return; + if (!usbd_edpt_claim(p_midi->rhport, ep_tx->ep_addr)) return; + if (!usbd_edpt_xfer(p_midi->rhport, ep_tx->ep_addr, buf, bytes, false)) { + usbd_edpt_release(p_midi->rhport, ep_tx->ep_addr); + } +} + bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) rhport; @@ -655,9 +702,7 @@ bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } tu_edpt_stream_read_xfer(ep_rx); } else if (ep_addr == ep_tx->ep_addr && result == XFER_RESULT_SUCCESS) { - if (0 == tu_edpt_stream_write_xfer(ep_tx)) { - (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, xferred_bytes); - } + midi2d_flush_tx_boundary_aware(p_midi, xferred_bytes); } else { return false; } diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c index 2046fdb67..5d77e5990 100644 --- a/src/class/midi/midi2_host.c +++ b/src/class/midi/midi2_host.c @@ -455,6 +455,44 @@ void midih2_close(uint8_t dev_addr) { } } +// Drain whole UMP packets from the TX FIFO into the EP buffer, capped at +// wMaxPacketSize. Needed when CFG_TUH_MIDI2_TX_BUFSIZE > mps to keep UMP +// packets from crossing USB transfer boundaries. +static void midih2_flush_tx_boundary_aware(midih2_interface_t* p_midi, uint32_t last_xferred) { + tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + const uint16_t mps = ep_tx->mps; + const uint16_t ff_count = tu_fifo_count(&ep_tx->ff); + + if (ff_count == 0) { + (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, last_xferred); + return; + } + if (ff_count <= mps || ep_tx->ep_buf == NULL) { + (void) tu_edpt_stream_write_xfer(ep_tx); + return; + } + + uint8_t word_bytes[4]; + uint8_t* buf = ep_tx->ep_buf; + uint16_t bytes = 0; + while (bytes < mps) { + if (tu_fifo_count(&ep_tx->ff) < 4) break; + if (4 != tu_fifo_peek_n(&ep_tx->ff, word_bytes, 4)) break; + uint8_t mt = (uint8_t)((word_bytes[3] >> 4) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); + if (tu_fifo_count(&ep_tx->ff) < pkt_bytes) break; + if (bytes + pkt_bytes > mps) break; + tu_fifo_read_n(&ep_tx->ff, buf + bytes, pkt_bytes); + bytes = (uint16_t)(bytes + pkt_bytes); + } + if (bytes == 0) return; + if (!usbh_edpt_claim(p_midi->daddr, ep_tx->ep_addr)) return; + if (!usbh_edpt_xfer(p_midi->daddr, ep_tx->ep_addr, buf, bytes)) { + usbh_edpt_release(p_midi->daddr, ep_tx->ep_addr); + } +} + bool midih2_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { uint8_t idx = get_idx_by_ep_addr(dev_addr, ep_addr); TU_VERIFY(idx < CFG_TUH_MIDI2); @@ -469,8 +507,8 @@ bool midih2_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); } else if (ep_addr == p_midi->ep_stream.tx.ep_addr) { tuh_midi2_tx_cb(idx, xferred_bytes); - if (0 == tu_edpt_stream_write_xfer(&p_midi->ep_stream.tx)) { - tu_edpt_stream_write_zlp_if_needed(&p_midi->ep_stream.tx, xferred_bytes); + if (result == XFER_RESULT_SUCCESS) { + midih2_flush_tx_boundary_aware(p_midi, xferred_bytes); } } -- cgit v1.3.1 From 4baf1883c194c2c4b6fa30cc0c443ad6c83e0b19 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 18 May 2026 23:07:49 +0200 Subject: midi2: convert to raw Tx FIFO for better segmentation handling, add count to packet api Signed-off-by: HiFiPhile --- docs/reference/class_drivers.rst | 4 +- src/class/midi/midi2_device.c | 276 +++++++++++++++++++++++---------------- src/class/midi/midi2_device.h | 14 +- 3 files changed, 176 insertions(+), 118 deletions(-) (limited to 'src/class/midi') diff --git a/docs/reference/class_drivers.rst b/docs/reference/class_drivers.rst index 3ac0d8d4e..4a101fabc 100644 --- a/docs/reference/class_drivers.rst +++ b/docs/reference/class_drivers.rst @@ -64,8 +64,8 @@ I/O Functions uint32_t tud_midi2_ump_read(uint32_t* words, uint32_t max_words); uint32_t tud_midi2_ump_write(const uint32_t* words, uint32_t count); - bool tud_midi2_packet_read(uint8_t packet[4]); - bool tud_midi2_packet_write(const uint8_t packet[4]); + uint32_t tud_midi2_packet_read(uint8_t packets[], uint32_t max_packets); + uint32_t tud_midi2_packet_write(const uint8_t packets[], uint32_t count); Callbacks ^^^^^^^^^ diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index c61884689..b14f439f8 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -100,6 +100,16 @@ enum { //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +typedef struct { + uint8_t ep_addr; + uint16_t mps; + tu_fifo_t ff; + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 + uint8_t* ep_buf; +#endif +} midi2d_tx_t; + typedef struct { uint8_t rhport; uint8_t itf_num; @@ -109,7 +119,7 @@ typedef struct { /*------------- From this point, data is not cleared by bus reset -------------*/ struct { - tu_edpt_stream_t tx; + midi2d_tx_t tx; tu_edpt_stream_t rx; uint8_t rx_ff_buf[CFG_TUD_MIDI2_RX_BUFSIZE]; @@ -117,19 +127,6 @@ typedef struct { } ep_stream; } midi2d_interface_t; -TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_GROUPS >= 1 && CFG_TUD_MIDI2_NUM_GROUPS <= 16, - "CFG_TUD_MIDI2_NUM_GROUPS must be 1..16"); -TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS <= 32, - "CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS must be 1..32"); - -#define ITF_MEM_RESET_SIZE offsetof(midi2d_interface_t, ep_stream) - -static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; - -static inline uint8_t _itf_idx(const midi2d_interface_t* p_midi) { - return (uint8_t)(p_midi - _midi2d_itf); -} - // Skip local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { @@ -140,6 +137,15 @@ typedef struct { CFG_TUD_MEM_SECTION static midi2d_epbuf_t _midi2d_epbuf[CFG_TUD_MIDI2]; #endif +TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_GROUPS >= 1 && CFG_TUD_MIDI2_NUM_GROUPS <= 16, + "CFG_TUD_MIDI2_NUM_GROUPS must be 1..16"); +TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS <= 32, + "CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS must be 1..32"); + +#define ITF_MEM_RESET_SIZE offsetof(midi2d_interface_t, ep_stream) + +static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; + // Default Group Terminal Block descriptor (USB-MIDI 2.0 spec, Table 5-5/5-6) static const uint8_t _default_gtb_desc[] = { // GTB Header (5 bytes) @@ -162,15 +168,112 @@ static const uint8_t _default_gtb_desc[] = { 0, 0 // wMaxOutputBandwidth: unknown }; +//--------------------------------------------------------------------+ +// Common utility functions +//--------------------------------------------------------------------+ + +static inline uint8_t _itf_idx(const midi2d_interface_t* p_midi) { + return (uint8_t)(p_midi - _midi2d_itf); +} + +static inline bool _tx_opened(const midi2d_interface_t* p_midi) { + return p_midi->ep_stream.tx.ep_addr != 0; +} + +static uint8_t _tx_byte_at(const tu_fifo_buffer_info_t* info, uint16_t offset) { + if (offset < info->linear.len) { + return info->linear.ptr[offset]; + } + + offset = (uint16_t) (offset - info->linear.len); + if (offset < info->wrapped.len) { + return info->wrapped.ptr[offset]; + } + + return 0; +} + +// Calculate the largest byte count that contains only whole UMP packets and +// fits in one USB transfer (<= mps). +static uint16_t _tx_nonseg_len_to_mps(midi2d_tx_t* tx) { + tu_fifo_buffer_info_t info; + tu_fifo_get_read_info(&tx->ff, &info); + + const uint16_t available = (uint16_t) (info.linear.len + info.wrapped.len); + uint16_t bytes = 0; + + while (bytes < tx->mps) { + if ((uint16_t) (available - bytes) < 4) break; + + uint8_t mt = (uint8_t)((_tx_byte_at(&info, (uint16_t) (bytes + 3)) >> 4) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t) pkt_words * 4; + + if (pkt_bytes == 0) break; + if ((uint16_t) (available - bytes) < pkt_bytes) break; + if ((uint16_t) (bytes + pkt_bytes) > tx->mps) break; + + bytes = (uint16_t) (bytes + pkt_bytes); + } + + return bytes; +} + +// Start one IN transfer capped at mps, return number of bytes queued to the controller, or 0 if nothing was queued. +static uint16_t _tx_start_xfer(midi2d_interface_t* p_midi) { + midi2d_tx_t* tx = &p_midi->ep_stream.tx; + uint16_t ff_count = tu_fifo_count(&tx->ff); + + if (ff_count == 0) return 0; + + if (!usbd_edpt_claim(p_midi->rhport, tx->ep_addr)) return 0; + + uint16_t bytes; + if (p_midi->alt_setting == 1) { + bytes = _tx_nonseg_len_to_mps(tx); + } else { + bytes = tu_min16(tu_fifo_count(&tx->ff), tx->mps); + } + if (bytes == 0) { + usbd_edpt_release(p_midi->rhport, tx->ep_addr); + return 0; + } + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO + TU_ASSERT(usbd_edpt_xfer_fifo(p_midi->rhport, tx->ep_addr, &tx->ff, bytes, false), 0); +#else + tu_fifo_read_n(&tx->ff, tx->ep_buf, bytes); + TU_ASSERT(usbd_edpt_xfer(p_midi->rhport, tx->ep_addr, tx->ep_buf, bytes, false), 0); +#endif + + return bytes; +} + +static uint32_t _tx_ump_write(midi2d_interface_t* p_midi, const uint32_t* words, uint32_t count) { + uint32_t written = 0; + while (written < count) { + uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t) pkt_words * 4; + + if (written + pkt_words > count) break; + if (tu_fifo_remaining(&p_midi->ep_stream.tx.ff) < pkt_bytes) break; + + if (tu_fifo_write_n(&p_midi->ep_stream.tx.ff, &words[written], pkt_bytes) != pkt_bytes) break; + written += pkt_words; + } + + (void) _tx_start_xfer(p_midi); + return written; +} + //--------------------------------------------------------------------+ // Protocol Negotiation //--------------------------------------------------------------------+ static void _nego_send_ump(midi2d_interface_t* p_midi, const uint32_t* words, uint8_t count) { - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - if (!tu_edpt_stream_is_opened(ep_tx)) return; - if (tu_edpt_stream_write_available(ep_tx) < count * 4) return; - tu_edpt_stream_write(ep_tx, words, count * 4); - tu_edpt_stream_write_xfer(ep_tx); + if (!_tx_opened(p_midi)) return; + if (tu_fifo_remaining(&p_midi->ep_stream.tx.ff) < (uint32_t) count * 4) return; + (void) _tx_ump_write(p_midi, words, count); } static void _nego_send_endpoint_info(midi2d_interface_t* p_midi) { @@ -307,7 +410,7 @@ static void _nego_process_rx(midi2d_interface_t* p_midi) { bool tud_midi2_n_mounted(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_MIDI2, false); midi2d_interface_t* p_midi = &_midi2d_itf[itf]; - return tu_edpt_stream_is_opened(&p_midi->ep_stream.tx) && + return _tx_opened(p_midi) && tu_edpt_stream_is_opened(&p_midi->ep_stream.rx); } @@ -346,10 +449,10 @@ uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words) return total_read; } -bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]) { - TU_VERIFY(itf < CFG_TUD_MIDI2, false); +uint32_t tud_midi2_n_packet_read(uint8_t itf, uint8_t packets[], uint32_t max_packets) { + TU_VERIFY(itf < CFG_TUD_MIDI2 && packets != NULL && max_packets > 0, 0); midi2d_interface_t* p_midi = &_midi2d_itf[itf]; - return 4 == tu_edpt_stream_read(&p_midi->ep_stream.rx, packet, 4); + return tu_edpt_stream_read(&p_midi->ep_stream.rx, packets, max_packets * 4u) >> 2u; } //--------------------------------------------------------------------+ @@ -362,44 +465,31 @@ uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t coun // UMP API is only valid on Alt Setting 1 (USB-MIDI 2.0). // Alt 0 carries USB-MIDI 1.0 32-bit Event Packets, not UMP words. if (p_midi->alt_setting != 1) { return 0; } + TU_VERIFY(_tx_opened(p_midi), 0); - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), 0); + return _tx_ump_write(p_midi, words, count); +} + +uint32_t tud_midi2_n_packet_write(uint8_t itf, const uint8_t packets[], uint32_t count) { + TU_VERIFY(itf < CFG_TUD_MIDI2 && packets != NULL && count > 0, 0); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + midi2d_tx_t* tx = &p_midi->ep_stream.tx; + + // Packet API is for Alt Setting 0 (USB-MIDI 1.0) event packets. + TU_VERIFY(p_midi->alt_setting == 0, 0); + TU_VERIFY(_tx_opened(p_midi), 0); uint32_t written = 0; while (written < count) { - uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); - uint8_t pkt_words = midi2_ump_word_count(mt); - uint32_t pkt_bytes = (uint32_t)pkt_words * 4; + if (tu_fifo_remaining(&tx->ff) < 4) break; - if (written + pkt_words > count) break; - if (tu_edpt_stream_write_available(ep_tx) < pkt_bytes) break; - - // Flush whole packets already queued before adding one that would cross - // the wMaxPacketSize boundary. Prevents an UMP message from being split - // across two USB transfers, which would corrupt the host RX context. - uint16_t ff_count = tu_fifo_count(&ep_tx->ff); - if (ff_count > 0 && ff_count + pkt_bytes > ep_tx->mps) { - tu_edpt_stream_write_xfer(ep_tx); - } - - tu_edpt_stream_write(ep_tx, &words[written], pkt_bytes); - written += pkt_words; + if (tu_fifo_write_n(&tx->ff, packets + written * 4u, 4) != 4) break; + written++; } - (void) tu_edpt_stream_write_xfer(ep_tx); - return written; -} + (void) _tx_start_xfer(p_midi); -bool tud_midi2_n_packet_write(uint8_t itf, const uint8_t packet[4]) { - TU_VERIFY(itf < CFG_TUD_MIDI2, false); - midi2d_interface_t* p_midi = &_midi2d_itf[itf]; - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), false); - TU_VERIFY(tu_edpt_stream_write_available(ep_tx) >= 4, false); - TU_VERIFY(tu_edpt_stream_write(ep_tx, packet, 4) > 0, false); - (void) tu_edpt_stream_write_xfer(ep_tx); - return true; + return written; } //--------------------------------------------------------------------+ @@ -439,8 +529,14 @@ void midi2d_init(void) { tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI2_RX_BUFSIZE, epout_buf); - tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, - p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI2_TX_BUFSIZE, epin_buf); + + midi2d_tx_t* tx = &p_midi->ep_stream.tx; + (void) tu_fifo_config(&tx->ff, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI2_TX_BUFSIZE, false); +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 + tx->ep_buf = epin_buf; +#else + (void) epin_buf; +#endif } } @@ -448,7 +544,6 @@ bool midi2d_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_MIDI2; i++) { midi2d_interface_t* p_midi = &_midi2d_itf[i]; tu_edpt_stream_deinit(&p_midi->ep_stream.rx); - tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } return true; } @@ -462,8 +557,8 @@ void midi2d_reset(uint8_t rhport) { tu_edpt_stream_clear(&p_midi->ep_stream.rx); tu_edpt_stream_close(&p_midi->ep_stream.rx); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); - tu_edpt_stream_close(&p_midi->ep_stream.tx); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); + p_midi->ep_stream.tx.ep_addr = 0; } } @@ -533,8 +628,9 @@ uint16_t midi2d_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint const uint8_t ep_addr = desc_ep->bEndpointAddress; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_midi->ep_stream.tx, rhport, desc_ep, CFG_TUD_MIDI2_TX_EPSIZE); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + p_midi->ep_stream.tx.ep_addr = ep_addr; + p_midi->ep_stream.tx.mps = tu_edpt_packet_size(desc_ep); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); } else { tu_edpt_stream_open(&p_midi->ep_stream.rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(&p_midi->ep_stream.rx); @@ -588,7 +684,7 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re p_midi->alt_setting = alt; tu_edpt_stream_clear(&p_midi->ep_stream.rx); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); if (alt == 1) { p_midi->negotiated = false; @@ -635,53 +731,6 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re } } -// Drain whole UMP packets from the TX FIFO into the EP buffer, capped at -// wMaxPacketSize. Needed when CFG_TUD_MIDI2_TX_BUFSIZE > mps: the FIFO can -// then hold more bytes than fit in a single USB transfer, and a blind -// tu_edpt_stream_write_xfer would split a UMP across two transfers. -static void midi2d_flush_tx_boundary_aware(midi2d_interface_t* p_midi, uint32_t last_xferred) { - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - const uint16_t mps = ep_tx->mps; - const uint16_t ff_count = tu_fifo_count(&ep_tx->ff); - - if (ff_count == 0) { - (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, last_xferred); - return; - } - if (ff_count <= mps) { - // Whole FIFO fits in one transfer; the stream API drain is safe. - (void) tu_edpt_stream_write_xfer(ep_tx); - return; - } - if (ep_tx->ep_buf == NULL) { - // HWFIFO mode: relies on CFG_TUD_MIDI2_TX_BUFSIZE <= mps for UMP integrity. - (void) tu_edpt_stream_write_xfer(ep_tx); - return; - } - - // ff_count > mps and a local EP buffer is available: drain only whole UMP - // packets up to mps to preserve packet boundaries on the USB wire. - uint8_t word_bytes[4]; - uint8_t* buf = ep_tx->ep_buf; - uint16_t bytes = 0; - while (bytes < mps) { - if (tu_fifo_count(&ep_tx->ff) < 4) break; - if (4 != tu_fifo_peek_n(&ep_tx->ff, word_bytes, 4)) break; - uint8_t mt = (uint8_t)((word_bytes[3] >> 4) & 0x0F); - uint8_t pkt_words = midi2_ump_word_count(mt); - uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); - if (tu_fifo_count(&ep_tx->ff) < pkt_bytes) break; - if (bytes + pkt_bytes > mps) break; - tu_fifo_read_n(&ep_tx->ff, buf + bytes, pkt_bytes); - bytes = (uint16_t)(bytes + pkt_bytes); - } - if (bytes == 0) return; - if (!usbd_edpt_claim(p_midi->rhport, ep_tx->ep_addr)) return; - if (!usbd_edpt_xfer(p_midi->rhport, ep_tx->ep_addr, buf, bytes, false)) { - usbd_edpt_release(p_midi->rhport, ep_tx->ep_addr); - } -} - bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) rhport; @@ -690,7 +739,7 @@ bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 midi2d_interface_t* p_midi = &_midi2d_itf[idx]; tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + midi2d_tx_t* ep_tx = &p_midi->ep_stream.tx; if (ep_addr == ep_rx->ep_addr) { if (result == XFER_RESULT_SUCCESS) { @@ -702,7 +751,14 @@ bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } tu_edpt_stream_read_xfer(ep_rx); } else if (ep_addr == ep_tx->ep_addr && result == XFER_RESULT_SUCCESS) { - midi2d_flush_tx_boundary_aware(p_midi, xferred_bytes); + uint16_t queued = _tx_start_xfer(p_midi); + // Send ZLP if no more data is queued but the last transfer was exactly mps + if (queued == 0 && tu_fifo_count(&ep_tx->ff) == 0 && xferred_bytes > 0 && + (0 == (xferred_bytes & (ep_tx->mps - 1)))) { + if (usbd_edpt_claim(rhport, ep_tx->ep_addr)) { + usbd_edpt_xfer(rhport, ep_tx->ep_addr, NULL, 0, false); + } + } } else { return false; } diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index 6c29b8ddf..e53535693 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -130,8 +130,8 @@ uint8_t tud_midi2_n_protocol(uint8_t itf); uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words); uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t count); -bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]); -bool tud_midi2_n_packet_write(uint8_t itf, const uint8_t packet[4]); +uint32_t tud_midi2_n_packet_read(uint8_t itf, uint8_t packets[], uint32_t max_packets); +uint32_t tud_midi2_n_packet_write(uint8_t itf, const uint8_t packets[], uint32_t count); //--------------------------------------------------------------------+ // Application API (Single Interface) @@ -166,12 +166,14 @@ tud_midi2_ump_write(const uint32_t* words, uint32_t count) { return tud_midi2_n_ump_write(0, words, count); } -TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_packet_read(uint8_t packet[4]) { - return tud_midi2_n_packet_read(0, packet); +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi2_packet_read(uint8_t packets[], uint32_t max_packets) { + return tud_midi2_n_packet_read(0, packets, max_packets); } -TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_packet_write(const uint8_t packet[4]) { - return tud_midi2_n_packet_write(0, packet); +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi2_packet_write(const uint8_t packets[], uint32_t count) { + return tud_midi2_n_packet_write(0, packets, count); } //--------------------------------------------------------------------+ -- cgit v1.3.1 From dad8c0ae51d68fd5355a8a0de4e478e4149ec05e Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Tue, 19 May 2026 16:34:42 -0300 Subject: midi2_host: convert TX to raw FIFO mirroring midi2_device refactor --- src/class/midi/midi2_host.c | 192 ++++++++++++++++++++++++++------------------ 1 file changed, 113 insertions(+), 79 deletions(-) (limited to 'src/class/midi') diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c index 5d77e5990..6d8861f4b 100644 --- a/src/class/midi/midi2_host.c +++ b/src/class/midi/midi2_host.c @@ -62,6 +62,13 @@ TU_ATTR_WEAK void tuh_midi2_umount_cb(uint8_t idx) { // Internal structure and state //--------------------------------------------------------------------+ +typedef struct { + uint8_t ep_addr; + uint16_t mps; + tu_fifo_t ff; + uint8_t* ep_buf; +} midih2_tx_t; + typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; @@ -76,7 +83,7 @@ typedef struct { uint8_t tx_cable_count_alt1; struct { - tu_edpt_stream_t tx; + midih2_tx_t tx; tu_edpt_stream_t rx; uint8_t rx_ff_buf[CFG_TUH_MIDI2_RX_BUFSIZE]; @@ -119,6 +126,86 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { return TUSB_INDEX_INVALID_8; } +static inline bool _tuh_tx_opened(const midih2_interface_t* p_midi) { + return p_midi->ep_stream.tx.ep_addr != 0; +} + +static uint8_t _tuh_tx_byte_at(const tu_fifo_buffer_info_t* info, uint16_t offset) { + if (offset < info->linear.len) { + return info->linear.ptr[offset]; + } + offset = (uint16_t)(offset - info->linear.len); + if (offset < info->wrapped.len) { + return info->wrapped.ptr[offset]; + } + return 0; +} + +// Largest byte count containing only whole UMP packets and fitting one xfer. +static uint16_t _tuh_tx_nonseg_len_to_mps(midih2_tx_t* tx) { + tu_fifo_buffer_info_t info; + tu_fifo_get_read_info(&tx->ff, &info); + + const uint16_t available = (uint16_t)(info.linear.len + info.wrapped.len); + uint16_t bytes = 0; + + while (bytes < tx->mps) { + if ((uint16_t)(available - bytes) < 4) break; + + uint8_t mt = (uint8_t)((_tuh_tx_byte_at(&info, (uint16_t)(bytes + 3)) >> 4) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); + + if (pkt_bytes == 0) break; + if ((uint16_t)(available - bytes) < pkt_bytes) break; + if ((uint16_t)(bytes + pkt_bytes) > tx->mps) break; + + bytes = (uint16_t)(bytes + pkt_bytes); + } + + return bytes; +} + +// Start one OUT transfer capped at mps. Returns bytes queued, or 0 if nothing. +static uint16_t _tuh_tx_start_xfer(midih2_interface_t* p_midi) { + midih2_tx_t* tx = &p_midi->ep_stream.tx; + uint16_t ff_count = tu_fifo_count(&tx->ff); + if (ff_count == 0) return 0; + if (!usbh_edpt_claim(p_midi->daddr, tx->ep_addr)) return 0; + + uint16_t bytes; + if (p_midi->alt_setting_current == 1) { + bytes = _tuh_tx_nonseg_len_to_mps(tx); + } else { + bytes = tu_min16(tu_fifo_count(&tx->ff), tx->mps); + } + if (bytes == 0) { + usbh_edpt_release(p_midi->daddr, tx->ep_addr); + return 0; + } + + tu_fifo_read_n(&tx->ff, tx->ep_buf, bytes); + TU_ASSERT(usbh_edpt_xfer(p_midi->daddr, tx->ep_addr, tx->ep_buf, bytes), 0); + return bytes; +} + +static uint32_t _tuh_tx_ump_write(midih2_interface_t* p_midi, const uint32_t* words, uint32_t count) { + uint32_t written = 0; + while (written < count) { + uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); + + if (written + pkt_words > count) break; + if (tu_fifo_remaining(&p_midi->ep_stream.tx.ff) < pkt_bytes) break; + if (tu_fifo_write_n(&p_midi->ep_stream.tx.ff, &words[written], pkt_bytes) != pkt_bytes) break; + written += pkt_words; + } + + (void) _tuh_tx_start_xfer(p_midi); + return written; +} + //--------------------------------------------------------------------+ // Descriptor parsing //--------------------------------------------------------------------+ @@ -151,8 +238,9 @@ static const uint8_t* midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, tu_edpt_stream_open(&p_midi->ep_stream.rx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); tu_edpt_stream_clear(&p_midi->ep_stream.rx); } else { - tu_edpt_stream_open(&p_midi->ep_stream.tx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + p_midi->ep_stream.tx.ep_addr = p_ep->bEndpointAddress; + p_midi->ep_stream.tx.mps = tu_edpt_packet_size(p_ep); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); } p_desc = tu_desc_next(p_desc); @@ -264,13 +352,14 @@ bool midih2_init(void) { for (int inst = 0; inst < CFG_TUH_MIDI2; inst++) { midih2_interface_t *p_midi = &_midi2_host[inst]; - uint8_t* rx_buf = _midi2_epbuf[inst].rx; - uint8_t* tx_buf = _midi2_epbuf[inst].tx; - tu_edpt_stream_init(&p_midi->ep_stream.rx, true, false, false, - p_midi->ep_stream.rx_ff_buf, CFG_TUH_MIDI2_RX_BUFSIZE, rx_buf); - tu_edpt_stream_init(&p_midi->ep_stream.tx, true, true, false, - p_midi->ep_stream.tx_ff_buf, CFG_TUH_MIDI2_TX_BUFSIZE, tx_buf); + p_midi->ep_stream.rx_ff_buf, CFG_TUH_MIDI2_RX_BUFSIZE, _midi2_epbuf[inst].rx); + + // TX uses raw tu_fifo + direct usbh_edpt_xfer (no FIFO wrapper) to preserve + // UMP packet boundaries across USB transfers. + midih2_tx_t* tx = &p_midi->ep_stream.tx; + (void) tu_fifo_config(&tx->ff, p_midi->ep_stream.tx_ff_buf, CFG_TUH_MIDI2_TX_BUFSIZE, false); + tx->ep_buf = _midi2_epbuf[inst].tx; } return true; } @@ -279,7 +368,6 @@ bool midih2_deinit(void) { for (size_t i = 0; i < CFG_TUH_MIDI2; i++) { midih2_interface_t* p_midi = &_midi2_host[i]; tu_edpt_stream_deinit(&p_midi->ep_stream.rx); - tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } return true; } @@ -448,56 +536,20 @@ void midih2_close(uint8_t dev_addr) { if (p_midi->daddr == dev_addr) { TU_LOG_DRV(" MIDI2 close addr = %u index = %u\r\n", dev_addr, idx); tu_edpt_stream_close(&p_midi->ep_stream.rx); - tu_edpt_stream_close(&p_midi->ep_stream.tx); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); + p_midi->ep_stream.tx.ep_addr = 0; tuh_midi2_umount_cb(idx); tu_memclr(p_midi, sizeof(midih2_interface_t)); } } } -// Drain whole UMP packets from the TX FIFO into the EP buffer, capped at -// wMaxPacketSize. Needed when CFG_TUH_MIDI2_TX_BUFSIZE > mps to keep UMP -// packets from crossing USB transfer boundaries. -static void midih2_flush_tx_boundary_aware(midih2_interface_t* p_midi, uint32_t last_xferred) { - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - const uint16_t mps = ep_tx->mps; - const uint16_t ff_count = tu_fifo_count(&ep_tx->ff); - - if (ff_count == 0) { - (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, last_xferred); - return; - } - if (ff_count <= mps || ep_tx->ep_buf == NULL) { - (void) tu_edpt_stream_write_xfer(ep_tx); - return; - } - - uint8_t word_bytes[4]; - uint8_t* buf = ep_tx->ep_buf; - uint16_t bytes = 0; - while (bytes < mps) { - if (tu_fifo_count(&ep_tx->ff) < 4) break; - if (4 != tu_fifo_peek_n(&ep_tx->ff, word_bytes, 4)) break; - uint8_t mt = (uint8_t)((word_bytes[3] >> 4) & 0x0F); - uint8_t pkt_words = midi2_ump_word_count(mt); - uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); - if (tu_fifo_count(&ep_tx->ff) < pkt_bytes) break; - if (bytes + pkt_bytes > mps) break; - tu_fifo_read_n(&ep_tx->ff, buf + bytes, pkt_bytes); - bytes = (uint16_t)(bytes + pkt_bytes); - } - if (bytes == 0) return; - if (!usbh_edpt_claim(p_midi->daddr, ep_tx->ep_addr)) return; - if (!usbh_edpt_xfer(p_midi->daddr, ep_tx->ep_addr, buf, bytes)) { - usbh_edpt_release(p_midi->daddr, ep_tx->ep_addr); - } -} - bool midih2_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { uint8_t idx = get_idx_by_ep_addr(dev_addr, ep_addr); TU_VERIFY(idx < CFG_TUH_MIDI2); midih2_interface_t *p_midi = &_midi2_host[idx]; + midih2_tx_t* ep_tx = &p_midi->ep_stream.tx; if (ep_addr == p_midi->ep_stream.rx.ep_addr) { if (result == XFER_RESULT_SUCCESS && xferred_bytes > 0) { @@ -505,10 +557,17 @@ bool midih2_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin tuh_midi2_rx_cb(idx, xferred_bytes); } tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); - } else if (ep_addr == p_midi->ep_stream.tx.ep_addr) { + } else if (ep_addr == ep_tx->ep_addr) { tuh_midi2_tx_cb(idx, xferred_bytes); if (result == XFER_RESULT_SUCCESS) { - midih2_flush_tx_boundary_aware(p_midi, xferred_bytes); + uint16_t queued = _tuh_tx_start_xfer(p_midi); + // Send ZLP if no more data is queued but the last transfer was exactly mps + if (queued == 0 && tu_fifo_count(&ep_tx->ff) == 0 && xferred_bytes > 0 && + (0 == (xferred_bytes & (ep_tx->mps - 1)))) { + if (usbh_edpt_claim(dev_addr, ep_tx->ep_addr)) { + usbh_edpt_xfer(dev_addr, ep_tx->ep_addr, NULL, 0); + } + } } } @@ -563,39 +622,14 @@ uint32_t tuh_midi2_ump_write(uint8_t idx, const uint32_t* words, uint32_t count) TU_VERIFY(idx < CFG_TUH_MIDI2 && words && count); midih2_interface_t *p_midi = &_midi2_host[idx]; - tu_edpt_stream_t *ep_tx = &p_midi->ep_stream.tx; + TU_VERIFY(_tuh_tx_opened(p_midi), 0); - uint32_t written = 0; - while (written < count) { - uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); - uint8_t pkt_words = midi2_ump_word_count(mt); - uint32_t pkt_bytes = (uint32_t)pkt_words * 4; - - if (written + pkt_words > count) break; - if (tu_edpt_stream_write_available(ep_tx) < pkt_bytes) break; - - // Flush whole packets already queued before adding one that would cross - // the wMaxPacketSize boundary. Prevents an UMP message from being split - // across two USB transfers, which would corrupt the peer RX context. - uint16_t ff_count = tu_fifo_count(&ep_tx->ff); - if (ff_count > 0 && ff_count + pkt_bytes > ep_tx->mps) { - tu_edpt_stream_write_xfer(ep_tx); - } - - tu_edpt_stream_write(ep_tx, (const uint8_t *) &words[written], pkt_bytes); - written += pkt_words; - } - - return written; + return _tuh_tx_ump_write(p_midi, words, count); } uint32_t tuh_midi2_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI2); - - midih2_interface_t *p_midi = &_midi2_host[idx]; - tu_edpt_stream_t *ep_tx = &p_midi->ep_stream.tx; - - return tu_edpt_stream_write_xfer(ep_tx); + return _tuh_tx_start_xfer(&_midi2_host[idx]); } #endif // CFG_TUH_ENABLED && CFG_TUH_MIDI2 -- cgit v1.3.1