diff options
Diffstat (limited to 'examples/device')
79 files changed, 1980 insertions, 1299 deletions
diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 3e0f03a20..de9e8a06a 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -66,8 +66,8 @@ uint32_t sampFreq; uint8_t clkValid; // Range states -audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state -audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state +audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state +audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX * CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000]; @@ -171,7 +171,7 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_req (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -191,7 +191,7 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_re (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -218,25 +218,25 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p (void) itf; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); - mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur; + mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); - volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; @@ -297,13 +297,13 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { - case AUDIO_TE_CTRL_CONNECTOR: { + case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. - audio_desc_channel_cluster_t ret; + audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; - ret.bmChannelConfig = (audio_channel_config_t) 0; + ret.bmChannelConfig = (audio20_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG2(" Get terminal connector\r\n"); @@ -321,24 +321,23 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below - audio_control_range_2_n_t(1) - ret; + audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB @@ -364,15 +363,15 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Clock Source unit if (entityID == 4) { switch (ctrlSel) { - case AUDIO_CS_CTRL_SAM_FREQ: + case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); // Buffered control transfer is needed for IN flow control to work return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Sample Freq. range\r\n"); return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); @@ -383,7 +382,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } break; - case AUDIO_CS_CTRL_CLK_VALID: + case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG2(" Get Sample Freq. valid\r\n"); return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); 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..085f9d168 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" { @@ -105,14 +105,10 @@ 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_CTRL_BUF_SZ 64 - #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 @@ -123,4 +119,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 728a5f9ce..2f5f67f66 100644 --- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -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/main.c b/examples/device/audio_4_channel_mic_freertos/src/main.c index 96eca0be9..4572bbb3c 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/main.c +++ b/examples/device/audio_4_channel_mic_freertos/src/main.c @@ -102,8 +102,8 @@ uint32_t sampFreq; uint8_t clkValid; // Range states -audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state -audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state +audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state +audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX * CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000]; @@ -245,7 +245,7 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_req (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -265,7 +265,7 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_re (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -292,25 +292,25 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p (void) itf; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); - mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur; + mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG1(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); - volume[channelNum] = ((audio_control_cur_2_t *) pBuff)->bCur; + volume[channelNum] = ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG1(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; @@ -368,9 +368,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { - case AUDIO_TE_CTRL_CONNECTOR: { + case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. - audio_desc_channel_cluster_t ret; + audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; @@ -392,23 +392,23 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG1(" Get Mute of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Volume of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below - audio_control_range_2_n_t(1) ret; + audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB @@ -434,15 +434,15 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Clock Source unit if (entityID == 4) { switch (ctrlSel) { - case AUDIO_CS_CTRL_SAM_FREQ: + case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Sample Freq.\r\n"); // Buffered control transfer is needed for IN flow control to work return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Sample Freq. range\r\n"); return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); @@ -453,7 +453,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } break; - case AUDIO_CS_CTRL_CLK_VALID: + case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG1(" Get Sample Freq. valid\r\n"); return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); 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..74729695f 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" { @@ -111,14 +111,10 @@ 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_CTRL_BUF_SZ 64 - #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 @@ -129,4 +125,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 728a5f9ce..2f5f67f66 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,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -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/main.c b/examples/device/audio_test/src/main.c index 5b3beec24..875d0b7f0 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -63,8 +63,8 @@ uint32_t sampFreq; uint8_t clkValid; // Range states -audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state -audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state +audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state +audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data uint16_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / 2]; @@ -157,7 +157,7 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_req (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -177,7 +177,7 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_re (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -204,25 +204,25 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p (void) itf; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); - mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur; + mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); - volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; @@ -283,13 +283,13 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { - case AUDIO_TE_CTRL_CONNECTOR: { + case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. - audio_desc_channel_cluster_t ret; + audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; - ret.bmChannelConfig = (audio_channel_config_t) 0; + ret.bmChannelConfig = (audio20_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG2(" Get terminal connector\r\n"); @@ -307,23 +307,23 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below - audio_control_range_2_n_t(1) + audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; @@ -350,14 +350,14 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Clock Source unit if (entityID == 4) { switch (ctrlSel) { - case AUDIO_CS_CTRL_SAM_FREQ: + case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Sample Freq. range\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); @@ -368,7 +368,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } break; - case AUDIO_CS_CTRL_CLK_VALID: + case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG2(" Get Sample Freq. valid\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 10bf53809..e311d892f 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" { @@ -108,13 +108,10 @@ 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_CTRL_BUF_SZ 64 // Size of control request buffer - #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! -#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device @@ -122,4 +119,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 9864377f6..b6c19deba 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -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/main.c b/examples/device/audio_test_freertos/src/main.c index 1eab5dab8..cf2fb74d1 100644 --- a/examples/device/audio_test_freertos/src/main.c +++ b/examples/device/audio_test_freertos/src/main.c @@ -100,8 +100,8 @@ uint32_t sampFreq; uint8_t clkValid; // Range states -audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state -audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state +audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state +audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data uint16_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / 2]; @@ -231,7 +231,7 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_req (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -251,7 +251,7 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_re (void) pBuff; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); @@ -278,25 +278,25 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p (void) itf; // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); - mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur; + mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG1(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); - volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG1(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; @@ -354,13 +354,13 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { - case AUDIO_TE_CTRL_CONNECTOR: { + case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. - audio_desc_channel_cluster_t ret; + audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; - ret.bmChannelConfig = (audio_channel_config_t) 0; + ret.bmChannelConfig = (audio20_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG1(" Get terminal connector\r\n"); @@ -378,23 +378,23 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Feature unit if (entityID == 2) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG1(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Volume of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below - audio_control_range_2_n_t(1) + audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; @@ -421,14 +421,14 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Clock Source unit if (entityID == 4) { switch (ctrlSel) { - case AUDIO_CS_CTRL_SAM_FREQ: + case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Sample Freq.\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Sample Freq. range\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); @@ -439,7 +439,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } break; - case AUDIO_CS_CTRL_CLK_VALID: + case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG1(" Get Sample Freq. valid\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h index c9dc50082..81f0c11f4 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" { @@ -114,13 +114,10 @@ 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_CTRL_BUF_SZ 64 // Size of control request buffer - #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! -#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device @@ -128,4 +125,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 9864377f6..b6c19deba 100644 --- a/examples/device/audio_test_freertos/src/usb_descriptors.c +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -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/main.c b/examples/device/audio_test_multi_rate/src/main.c index 9d467991e..55a649613 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -60,7 +60,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 -uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 +int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 uint32_t sampFreq; uint8_t bytesPerSample; uint8_t clkValid; @@ -80,9 +80,6 @@ static const uint8_t bytesPerSampleAltList[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] = CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, }; -audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state - - // Audio test data CFG_TUD_MEM_ALIGN uint8_t test_buffer_audio[(TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; uint16_t startVal = 0; @@ -111,9 +108,6 @@ int main(void) { led_blinking_task(); audio_task(); } - - - return 0; } //--------------------------------------------------------------------+ @@ -176,91 +170,204 @@ void audio_task(void) { // Application Callback API Implementations //--------------------------------------------------------------------+ -// Invoked when set interface is called, typically on start/stop streaming or format change -bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - (void) rhport; - //uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); - uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); +//--------------------------------------------------------------------+ +// UAC1 Helper Functions +//--------------------------------------------------------------------+ - // Clear buffer when streaming format is changed - if (alt != 0) { - bytesPerSample = bytesPerSampleAltList[alt - 1]; +static bool audio10_set_req_ep(tusb_control_request_t const *p_request, uint8_t *pBuff) { + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + + switch (ctrlSel) { + case AUDIO10_EP_CTRL_SAMPLING_FREQ: + if (p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { + // Request uses 3 bytes + TU_VERIFY(p_request->wLength == 3); + + sampFreq = tu_unaligned_read32(pBuff) & 0x00FFFFFF; + + TU_LOG2("EP set current freq: %" PRIu32 "\r\n", sampFreq); + + return true; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; } - return true; + + return false; } -// Invoked when audio class specific set request received for an EP -bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { - (void) rhport; - (void) pBuff; +static bool audio10_get_req_ep(uint8_t rhport, tusb_control_request_t const *p_request) { + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + switch (ctrlSel) { + case AUDIO10_EP_CTRL_SAMPLING_FREQ: + if (p_request->bRequest == AUDIO10_CS_REQ_GET_CUR) { + TU_LOG2("EP get current freq\r\n"); + + uint8_t freq[3]; + freq[0] = (uint8_t) (sampFreq & 0xFF); + freq[1] = (uint8_t) ((sampFreq >> 8) & 0xFF); + freq[2] = (uint8_t) ((sampFreq >> 16) & 0xFF); + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, freq, sizeof(freq)); + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + + return false; +} - // Page 91 in UAC2 specification +static bool audio10_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - uint8_t ep = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); - (void) channelNum; - (void) ctrlSel; - (void) ep; + // If request is for our feature unit (ID defined in usbd.h) + if (entityID == 0x02) { + switch (ctrlSel) { + case AUDIO10_FU_CTRL_MUTE: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_SET_CUR: + // Only 1st form is supported + TU_VERIFY(p_request->wLength ==1); - return false;// Yet not implemented -} + mute[channelNum] = pBuff[0]; -// Invoked when audio class specific set request received for an interface -bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { - (void) rhport; - (void) pBuff; + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; - // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + default: + return false; // not supported + } - // Page 91 in UAC2 specification + case AUDIO10_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_SET_CUR: + // Only 1st form is supported + TU_VERIFY(p_request->wLength == 2); + + volume[channelNum] = (int16_t)tu_unaligned_read16(pBuff) / 256; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + default: + return false; // not supported + } + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + return false; +} + +static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // If request is for our feature unit (ID defined in usbd.h) + if (entityID == 0x02) { + switch (ctrlSel) { + case AUDIO10_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); - (void) channelNum; - (void) ctrlSel; - (void) itf; + case AUDIO10_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_GET_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + { + int16_t vol = (int16_t) volume[channelNum]; + vol = vol * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &vol, sizeof(vol)); + } - return false;// Yet not implemented + case AUDIO10_CS_REQ_GET_MIN: + TU_LOG2(" Get Volume min of channel: %u\r\n", channelNum); + { + int16_t min = -90; // -90 dB + min = min * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &min, sizeof(min)); + } + + case AUDIO10_CS_REQ_GET_MAX: + TU_LOG2(" Get Volume max of channel: %u\r\n", channelNum); + { + int16_t max = 30; // +30 dB + max = max * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &max, sizeof(max)); + } + + case AUDIO10_CS_REQ_GET_RES: + TU_LOG2(" Get Volume res of channel: %u\r\n", channelNum); + { + int16_t res = 1; // 1 dB + res = res * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &res, sizeof(res)); + } + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + return false; } -// Invoked when audio class specific set request received for an entity -bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { - (void) rhport; +//--------------------------------------------------------------------+ +// UAC2 Helper Functions +//--------------------------------------------------------------------+ + +#if TUD_OPT_HIGH_SPEED - // Page 91 in UAC2 specification +static bool audio20_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); - (void) itf; - // We do not support any set range requests here, only current value requests - TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == UAC2_ENTITY_FEATURE_UNIT) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); - mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur; + mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); - volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur; + volume[channelNum] = (int16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; @@ -275,10 +382,10 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Clock Source unit if (entityID == UAC2_ENTITY_CLOCK) { switch (ctrlSel) { - case AUDIO_CS_CTRL_SAM_FREQ: - TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_4_t)); + case AUDIO20_CS_CTRL_SAM_FREQ: + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_4_t)); - sampFreq = (uint32_t) ((audio_control_cur_4_t *) pBuff)->bCur; + sampFreq = (uint32_t) ((audio20_control_cur_4_t *) pBuff)->bCur; TU_LOG2("Clock set current freq: %" PRIu32 "\r\n", sampFreq); @@ -292,59 +399,20 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } } - return false;// Yet not implemented -} - -// Invoked when audio class specific get request received for an EP -bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - (void) rhport; - - // Page 91 in UAC2 specification - uint8_t channelNum = TU_U16_LOW(p_request->wValue); - uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - uint8_t ep = TU_U16_LOW(p_request->wIndex); - - (void) channelNum; - (void) ctrlSel; - (void) ep; - - // return tud_control_xfer(rhport, p_request, &tmp, 1); - - return false;// Yet not implemented -} - -// Invoked when audio class specific get request received for an interface -bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - (void) rhport; - - // Page 91 in UAC2 specification - uint8_t channelNum = TU_U16_LOW(p_request->wValue); - uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - uint8_t itf = TU_U16_LOW(p_request->wIndex); - - (void) channelNum; - (void) ctrlSel; - (void) itf; - - return false;// Yet not implemented + return false; } -// Invoked when audio class specific get request received for an entity -bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - (void) rhport; - - // Page 91 in UAC2 specification +static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); - // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Input terminal (Microphone input) if (entityID == UAC2_ENTITY_INPUT_TERMINAL) { switch (ctrlSel) { - case AUDIO_TE_CTRL_CONNECTOR: { + case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. - audio_desc_channel_cluster_t ret; + audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; @@ -366,23 +434,23 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Feature unit if (entityID == UAC2_ENTITY_FEATURE_UNIT) { switch (ctrlSel) { - case AUDIO_FU_CTRL_MUTE: + case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); - case AUDIO_FU_CTRL_VOLUME: + case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); - case AUDIO_CS_REQ_RANGE: + case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below - audio_control_range_2_n_t(1) + audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; @@ -409,16 +477,16 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Clock Source unit if (entityID == UAC2_ENTITY_CLOCK) { switch (ctrlSel) { - case AUDIO_CS_CTRL_SAM_FREQ: + case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { - case AUDIO_CS_REQ_CUR: + case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); - case AUDIO_CS_REQ_RANGE: { + case AUDIO20_CS_REQ_RANGE: { TU_LOG2(" Get Sample Freq. range\r\n"); - audio_control_range_4_n_t(N_sampleRates) rangef = + audio20_control_range_4_n_t(N_sampleRates) rangef = { .wNumSubRanges = tu_htole16(N_sampleRates)}; TU_LOG1("Clock get %d freq ranges\r\n", N_sampleRates); @@ -437,7 +505,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } break; - case AUDIO_CS_CTRL_CLK_VALID: + case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG2(" Get Sample Freq. valid\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); @@ -449,7 +517,82 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } } - TU_LOG2(" Unsupported entity: %d\r\n", entityID); + return false; +} + +#endif // TUD_OPT_HIGH_SPEED + +//--------------------------------------------------------------------+ +// Main Callback Functions +//--------------------------------------------------------------------+ + +// Invoked when set interface is called, typically on start/stop streaming or format change +bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + //uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); + uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); + + // Clear buffer when streaming format is changed + if (alt != 0) { + bytesPerSample = bytesPerSampleAltList[alt - 1]; + } + return true; +} + +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { + (void) rhport; + (void) pBuff; + + if (tud_audio_version() == 1) { + return audio10_set_req_ep(p_request, pBuff); + } else if (tud_audio_version() == 2) { + // We do not support any requests here + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_get_req_ep(rhport, p_request); + } else if (tud_audio_version() == 2) { + // We do not support any requests here + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_set_req_entity(p_request, pBuff); +#if TUD_OPT_HIGH_SPEED + } else if (tud_audio_version() == 2) { + return audio20_set_req_entity(p_request, pBuff); +#endif + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_get_req_entity(rhport, p_request); +#if TUD_OPT_HIGH_SPEED + } else if (tud_audio_version() == 2) { + return audio20_get_req_entity(rhport, p_request); +#endif + } + return false;// Yet not implemented } 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..3587ae089 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" { @@ -116,26 +116,31 @@ extern "C" { #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 16 -// 24bit in 32bit slots +// 24bit in 32bit slots (UAC2 only) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 24 // 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_CTRL_BUF_SZ 64 // Size of control request buffer +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! -#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! +// UAC1 (Full-Speed) Endpoint size calculation +#define CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(false, 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) -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN 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) -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN 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) +// UAC2 (High-Speed) Endpoint size calculation +#define CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, 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) +#define CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, 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) -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example write FIFO every 1ms, so it should be 8 times larger for HS device +// Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) + +// Tx flow control needs buffer size >= 4* EP size to work correctly +// Example write FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, 32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) #ifdef __cplusplus } #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 f50e70a25..1912a81e2 100644 --- a/examples/device/audio_test_multi_rate/src/usb_descriptors.c +++ b/examples/device/audio_test_multi_rate/src/usb_descriptors.c @@ -34,15 +34,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, @@ -67,23 +66,19 @@ tusb_desc_device_t const desc_device = // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ +uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -enum -{ +enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_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 // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... @@ -97,24 +92,81 @@ enum #define EPNUM_AUDIO 0x01 #endif -uint8_t const desc_configuration[] = -{ +#define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_MIC_ONE_CH_DESC_LEN(3)) + +uint8_t const desc_uac1_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC1_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO10_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ 2, /*_nBitsUsedPerSample*/ 16, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, 32000, 48000, 96000) +}; + +TU_VERIFY_STATIC(sizeof(desc_uac1_configuration) == CONFIG_UAC1_TOTAL_LEN, "Incorrect size"); + +#if TUD_OPT_HIGH_SPEED +#define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESC_LEN) + +uint8_t const desc2_uac2_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC2_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(desc2_uac2_configuration) == CONFIG_UAC2_TOTAL_LEN, "Incorrect size"); + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 }; -TU_VERIFY_STATIC(sizeof(desc_configuration) == CONFIG_TOTAL_LEN, "Incorrect size"); +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const *tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const *) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index;// for multiple configurations + + // if link speed is high return fullspeed config, and vice versa + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_uac1_configuration : desc2_uac2_configuration; +} + +#endif// highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations - return desc_configuration; +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + if(tud_speed_get() == TUSB_SPEED_FULL) { + return desc_uac1_configuration; + } else { + return desc2_uac2_configuration; + } +#else + return desc_uac1_configuration; +#endif } //--------------------------------------------------------------------+ @@ -130,8 +182,7 @@ enum { }; // array of pointer to string descriptors -char const* string_desc_arr [] = -{ +char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "PaniRCorp", // 1: Manufacturer "MicNode", // 2: Product 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 8381e31f5..c02f40cd9 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*/ AUDIO_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*/ AUDIO_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*/ AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ AUDIO_CTRL_RW << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS | AUDIO_CTRL_R << AUDIO_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*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO_CTRL_R << AUDIO_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*/ AUDIO_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*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO_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*/ ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO20_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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO_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*/ ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO20_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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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/board_test/src/main.c b/examples/device/board_test/src/main.c index d91a8760e..ee0829e5b 100644 --- a/examples/device/board_test/src/main.c +++ b/examples/device/board_test/src/main.c @@ -66,12 +66,12 @@ int main(void) { printf(HELLO_STR); #ifndef LOGGER_UART - board_uart_write(HELLO_STR, strlen(HELLO_STR)); + board_uart_write(HELLO_STR, sizeof(HELLO_STR)-1); #endif } board_led_write(led_state); - led_state = 1 - led_state; // toggle + led_state = !led_state; // toggle } } } 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 bbcb479f5..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) << (n) ) -#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 @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -127,7 +127,7 @@ enum { #define EPNUM_CDC_1_IN 0x84 #endif -uint8_t const desc_fs_configuration[] = { +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -140,7 +140,7 @@ uint8_t const desc_fs_configuration[] = { #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration -uint8_t const desc_hs_configuration[] = { +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -152,7 +152,7 @@ uint8_t const desc_hs_configuration[] = { }; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = { +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -213,7 +213,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = { +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c index 4e7aa989e..c4606528a 100644 --- a/examples/device/cdc_msc/src/main.c +++ b/examples/device/cdc_msc/src/main.c @@ -42,6 +42,7 @@ enum { }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; +static bool blink_enable = true; void led_blinking_task(void); void cdc_task(void); @@ -135,11 +136,13 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; (void) rts; - // TODO set some indicator if (dtr) { // Terminal connected + blink_enable = false; + board_led_write(true); } else { // Terminal disconnected + blink_enable = true; } } @@ -155,10 +158,14 @@ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; - // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; // not enough time - start_ms += blink_interval_ms; + if (blink_enable) { + // Blink every interval ms + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } + start_ms += blink_interval_ms; - board_led_write(led_state); - led_state = 1 - led_state; // toggle + board_led_write(led_state); + led_state = !led_state; + } } diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index 96f9f19ec..1a95f7f8b 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -45,6 +45,7 @@ enum { DISK_BLOCK_SIZE = 512 }; +static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif @@ -57,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, + { + 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, + // 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, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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}, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 @@ -126,9 +128,9 @@ uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uin const char pid[] = "Mass Storage"; const char rev[] = "1.0"; - memcpy(inquiry_resp->vendor_id, vid, strlen(vid)); - memcpy(inquiry_resp->product_id, pid, strlen(pid)); - memcpy(inquiry_resp->product_rev, rev, strlen(rev)); + strncpy((char*) inquiry_resp->vendor_id, vid, 8); + strncpy((char*) inquiry_resp->product_id, pid, 16); + strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } @@ -213,7 +215,9 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * (void) lun; // out of ramdisk - if (lba >= DISK_BLOCK_NUM) return -1; + if (lba >= DISK_BLOCK_NUM) { + return -1; + } #ifndef CFG_EXAMPLE_MSC_READONLY uint8_t *addr = msc_disk[lba] + offset; @@ -242,6 +246,8 @@ int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, u // negative means error -> tinyusb could stall and/or response with failed status return -1; } + + return -1; } #endif 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 597a6b1e6..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) << (n) ) -#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 @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -125,7 +125,7 @@ enum { #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN) // full speed configuration -uint8_t const desc_fs_configuration[] = { +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -140,7 +140,7 @@ uint8_t const desc_fs_configuration[] = { // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = { +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -152,10 +152,10 @@ uint8_t const desc_hs_configuration[] = { }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = { +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, @@ -223,7 +223,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = { +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 69f2435ba..4fb209fd0 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -37,7 +37,7 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif -#define CDC_STACK_SIZE configMINIMAL_STACK_SIZE +#define CDC_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c index c09cf67d6..29ff86281 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -76,6 +76,7 @@ enum { DISK_BLOCK_SIZE = 512 }; +static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif @@ -198,9 +199,9 @@ uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp, uin const char pid[] = "Mass Storage"; const char rev[] = "1.0"; - memcpy(inquiry_resp->vendor_id, vid, strlen(vid)); - memcpy(inquiry_resp->product_id, pid, strlen(pid)); - memcpy(inquiry_resp->product_rev, rev, strlen(rev)); + strncpy((char*) inquiry_resp->vendor_id, vid, 8); + strncpy((char*) inquiry_resp->product_id, pid, 16); + strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } @@ -324,12 +325,8 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { // read10 & write10 has their own callback and MUST not be handled here - - void const *response = NULL; - int32_t resplen = 0; - - // most scsi handled is input - bool in_xfer = true; + (void) buffer; + (void) bufsize; switch (scsi_cmd[0]) { default: @@ -337,22 +334,10 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // negative means error -> tinyusb could stall and/or response with failed status - resplen = -1; - break; - } - - // return resplen must not larger than bufsize - if (resplen > bufsize) { resplen = bufsize; } - - if (response && (resplen > 0)) { - if (in_xfer) { - memcpy(buffer, response, (size_t) resplen); - } else { - // SCSI output - } + return -1; } - return (int32_t) resplen; + return -1; } #endif 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 cb440c209..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) << (n) ) -#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 @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -124,7 +124,7 @@ enum { #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN) -uint8_t const desc_fs_configuration[] = +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -140,7 +140,7 @@ uint8_t const desc_fs_configuration[] = // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -153,10 +153,10 @@ uint8_t const desc_hs_configuration[] = }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, @@ -225,7 +225,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = { +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h index 2e744f8d2..b7ece8b7c 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" { @@ -105,8 +105,6 @@ extern "C" { // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_HEADSET_STEREO_DESC_LEN - // How many formats are used, need to adjust USB descriptor if changed #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 @@ -142,8 +140,8 @@ extern "C" { // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN 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) -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN 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) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, 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) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, 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) #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device @@ -151,15 +149,12 @@ extern "C" { // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT 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) -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT 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) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, 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) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, 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) #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device -// Size of control request buffer -#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 - // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) @@ -171,4 +166,4 @@ extern "C" { } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index a1a0dd73d..cb7b716e8 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -80,22 +80,22 @@ void audio_task(void) { } // Helper for clock get requests -static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) +static bool tud_audio_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) + if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { - if (request->bRequest == AUDIO_CS_REQ_CUR) + if (request->bRequest == AUDIO20_CS_REQ_CUR) { TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); - audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; + audio20_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); } - else if (request->bRequest == AUDIO_CS_REQ_RANGE) + else if (request->bRequest == AUDIO20_CS_REQ_RANGE) { - audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = + audio20_control_range_4_n_t(N_SAMPLE_RATES) rangef = { .wNumSubRanges = tu_htole16(N_SAMPLE_RATES) }; @@ -111,10 +111,10 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef)); } } - else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID && - request->bRequest == AUDIO_CS_REQ_CUR) + else if (request->bControlSelector == AUDIO20_CS_CTRL_CLK_VALID && + request->bRequest == AUDIO20_CS_REQ_CUR) { - audio_control_cur_1_t cur_valid = { .bCur = 1 }; + audio20_control_cur_1_t cur_valid = { .bCur = 1 }; TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid)); } @@ -124,18 +124,18 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t } // Helper for clock set requests -static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) +static bool tud_audio_clock_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void)rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); - if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) + if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_4_t)); - current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; + current_sample_rate = (uint32_t) ((audio20_control_cur_4_t const *)buf)->bCur; TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); @@ -150,21 +150,21 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t } // Helper for feature unit get requests -static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) +static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); - if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) + if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE && request->bRequest == AUDIO20_CS_REQ_CUR) { - audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] }; + audio20_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] }; TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); } - else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { - if (request->bRequest == AUDIO_CS_REQ_RANGE) + if (request->bRequest == AUDIO20_CS_REQ_RANGE) { - audio_control_range_2_n_t(1) range_vol = { + audio20_control_range_2_n_t(1) range_vol = { .wNumSubRanges = tu_htole16(1), .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) } }; @@ -172,9 +172,9 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol)); } - else if (request->bRequest == AUDIO_CS_REQ_CUR) + else if (request->bRequest == AUDIO20_CS_REQ_CUR) { - audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) }; + audio20_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) }; TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol)); } @@ -186,28 +186,28 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req } // Helper for feature unit set requests -static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) +static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void)rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); - TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); - if (request->bControlSelector == AUDIO_FU_CTRL_MUTE) + if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t)); + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_1_t)); - mute[request->bChannelNumber] = ((audio_control_cur_1_t const *)buf)->bCur; + mute[request->bChannelNumber] = ((audio20_control_cur_1_t const *)buf)->bCur; TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; } - else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t)); + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_2_t)); - volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur; + volume[request->bChannelNumber] = ((audio20_control_cur_2_t const *)buf)->bCur; TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); @@ -228,7 +228,7 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - audio_control_request_t const *request = (audio_control_request_t const *)p_request; + audio20_control_request_t const *request = (audio20_control_request_t const *)p_request; if (request->bEntityID == UAC2_ENTITY_CLOCK) return tud_audio_clock_get_request(rhport, request); @@ -245,7 +245,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { - audio_control_request_t const *request = (audio_control_request_t const *)p_request; + audio20_control_request_t const *request = (audio20_control_request_t const *)p_request; if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) return tud_audio_feature_unit_set_request(rhport, request, buf); diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index da55bdb5a..252b602ac 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -35,14 +35,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -116,7 +116,7 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_IN 0x84 #endif -uint8_t const desc_fs_configuration[] = +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -132,7 +132,7 @@ uint8_t const desc_fs_configuration[] = // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = { +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -144,10 +144,10 @@ uint8_t const desc_hs_configuration[] = { }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = { +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = 0x0100, @@ -215,7 +215,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer diff --git a/examples/device/cdc_uac2/src/usb_descriptors.h b/examples/device/cdc_uac2/src/usb_descriptors.h index 736feeefe..95d8da5c3 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*/ AUDIO_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*/ AUDIO_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*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_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*/ (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_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*/ AUDIO_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*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_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*/ AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index fd469aaf2..14ec315ea 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -33,14 +33,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -126,7 +126,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer diff --git a/examples/device/dfu_runtime/src/usb_descriptors.c b/examples/device/dfu_runtime/src/usb_descriptors.c index 7ac53d255..1d46ee252 100644 --- a/examples/device/dfu_runtime/src/usb_descriptors.c +++ b/examples/device/dfu_runtime/src/usb_descriptors.c @@ -33,14 +33,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -122,7 +122,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index ebc86e260..ab71b02d6 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -43,6 +43,7 @@ enum DISK_BLOCK_SIZE = 512 }; +static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif @@ -126,9 +127,9 @@ uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uin const char pid[] = "Mass Storage"; const char rev[] = "1.0"; - memcpy(inquiry_resp->vendor_id, vid, strlen(vid)); - memcpy(inquiry_resp->product_id, pid, strlen(pid)); - memcpy(inquiry_resp->product_rev, rev, strlen(rev)); + strncpy((char*) inquiry_resp->vendor_id, vid, 8); + strncpy((char*) inquiry_resp->product_id, pid, 16); + strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } @@ -211,42 +212,21 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks -int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) -{ +int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { // read10 & write10 has their own callback and MUST not be handled here + (void) buffer; + (void) bufsize; - void const* response = NULL; - int32_t resplen = 0; - - // most scsi handled is input - bool in_xfer = true; - - switch (scsi_cmd[0]) - { + switch (scsi_cmd[0]) { default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // negative means error -> tinyusb could stall and/or response with failed status - resplen = -1; - break; - } - - // return resplen must not larger than bufsize - if ( resplen > bufsize ) resplen = bufsize; - - if ( response && (resplen > 0) ) - { - if(in_xfer) - { - memcpy(buffer, response, (size_t) resplen); - }else - { - // SCSI output - } + return -1; } - return resplen; + return -1; } #endif 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 0a2049288..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) << (n) ) -#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 @@ -202,7 +202,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 d68ef16d9..9b4becc85 100644 --- a/examples/device/hid_boot_interface/src/usb_descriptors.c +++ b/examples/device/hid_boot_interface/src/usb_descriptors.c @@ -33,14 +33,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -140,7 +140,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 ce7fbd13f..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) << (n) ) -#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 @@ -43,7 +43,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -120,10 +120,10 @@ uint8_t const desc_configuration[] = // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, @@ -188,7 +188,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 0eb13add3..391e3c42a 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -53,7 +53,7 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif -#define HID_STACK_SZIE configMINIMAL_STACK_SIZE +#define HID_STACK_SZIE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES 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 3f231fecc..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) << (n) ) -#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 @@ -43,7 +43,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -119,10 +119,10 @@ uint8_t const desc_configuration[] = // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, @@ -185,7 +185,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 64f6d17ae..f26333d50 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -130,7 +130,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 86f567e8e..cd2d93c44 100644 --- a/examples/device/hid_multiple_interface/src/usb_descriptors.c +++ b/examples/device/hid_multiple_interface/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -146,7 +146,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 384742ae8..e969f33a3 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, @@ -98,7 +98,7 @@ enum { #define EPNUM_MIDI_IN 0x81 #endif -uint8_t const desc_fs_configuration[] = { +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -107,7 +107,7 @@ uint8_t const desc_fs_configuration[] = { }; #if TUD_OPT_HIGH_SPEED -uint8_t const desc_hs_configuration[] = { +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -143,7 +143,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = { +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product diff --git a/examples/device/midi_test_freertos/src/main.c b/examples/device/midi_test_freertos/src/main.c index 9dd66c526..f5267214e 100644 --- a/examples/device/midi_test_freertos/src/main.c +++ b/examples/device/midi_test_freertos/src/main.c @@ -48,7 +48,7 @@ #endif #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE -#define MIDI_STACK_SIZE configMINIMAL_STACK_SIZE +#define MIDI_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) // static task #if configSUPPORT_STATIC_ALLOCATION 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 384742ae8..e969f33a3 100644 --- a/examples/device/midi_test_freertos/src/usb_descriptors.c +++ b/examples/device/midi_test_freertos/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, @@ -98,7 +98,7 @@ enum { #define EPNUM_MIDI_IN 0x81 #endif -uint8_t const desc_fs_configuration[] = { +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -107,7 +107,7 @@ uint8_t const desc_fs_configuration[] = { }; #if TUD_OPT_HIGH_SPEED -uint8_t const desc_hs_configuration[] = { +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -143,7 +143,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = { +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 775fa047e..694da11db 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -217,9 +217,9 @@ uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uin const char pid[] = "Mass Storage"; const char rev[] = "1.0"; - memcpy(inquiry_resp->vendor_id, vid, strlen(vid)); - memcpy(inquiry_resp->product_id, pid, strlen(pid)); - memcpy(inquiry_resp->product_rev, rev, strlen(rev)); + strncpy((char*) inquiry_resp->vendor_id, vid, 8); + strncpy((char*) inquiry_resp->product_id, pid, 16); + strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } @@ -227,9 +227,7 @@ uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uin // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { - if ( lun == 1 && board_button_read() ) return false; - - return true; // RAM disk is always ready + return ( lun == 1 && board_button_read() ) ? false : true; } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size 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 efb9a966d..f73935ee0 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -32,14 +32,14 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -103,7 +103,7 @@ enum #endif -uint8_t const desc_fs_configuration[] = +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -113,7 +113,7 @@ uint8_t const desc_fs_configuration[] = }; #if TUD_OPT_HIGH_SPEED -uint8_t const desc_hs_configuration[] = +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -151,7 +151,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 80345d8f8..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) << (n) ) -#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 @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -121,7 +121,7 @@ const uint8_t desc_fs_configuration[] = { // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = { +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP event, EP event size, EP event polling, EP Out & EP In address, EP size @@ -129,10 +129,10 @@ uint8_t const desc_hs_configuration[] = { }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = { +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, @@ -198,7 +198,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUsb", // 1: Manufacturer 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 cd800f521..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) << (n) ) -#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 @@ -68,7 +68,7 @@ enum //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 102a6eef1..96fa66f1e 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -73,7 +73,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states -int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 +uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0 // Buffer for microphone data @@ -141,18 +141,195 @@ void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } +//--------------------------------------------------------------------+ +// Audio Callback Functions +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// UAC1 Helper Functions +//--------------------------------------------------------------------+ + +static bool audio10_set_req_ep(tusb_control_request_t const *p_request, uint8_t *pBuff) { + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + + switch (ctrlSel) { + case AUDIO10_EP_CTRL_SAMPLING_FREQ: + if (p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { + // Request uses 3 bytes + TU_VERIFY(p_request->wLength == 3); + + current_sample_rate = tu_unaligned_read32(pBuff) & 0x00FFFFFF; + + TU_LOG2("EP set current freq: %" PRIu32 "\r\n", current_sample_rate); + + return true; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + + return false; +} + +static bool audio10_get_req_ep(uint8_t rhport, tusb_control_request_t const *p_request) { + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + + switch (ctrlSel) { + case AUDIO10_EP_CTRL_SAMPLING_FREQ: + if (p_request->bRequest == AUDIO10_CS_REQ_GET_CUR) { + TU_LOG2("EP get current freq\r\n"); + + uint8_t freq[3]; + freq[0] = (uint8_t) (current_sample_rate & 0xFF); + freq[1] = (uint8_t) ((current_sample_rate >> 8) & 0xFF); + freq[2] = (uint8_t) ((current_sample_rate >> 16) & 0xFF); + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, freq, sizeof(freq)); + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + + return false; +} + +static bool audio10_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // If request is for our speaker feature unit + if (entityID == UAC1_ENTITY_SPK_FEATURE_UNIT) { + switch (ctrlSel) { + case AUDIO10_FU_CTRL_MUTE: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_SET_CUR: + // Only 1st form is supported + TU_VERIFY(p_request->wLength == 1); + + mute[channelNum] = pBuff[0]; + + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; + + default: + return false; // not supported + } + + case AUDIO10_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_SET_CUR: + // Only 1st form is supported + TU_VERIFY(p_request->wLength == 2); + + volume[channelNum] = (int16_t)tu_unaligned_read16(pBuff) / 256; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + default: + return false; // not supported + } + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + return false; +} + +static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // If request is for our speaker feature unit + if (entityID == UAC1_ENTITY_SPK_FEATURE_UNIT) { + switch (ctrlSel) { + case AUDIO10_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); + + case AUDIO10_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_GET_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + { + int16_t vol = (int16_t) volume[channelNum]; + vol = vol * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &vol, sizeof(vol)); + } + + case AUDIO10_CS_REQ_GET_MIN: + TU_LOG2(" Get Volume min of channel: %u\r\n", channelNum); + { + int16_t min = -90; // -90 dB + min = min * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &min, sizeof(min)); + } + + case AUDIO10_CS_REQ_GET_MAX: + TU_LOG2(" Get Volume max of channel: %u\r\n", channelNum); + { + int16_t max = 30; // +30 dB + max = max * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &max, sizeof(max)); + } + + case AUDIO10_CS_REQ_GET_RES: + TU_LOG2(" Get Volume res of channel: %u\r\n", channelNum); + { + int16_t res = 1; // 1 dB + res = res * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &res, sizeof(res)); + } + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + return false; +} + +//--------------------------------------------------------------------+ +// UAC2 Helper Functions +//--------------------------------------------------------------------+ + +#if TUD_OPT_HIGH_SPEED + // Helper for clock get requests -static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) { +static bool audio20_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) { - if (request->bRequest == AUDIO_CS_REQ_CUR) { + if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { + if (request->bRequest == AUDIO20_CS_REQ_CUR) { TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); - audio_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)}; + audio20_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)}; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &curf, sizeof(curf)); - } else if (request->bRequest == AUDIO_CS_REQ_RANGE) { - audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = + } else if (request->bRequest == AUDIO20_CS_REQ_RANGE) { + audio20_control_range_4_n_t(N_SAMPLE_RATES) rangef = { .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)}; TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); @@ -165,9 +342,9 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &rangef, sizeof(rangef)); } - } else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID && - request->bRequest == AUDIO_CS_REQ_CUR) { - audio_control_cur_1_t cur_valid = {.bCur = 1}; + } else if (request->bControlSelector == AUDIO20_CS_CTRL_CLK_VALID && + request->bRequest == AUDIO20_CS_REQ_CUR) { + audio20_control_cur_1_t cur_valid = {.bCur = 1}; TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_valid, sizeof(cur_valid)); } @@ -177,16 +354,16 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t } // Helper for clock set requests -static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) { +static bool audio20_clock_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void) rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); - if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); + if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_4_t)); - current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *) buf)->bCur; + current_sample_rate = (uint32_t) ((audio20_control_cur_4_t const *) buf)->bCur; TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); @@ -199,23 +376,23 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t } // Helper for feature unit get requests -static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) { +static bool audio20_feature_unit_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); - if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) { - audio_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]}; + if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE && request->bRequest == AUDIO20_CS_REQ_CUR) { + audio20_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]}; TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &mute1, sizeof(mute1)); - } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { - if (request->bRequest == AUDIO_CS_REQ_RANGE) { - audio_control_range_2_n_t(1) range_vol = { + } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { + if (request->bRequest == AUDIO20_CS_REQ_RANGE) { + audio20_control_range_2_n_t(1) range_vol = { .wNumSubRanges = tu_htole16(1), .subrange[0] = {.bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256)}}; TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &range_vol, sizeof(range_vol)); - } else if (request->bRequest == AUDIO_CS_REQ_CUR) { - audio_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])}; + } else if (request->bRequest == AUDIO20_CS_REQ_CUR) { + audio20_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])}; TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_vol, sizeof(cur_vol)); } @@ -227,24 +404,24 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req } // Helper for feature unit set requests -static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) { +static bool audio20_feature_unit_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void) rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); - TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); - if (request->bControlSelector == AUDIO_FU_CTRL_MUTE) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t)); + if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE) { + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_1_t)); - mute[request->bChannelNumber] = ((audio_control_cur_1_t const *) buf)->bCur; + mute[request->bChannelNumber] = ((audio20_control_cur_1_t const *) buf)->bCur; TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; - } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t)); + } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_2_t)); - volume[request->bChannelNumber] = ((audio_control_cur_2_t const *) buf)->bCur; + volume[request->bChannelNumber] = ((audio20_control_cur_2_t const *) buf)->bCur; TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); @@ -256,18 +433,13 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req } } -//--------------------------------------------------------------------+ -// Application Callback API Implementations -//--------------------------------------------------------------------+ - -// Invoked when audio class specific get request received for an entity -bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - audio_control_request_t const *request = (audio_control_request_t const *) p_request; +static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { + audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_CLOCK) - return tud_audio_clock_get_request(rhport, request); + return audio20_clock_get_request(rhport, request); if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) - return tud_audio_feature_unit_get_request(rhport, request); + return audio20_feature_unit_get_request(rhport, request); else { TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); @@ -275,20 +447,78 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p return false; } -// Invoked when audio class specific set request received for an entity -bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { - audio_control_request_t const *request = (audio_control_request_t const *) p_request; +static bool audio20_set_req_entity(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { + audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) - return tud_audio_feature_unit_set_request(rhport, request, buf); + return audio20_feature_unit_set_request(rhport, request, buf); if (request->bEntityID == UAC2_ENTITY_CLOCK) - return tud_audio_clock_set_request(rhport, request, buf); + return audio20_clock_set_request(rhport, request, buf); TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } +#endif // TUD_OPT_HIGH_SPEED + +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { + (void) rhport; + (void) pBuff; + + if (tud_audio_version() == 1) { + return audio10_set_req_ep(p_request, pBuff); + } else if (tud_audio_version() == 2) { + // We do not support any requests here + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_get_req_ep(rhport, p_request); + } else if (tud_audio_version() == 2) { + // We do not support any requests here + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_get_req_entity(rhport, p_request); +#if TUD_OPT_HIGH_SPEED + } else if (tud_audio_version() == 2) { + return audio20_get_req_entity(rhport, p_request); +#endif + } + + return false; +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_set_req_entity(p_request, buf); +#if TUD_OPT_HIGH_SPEED + } else if (tud_audio_version() == 2) { + return audio20_set_req_entity(rhport, p_request, buf); +#endif + } + + return false; +} + bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; @@ -380,6 +610,10 @@ void audio_control_task(void) { uint32_t btn = board_button_read(); + // Even UAC1 spec have status interrupt support like UAC2, most host do not support it + // So you have to either use UAC2 or use old day HID volume control + TU_VERIFY((tud_audio_version() == 1),); + if (!btn_prev && btn) { // Adjust volume between 0dB (100%) and -30dB (10%) for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) { @@ -387,14 +621,14 @@ void audio_control_task(void) { } // 6.1 Interrupt Data Message - const audio_interrupt_data_t data = { + const audio_interrupt_data_t data = {.v2 = { .bInfo = 0, // Class-specific interrupt, originated from an interface - .bAttribute = AUDIO_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 = AUDIO_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/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index e9165163b..a43a4bd25 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" { @@ -108,8 +108,6 @@ extern "C" { // Allow volume controlled by on-baord button #define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 1 -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_HEADSET_STEREO_DESC_LEN - // How many formats are used, need to adjust USB descriptor if changed #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 @@ -126,43 +124,48 @@ extern "C" { #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 16 -#if defined(__RX__) -// 8bit in 8bit slots -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 1 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX 8 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX 1 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 8 -#else -// 24bit in 32bit slots +// 24bit in 32bit slots (UAC2 only) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX 24 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 24 -#endif // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN 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) -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN 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) +// UAC1 (Full-Speed) Endpoint size calculation +#define CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(false, 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) + +// UAC2 (High-Speed) Endpoint size calculation +#define CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, 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) +#define CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, 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) -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device +// Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) + +// Tx flow control needs buffer size >= 4* EP size to work correctly +// Example write FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, 32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT 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) -#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT 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) +// UAC1 (Full-Speed) Endpoint size calculation +#define CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(false, 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) + +// UAC2 (High-Speed) Endpoint size calculation +#define CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(true, 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) +#define CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(true, 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) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device +// Maximum EP OUT size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT, TU_MAX(CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_OUT)) -// Size of control request buffer -#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 +// Rx flow control needs buffer size >= 4* EP size to work correctly +// Example read FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT, TU_MAX(32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_OUT, 32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_OUT)) #ifdef __cplusplus } #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 fc12c122e..e4fbbf8a5 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -34,14 +34,14 @@ * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -110,22 +110,93 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_INT 0x02 #endif -uint8_t const desc_configuration[] = +#define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_HEADSET_STEREO_DESC_LEN(2)) + +uint8_t const desc_uac1_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC1_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, bytes per sample RX/TX, bits used per sample RX/TX, EP Out & EP In address, EP sizes, sample rate + TUD_AUDIO10_HEADSET_STEREO_DESCRIPTOR(ITF_NUM_AUDIO_CONTROL, 4, \ + CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX, \ + CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX, \ + EPNUM_AUDIO_OUT, CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT, \ + EPNUM_AUDIO_IN | 0x80, CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, \ + 44100, 48000) +}; + +TU_VERIFY_STATIC(sizeof(desc_uac1_configuration) == CONFIG_UAC1_TOTAL_LEN, "Incorrect size"); + +#if TUD_OPT_HIGH_SPEED + +#define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_HEADSET_STEREO_DESC_LEN) + +uint8_t const desc_uac2_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC2_TOTAL_LEN, 0x00, 100), + + // String index, EP Out & EP In address, EP Interrupt address + TUD_AUDIO20_HEADSET_STEREO_DESCRIPTOR(5, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80, EPNUM_AUDIO_INT | 0x80) +}; + +TU_VERIFY_STATIC(sizeof(desc_uac2_configuration) == CONFIG_UAC2_TOTAL_LEN, "Incorrect size"); + + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = +{ + .bLength = sizeof(tusb_desc_device_qualifier_t), + .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, + .bcdUSB = 0x0200, + + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, - // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80, EPNUM_AUDIO_INT | 0x80) + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 }; +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const *tud_descriptor_device_qualifier_cb(void) +{ + return (uint8_t const *) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + + // if link speed is high return fullspeed config, and vice versa + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_uac1_configuration : desc_uac2_configuration; +} +#endif + // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations - return desc_configuration; +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + if(tud_speed_get() == TUSB_SPEED_FULL) { + return desc_uac1_configuration; + } else { + return desc_uac2_configuration; + } +#else + return desc_uac1_configuration; +#endif } //--------------------------------------------------------------------+ @@ -141,14 +212,14 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer - "TinyUSB headset", // 2: Product + "TinyUSB Headset", // 2: Product NULL, // 3: Serials will use unique ID if possible - "TinyUSB Speakers", // 4: Audio Interface - "TinyUSB Microphone", // 5: Audio Interface + "TinyUSB UAC1 Headset", // 4: Function + "TinyUSB UAC2 Headset", // 5: Function }; static uint16_t _desc_str[32 + 1]; diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index da0da83e8..d673beace 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -26,7 +26,17 @@ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ -// #include "tusb.h" +enum +{ + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING_SPK, + ITF_NUM_AUDIO_STREAMING_MIC, + ITF_NUM_TOTAL +}; + +//--------------------------------------------------------------------+ +// UAC2 DESCRIPTOR TEMPLATES +//--------------------------------------------------------------------+ // Unit numbers are arbitrary selected #define UAC2_ENTITY_CLOCK 0x04 @@ -38,121 +48,192 @@ #define UAC2_ENTITY_MIC_INPUT_TERMINAL 0x11 #define UAC2_ENTITY_MIC_OUTPUT_TERMINAL 0x13 -enum -{ - ITF_NUM_AUDIO_CONTROL = 0, - ITF_NUM_AUDIO_STREAMING_SPK, - ITF_NUM_AUDIO_STREAMING_MIC, - 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_AUDIO20_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) \ +#define TUD_AUDIO20_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*/ AUDIO_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*/ AUDIO_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*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_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*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_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*/ (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_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*/ AUDIO_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*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_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*/ AUDIO_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*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_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*/ _stridx),\ /* 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*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ _stridx),\ /* 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*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ - TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO_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(TUD_OPT_HIGH_SPEED, 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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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) + +//--------------------------------------------------------------------+ +// UAC1 DESCRIPTOR TEMPLATES +//--------------------------------------------------------------------+ + +// UAC1 entity IDs for speaker and microphone +// Speaker path +#define UAC1_ENTITY_SPK_INPUT_TERMINAL 0x01 +#define UAC1_ENTITY_SPK_FEATURE_UNIT 0x02 +#define UAC1_ENTITY_SPK_OUTPUT_TERMINAL 0x03 +// Microphone path +#define UAC1_ENTITY_MIC_INPUT_TERMINAL 0x11 +#define UAC1_ENTITY_MIC_OUTPUT_TERMINAL 0x13 + +#define TUD_AUDIO10_HEADSET_STEREO_DESC_LEN(_nfreqs) (\ + +TUD_AUDIO10_DESC_STD_AC_LEN\ + + TUD_AUDIO10_DESC_CS_AC_LEN(2)\ + + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)\ + + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 (speaker) */\ + + TUD_AUDIO10_DESC_STD_AS_LEN\ + /* Interface 1, Alternate 1 (speaker) */\ + + TUD_AUDIO10_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\ + /* Interface 2, Alternate 0 (microphone) */\ + + TUD_AUDIO10_DESC_STD_AS_LEN\ + /* Interface 2, Alternate 1 (microphone) */\ + + TUD_AUDIO10_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) + + +#define TUD_AUDIO10_HEADSET_STEREO_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample_RX, _nBitsUsedPerSample_RX, _nBytesPerSample_TX, _nBitsUsedPerSample_TX, _epout, _epoutsize, _epin, _epinsize, ...) \ + /* 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_FEATURE_UNIT_LEN(2)+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN+TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(1)+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN), /*_itf*/ ((_itfnum)+1), ((_itfnum)+2)),\ + /* Speaker Input Terminal Descriptor(4.3.2.1) */\ + TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC1_ENTITY_MIC_OUTPUT_TERMINAL, /*_nchannels*/ 0x02, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ + /* Speaker Feature Unit Descriptor(4.3.2.5) */\ + TUD_AUDIO10_DESC_FEATURE_UNIT(/*_unitid*/ UAC1_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_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)),\ + /* Speaker Output Terminal Descriptor(4.3.2.2) */\ + TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ UAC1_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC1_ENTITY_SPK_FEATURE_UNIT, /*_stridx*/ 0x00),\ + /* Microphone Input Terminal Descriptor(4.3.2.1) */\ + TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ UAC1_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_nchannels*/ 0x01, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ + /* Microphone Output Terminal Descriptor(4.3.2.2) */\ + TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ UAC1_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_srcid*/ UAC1_ENTITY_MIC_INPUT_TERMINAL, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.5.1) - Speaker Interface 1, Alternate 0 */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Standard AS Interface Descriptor(4.5.1) - Speaker Interface 1, Alternate 1 */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ + /* Class-Specific AS Interface Descriptor(4.5.2) */\ + TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_delay*/ 0x01, /*_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_RX, /*_bitresolution*/ _nBitsUsedPerSample_RX, /*_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_ADAPTIVE), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01, /*_syncep*/ 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),\ + /* Standard AS Interface Descriptor(4.5.1) - Microphone Interface 2, Alternate 0 */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+2), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Standard AS Interface Descriptor(4.5.1) - Microphone Interface 2, Alternate 1 */\ + TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+2), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ + /* Class-Specific AS Interface Descriptor(4.5.2) */\ + TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ UAC1_ENTITY_MIC_OUTPUT_TERMINAL, /*_delay*/ 0x01, /*_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_TX, /*_bitresolution*/ _nBitsUsedPerSample_TX, /*_freqs*/ __VA_ARGS__),\ + /* 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*/ _epinsize, /*_interval*/ 0x01, /*_syncep*/ 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) #endif diff --git a/examples/device/uac2_speaker_fb/CMakeLists.txt b/examples/device/uac2_speaker_fb/CMakeLists.txt index 0ed3db646..ced98a909 100644 --- a/examples/device/uac2_speaker_fb/CMakeLists.txt +++ b/examples/device/uac2_speaker_fb/CMakeLists.txt @@ -21,7 +21,6 @@ add_executable(${PROJECT}) target_sources(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/quirk_os_guessing.c ) # Example include diff --git a/examples/device/uac2_speaker_fb/src/common_types.h b/examples/device/uac2_speaker_fb/src/common_types.h index 174e26671..b79ae2fd0 100644 --- a/examples/device/uac2_speaker_fb/src/common_types.h +++ b/examples/device/uac2_speaker_fb/src/common_types.h @@ -41,7 +41,7 @@ typedef struct { uint32_t sample_rate; uint8_t alt_settings; - int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; + uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; uint16_t fifo_size; uint16_t fifo_count; diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index e742dc52a..f2cfb155e 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -31,25 +31,17 @@ #include "tusb.h" #include "usb_descriptors.h" -#ifdef CFG_QUIRK_OS_GUESSING - #include "quirk_os_guessing.h" -#endif - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ -// List of supported sample rates -#if defined(__RX__) -const uint32_t sample_rates[] = {44100, 48000}; -#else +// List of supported sample rates for UAC2 const uint32_t sample_rates[] = {44100, 48000, 88200, 96000}; -#endif - -uint32_t current_sample_rate = 44100; #define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates) +uint32_t current_sample_rate = 44100; + /* Blink pattern * - 25 ms : streaming data * - 250 ms : device not mounted @@ -82,7 +74,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states -int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 +uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0 // Buffer for speaker data @@ -153,18 +145,189 @@ void tud_resume_cb(void) { // Application Callback API Implementations //--------------------------------------------------------------------+ -// Helper for clock get requests -static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) { +//--------------------------------------------------------------------+ +// UAC1 Helper Functions +//--------------------------------------------------------------------+ + +static bool audio10_set_req_ep(tusb_control_request_t const *p_request, uint8_t *pBuff) { + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + + switch (ctrlSel) { + case AUDIO10_EP_CTRL_SAMPLING_FREQ: + if (p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { + // Request uses 3 bytes + TU_VERIFY(p_request->wLength == 3); + + current_sample_rate = tu_unaligned_read32(pBuff) & 0x00FFFFFF; + + TU_LOG2("EP set current freq: %" PRIu32 "\r\n", current_sample_rate); + + return true; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + + return false; +} + +static bool audio10_get_req_ep(uint8_t rhport, tusb_control_request_t const *p_request) { + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + + switch (ctrlSel) { + case AUDIO10_EP_CTRL_SAMPLING_FREQ: + if (p_request->bRequest == AUDIO10_CS_REQ_GET_CUR) { + TU_LOG2("EP get current freq\r\n"); + + uint8_t freq[3]; + freq[0] = (uint8_t) (current_sample_rate & 0xFF); + freq[1] = (uint8_t) ((current_sample_rate >> 8) & 0xFF); + freq[2] = (uint8_t) ((current_sample_rate >> 16) & 0xFF); + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, freq, sizeof(freq)); + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + + return false; +} + +static bool audio10_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // If request is for our feature unit + if (entityID == UAC1_ENTITY_FEATURE_UNIT) { + switch (ctrlSel) { + case AUDIO10_FU_CTRL_MUTE: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_SET_CUR: + // Only 1st form is supported + TU_VERIFY(p_request->wLength == 1); + + mute[channelNum] = pBuff[0]; + + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; + + default: + return false; // not supported + } + + case AUDIO10_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_SET_CUR: + // Only 1st form is supported + TU_VERIFY(p_request->wLength == 2); + + volume[channelNum] = (int16_t)tu_unaligned_read16(pBuff) / 256; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + default: + return false; // not supported + } + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + return false; +} + +static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // If request is for our feature unit + if (entityID == UAC1_ENTITY_FEATURE_UNIT) { + switch (ctrlSel) { + case AUDIO10_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); + + case AUDIO10_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO10_CS_REQ_GET_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + { + int16_t vol = (int16_t) volume[channelNum]; + vol = vol * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &vol, sizeof(vol)); + } + + case AUDIO10_CS_REQ_GET_MIN: + TU_LOG2(" Get Volume min of channel: %u\r\n", channelNum); + { + int16_t min = -90; // -90 dB + min = min * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &min, sizeof(min)); + } + + case AUDIO10_CS_REQ_GET_MAX: + TU_LOG2(" Get Volume max of channel: %u\r\n", channelNum); + { + int16_t max = 30; // +30 dB + max = max * 256; // convert to 1/256 dB units + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &max, sizeof(max)); + } + + case AUDIO10_CS_REQ_GET_RES: + TU_LOG2(" Get Volume res of channel: %u\r\n", channelNum); + { + int16_t res = 128; // 0.5 dB + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &res, sizeof(res)); + } + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + return false; +} + +//--------------------------------------------------------------------+ +// UAC2 Helper Functions +//--------------------------------------------------------------------+ + +#if TUD_OPT_HIGH_SPEED + +static bool audio20_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) { - if (request->bRequest == AUDIO_CS_REQ_CUR) { + if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { + if (request->bRequest == AUDIO20_CS_REQ_CUR) { TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); - audio_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)}; + audio20_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)}; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &curf, sizeof(curf)); - } else if (request->bRequest == AUDIO_CS_REQ_RANGE) { - audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = + } else if (request->bRequest == AUDIO20_CS_REQ_RANGE) { + audio20_control_range_4_n_t(N_SAMPLE_RATES) rangef = { .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)}; TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); @@ -177,9 +340,9 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &rangef, sizeof(rangef)); } - } else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID && - request->bRequest == AUDIO_CS_REQ_CUR) { - audio_control_cur_1_t cur_valid = {.bCur = 1}; + } else if (request->bControlSelector == AUDIO20_CS_CTRL_CLK_VALID && + request->bRequest == AUDIO20_CS_REQ_CUR) { + audio20_control_cur_1_t cur_valid = {.bCur = 1}; TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_valid, sizeof(cur_valid)); } @@ -188,17 +351,14 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t return false; } -// Helper for clock set requests -static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) { - (void) rhport; - +static bool audio20_clock_set_request(audio20_control_request_t const *request, uint8_t const *buf) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); - if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); + if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_4_t)); - current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *) buf)->bCur; + current_sample_rate = (uint32_t) ((audio20_control_cur_4_t const *) buf)->bCur; TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); @@ -210,24 +370,23 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t } } -// Helper for feature unit get requests -static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) { +static bool audio20_feature_unit_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT); - if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) { - audio_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]}; + if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE && request->bRequest == AUDIO20_CS_REQ_CUR) { + audio20_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]}; TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &mute1, sizeof(mute1)); - } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { - if (request->bRequest == AUDIO_CS_REQ_RANGE) { - audio_control_range_2_n_t(1) range_vol = { + } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { + if (request->bRequest == AUDIO20_CS_REQ_RANGE) { + audio20_control_range_2_n_t(1) range_vol = { .wNumSubRanges = tu_htole16(1), .subrange[0] = {.bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256)}}; TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &range_vol, sizeof(range_vol)); - } else if (request->bRequest == AUDIO_CS_REQ_CUR) { - audio_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])}; + } else if (request->bRequest == AUDIO20_CS_REQ_CUR) { + audio20_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])}; TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_vol, sizeof(cur_vol)); } @@ -238,25 +397,22 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req return false; } -// Helper for feature unit set requests -static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) { - (void) rhport; - +static bool audio20_feature_unit_set_request(audio20_control_request_t const *request, uint8_t const *buf) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT); - TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); - if (request->bControlSelector == AUDIO_FU_CTRL_MUTE) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t)); + if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE) { + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_1_t)); - mute[request->bChannelNumber] = ((audio_control_cur_1_t const *) buf)->bCur; + mute[request->bChannelNumber] = ((audio20_control_cur_1_t const *) buf)->bCur; TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; - } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { - TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t)); + } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { + TU_VERIFY(request->wLength == sizeof(audio20_control_cur_2_t)); - volume[request->bChannelNumber] = ((audio_control_cur_2_t const *) buf)->bCur; + volume[request->bChannelNumber] = ((audio20_control_cur_2_t const *) buf)->bCur; TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); @@ -268,14 +424,13 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req } } -// Invoked when audio class specific get request received for an entity -bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - audio_control_request_t const *request = (audio_control_request_t const *) p_request; +static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { + audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_CLOCK) - return tud_audio_clock_get_request(rhport, request); + return audio20_clock_get_request(rhport, request); if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT) - return tud_audio_feature_unit_get_request(rhport, request); + return audio20_feature_unit_get_request(rhport, request); else { TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); @@ -283,31 +438,24 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p return false; } -// Invoked when audio class specific set request received for an entity -bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { - audio_control_request_t const *request = (audio_control_request_t const *) p_request; +static bool audio20_set_req_entity(tusb_control_request_t const *p_request, uint8_t *buf) { + audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT) - return tud_audio_feature_unit_set_request(rhport, request, buf); + return audio20_feature_unit_set_request(request, buf); if (request->bEntityID == UAC2_ENTITY_CLOCK) - return tud_audio_clock_set_request(rhport, request, buf); + return audio20_clock_set_request(request, buf); TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } -bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { - (void) rhport; +#endif // TUD_OPT_HIGH_SPEED - uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); - uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); - - if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) - blink_interval_ms = BLINK_MOUNTED; - - return true; -} +//--------------------------------------------------------------------+ +// Main Callback Functions +//--------------------------------------------------------------------+ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; @@ -325,6 +473,75 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_reques return true; } +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { + (void) rhport; + (void) pBuff; + + if (tud_audio_version() == 1) { + return audio10_set_req_ep(p_request, pBuff); + } else if (tud_audio_version() == 2) { + // We do not support any requests here + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_get_req_ep(rhport, p_request); + } else if (tud_audio_version() == 2) { + // We do not support any requests here + } + + return false;// Yet not implemented +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_set_req_entity(p_request, buf); +#if TUD_OPT_HIGH_SPEED + } else if (tud_audio_version() == 2) { + return audio20_set_req_entity(p_request, buf); +#endif + } + + return false; +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + if (tud_audio_version() == 1) { + return audio10_get_req_entity(rhport, p_request); +#if TUD_OPT_HIGH_SPEED + } else if (tud_audio_version() == 2) { + return audio20_get_req_entity(rhport, p_request); +#endif + } + + return false; +} + +bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + + uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); + uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); + + if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) + blink_interval_ms = BLINK_MOUNTED; + + return true; +} + void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t *feedback_param) { (void) func_id; (void) alt_itf; @@ -349,16 +566,6 @@ bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t fu } #endif -#if CFG_QUIRK_OS_GUESSING -bool tud_audio_feedback_format_correction_cb(uint8_t func_id) { - (void) func_id; - if (tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) { - return true; - } else { - return false; - } -} -#endif //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ diff --git a/examples/device/uac2_speaker_fb/src/quirk_os_guessing.c b/examples/device/uac2_speaker_fb/src/quirk_os_guessing.c deleted file mode 100644 index 92b9ab6ee..000000000 --- a/examples/device/uac2_speaker_fb/src/quirk_os_guessing.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 HiFiPhile - * - * 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. - * - */ - -#include "quirk_os_guessing.h" - -static tusb_desc_type_t desc_req_buf[2]; -static int desc_req_idx = 0; - -// Place at the start of tud_descriptor_device_cb() -void quirk_os_guessing_desc_device_cb(void) { - desc_req_idx = 0; -} - -// Place at the start of tud_descriptor_configuration_cb() -void quirk_os_guessing_desc_configuration_cb(void) { - // Skip redundant request - if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_CONFIGURATION)) { - desc_req_buf[desc_req_idx++] = TUSB_DESC_CONFIGURATION; - } -} - -// Place at the start of tud_descriptor_bos_cb() -void quirk_os_guessing_desc_bos_cb(void) { - // Skip redundant request - if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_BOS)) { - desc_req_buf[desc_req_idx++] = TUSB_DESC_BOS; - } -} - -// Place at the start of tud_descriptor_string_cb() -void quirk_os_guessing_desc_string_cb(void) { - // Skip redundant request - if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_STRING)) { - desc_req_buf[desc_req_idx++] = TUSB_DESC_STRING; - } -} - -// Each OS request descriptors differently: -// Windows 10 - 11 -// Device Desc -// Config Desc -// BOS Desc -// String Desc -// Linux 3.16 - 6.8 -// Device Desc -// BOS Desc -// Config Desc -// String Desc -// OS X Ventura - Sonoma -// Device Desc -// String Desc -// Config Desc || BOS Desc -// BOS Desc || Config Desc -quirk_os_guessing_t quirk_os_guessing_get(void) { - if (desc_req_idx < 2) { - return QUIRK_OS_GUESSING_UNKNOWN; - } - - if (desc_req_buf[0] == TUSB_DESC_BOS && desc_req_buf[1] == TUSB_DESC_CONFIGURATION) { - return QUIRK_OS_GUESSING_LINUX; - } else if (desc_req_buf[0] == TUSB_DESC_CONFIGURATION && desc_req_buf[1] == TUSB_DESC_BOS) { - return QUIRK_OS_GUESSING_WINDOWS; - } else if (desc_req_buf[0] == TUSB_DESC_STRING && (desc_req_buf[1] == TUSB_DESC_BOS || desc_req_buf[1] == TUSB_DESC_CONFIGURATION)) { - return QUIRK_OS_GUESSING_OSX; - } - - return QUIRK_OS_GUESSING_UNKNOWN; -} diff --git a/examples/device/uac2_speaker_fb/src/quirk_os_guessing.h b/examples/device/uac2_speaker_fb/src/quirk_os_guessing.h deleted file mode 100644 index 1120355c9..000000000 --- a/examples/device/uac2_speaker_fb/src/quirk_os_guessing.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 HiFiPhile - * - * 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. - * - */ - -#ifndef _QUIRK_OS_GUESSING_H_ -#define _QUIRK_OS_GUESSING_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "tusb.h" - -//================================== !!! WARNING !!! ==================================== -// This quirk operate out of USB specification in order to workaround specific issues. -// It may not work on your platform. -//======================================================================================= -// -// Prerequisites: -// - Set USB version to at least 2.01 in Device Descriptor -// - Has a valid BOS Descriptor, refer to webusb_serial example -// -// Attention: -// Windows detection result comes out after Configuration Descriptor request, -// meaning it will be too late to do descriptor adjustment. It's advised to make -// Windows as default configuration and adjust to other OS accordingly. - -typedef enum { - QUIRK_OS_GUESSING_UNKNOWN, - QUIRK_OS_GUESSING_LINUX, - QUIRK_OS_GUESSING_OSX, - QUIRK_OS_GUESSING_WINDOWS, -} quirk_os_guessing_t; - -// Get Host OS type -quirk_os_guessing_t quirk_os_guessing_get(void); - -// Place at the start of tud_descriptor_device_cb() -void quirk_os_guessing_desc_device_cb(void); - -// Place at the start of tud_descriptor_configuration_cb() -void quirk_os_guessing_desc_configuration_cb(void); - -// Place at the start of tud_descriptor_bos_cb() -void quirk_os_guessing_desc_bos_cb(void); - -// Place at the start of tud_descriptor_string_cb() -void quirk_os_guessing_desc_string_cb(void); - -#ifdef __cplusplus - } -#endif - -#endif /* _QUIRK_OS_GUESSING_H_ */ diff --git a/examples/device/uac2_speaker_fb/src/tusb_config.h b/examples/device/uac2_speaker_fb/src/tusb_config.h index 18ab2ff96..46f5703c8 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" { @@ -87,14 +87,6 @@ extern "C" { #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif -/* (Needed for Full-Speed only) - * Enable host OS guessing to workaround UAC2 compatibility issues between Windows and OS X - * The default configuration only support Windows and Linux, enable this option for OS X - * support. Otherwise if you don't need Windows support you can make OS X's configuration as - * default. - */ -#define CFG_QUIRK_OS_GUESSING 1 - //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- @@ -128,38 +120,33 @@ extern "C" { // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_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 +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 -// Audio format type I specifications -#if defined(__RX__) -#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 -#else -#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000 -#endif +// 16bit data in 16bit slots +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2 +#define CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX 16 -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 +// UAC1 Full-Speed endpoint size +#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_FS 48000 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS TUD_AUDIO_EP_SIZE(false, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_FS, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +// UAC2 High-Speed endpoint size +#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_HS 96000 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_HS, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -// 16bit in 16bit slots -#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2 -#define CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX 16 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS) -// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) -#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 +// AUDIO_FEEDBACK_METHOD_FIFO_COUNT needs buffer size >= 4* EP size to work correctly +// Example read FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS, 32 * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device +// Enable OUT EP +#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 // Enable feedback EP -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 1 - -// Size of control request buffer -#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 1 #ifdef __cplusplus } #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 ee1b92225..697e51483 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -28,28 +28,24 @@ #include "usb_descriptors.h" #include "common_types.h" -#ifdef CFG_QUIRK_OS_GUESSING -#include "quirk_os_guessing.h" -#endif - /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0201, + .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) @@ -71,12 +67,8 @@ tusb_desc_device_t const desc_device = // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ -#if CFG_QUIRK_OS_GUESSING - quirk_os_guessing_desc_device_cb(); -#endif - return (uint8_t const *)&desc_device; +uint8_t const * tud_descriptor_device_cb(void) { + return (uint8_t const *) &desc_device; } #if CFG_AUDIO_DEBUG @@ -84,8 +76,7 @@ uint8_t const * tud_descriptor_device_cb(void) // HID Report Descriptor //--------------------------------------------------------------------+ -uint8_t const desc_hid_report[] = -{ +uint8_t const desc_hid_report[] = { HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\ HID_USAGE ( 0x01 ),\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ @@ -101,8 +92,7 @@ uint8_t const desc_hid_report[] = // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) -{ +uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) { (void) itf; return desc_hid_report; } @@ -112,109 +102,126 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) // Configuration Descriptor //--------------------------------------------------------------------+ -#if CFG_AUDIO_DEBUG - #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_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) -#endif - #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 // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_AUDIO 0x03 #define EPNUM_AUDIO_FB 0x03 - #define EPNUM_AUDIO_OUT 0x03 #define EPNUM_DEBUG 0x04 -#elif CFG_TUSB_MCU == OPT_MCU_NRF5X - // ISO endpoints for NRF5x are fixed to 0x08 (0x88) +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) + // nRF5x ISO can only be endpoint 8 + #define EPNUM_AUDIO 0x08 #define EPNUM_AUDIO_FB 0x08 - #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_DEBUG 0x01 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO 0x02 #define EPNUM_AUDIO_FB 0x01 - #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_DEBUG 0x03 #else + #define EPNUM_AUDIO 0x01 #define EPNUM_AUDIO_FB 0x01 - #define EPNUM_AUDIO_OUT 0x01 #define EPNUM_DEBUG 0x02 #endif -uint8_t const desc_configuration_default[] = -{ - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), +#if CFG_AUDIO_DEBUG + #define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_SPEAKER_STEREO_FB_DESC_LEN(2) + TUD_HID_DESC_LEN) +#else + #define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_SPEAKER_STEREO_FB_DESC_LEN(2)) +#endif + +uint8_t const desc_uac1_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC1_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), + // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, sample rates (44.1kHz, 48kHz) + TUD_AUDIO10_SPEAKER_STEREO_FB_DESCRIPTOR(ITF_NUM_AUDIO_CONTROL, 5, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS, EPNUM_AUDIO_FB | 0x80, 44100, 48000), #if CFG_AUDIO_DEBUG - // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) #endif }; -#if CFG_QUIRK_OS_GUESSING -// OS X needs 3 bytes feedback endpoint on FS -uint8_t const desc_configuration_osx_fs[] = -{ - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), +TU_VERIFY_STATIC(sizeof(desc_uac1_configuration) == CONFIG_UAC1_TOTAL_LEN, "Incorrect size"); - // 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), +#if TUD_OPT_HIGH_SPEED #if CFG_AUDIO_DEBUG - // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) -#endif -}; + #define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN + TUD_HID_DESC_LEN) +#else + #define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN) #endif -// Invoked when received GET CONFIGURATION DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ - (void)index; // for multiple configurations +uint8_t const desc_uac2_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC2_TOTAL_LEN, 0x00, 100), -#if CFG_QUIRK_OS_GUESSING - quirk_os_guessing_desc_configuration_cb(); - if(tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) { - return desc_configuration_osx_fs; - } -#endif - return desc_configuration_default; -} + // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size, + TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR(ITF_NUM_AUDIO_CONTROL, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS, EPNUM_AUDIO_FB | 0x80, 4), -//--------------------------------------------------------------------+ -// BOS Descriptor, required for OS guessing quirk -//--------------------------------------------------------------------+ +#if CFG_AUDIO_DEBUG + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) +#endif +}; -#define TUD_BOS_USB20_EXT_DESC_LEN 7 +TU_VERIFY_STATIC(sizeof(desc_uac2_configuration) == CONFIG_UAC2_TOTAL_LEN, "Incorrect size"); -#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_USB20_EXT_DESC_LEN) +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, -// BOS Descriptor is required for webUSB -uint8_t const desc_bos[] = -{ - // total length, number of device caps - TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, - // USB 2.0 Extension Descriptor - 0x07, TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_USB20_EXTENSION, 0x00, 0x00, 0x00,0x00 + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 }; -uint8_t const * tud_descriptor_bos_cb(void) -{ -#if CFG_QUIRK_OS_GUESSING - quirk_os_guessing_desc_bos_cb(); +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const *tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const *) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index;// for multiple configurations + + // if link speed is high return fullspeed config, and vice versa + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_uac1_configuration : desc_uac2_configuration; +} + +#endif // highspeed + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + if(tud_speed_get() == TUSB_SPEED_FULL) { + return desc_uac1_configuration; + } else { + return desc_uac2_configuration; + } +#else + return desc_uac1_configuration; #endif - return desc_bos; } //--------------------------------------------------------------------+ @@ -230,13 +237,14 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Speaker", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2 Speaker", // 4: Audio Interface + "UAC1 Speaker", // 5: UAC1 Audio Interface }; static uint16_t _desc_str[32 + 1]; @@ -247,10 +255,6 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; -#if CFG_QUIRK_OS_GUESSING - quirk_os_guessing_desc_string_cb(); -#endif - switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.h b/examples/device/uac2_speaker_fb/src/usb_descriptors.h index 9511bf797..b0ec60ea1 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.h +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.h @@ -26,57 +26,145 @@ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ -// Defined in TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR +//--------------------------------------------------------------------+ +// UAC2 DESCRIPTOR TEMPLATES +//--------------------------------------------------------------------+ + +// 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*/ AUDIO_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*/ AUDIO_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*/ AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO_CTRL_RW << AUDIO_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*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_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*/ AUDIO_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*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_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*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO_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*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_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_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(2)\ + + 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(_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), /*_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_UNDEFINED, /*_lockdelay*/ 0x0000),\ + /* Standard AS Isochronous Synch Endpoint Descriptor (4.6.2.1) */\ + TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP(/*_ep*/ _epfb, /*_bRefresh*/ 0) + +//---------------------------------------------------------------------------+ +// UAC1 Isochronous Synch Endpoint bRefresh Workaround +// +// bRefresh value is set to 0, while UAC1 spec requires it to be between +// 1 (2 ms) and 9 (512 ms) +// +// This value has been tested to work with Windows, macOS and Linux. +// +// Rationale: +// Some USB device controllers (e.g. Synopsys DWC2) require a known transfer +// interval to manually schedule isochronous IN transfers. For data isochronous +// endpoints, the bInterval field in the endpoint descriptor is used. However, +// for synch endpoint it's unclear which field the host uses to determine the +// transfer interval. Windows and macOS use bRefresh, while Linux uses bInterval. +// +// Since bInterval is fixed to 1, if bRefresh is set to 2 then Windows and macOS +// will schedule the feedback transfer every 4 ms, but Linux will schedule it +// every 1 ms. DWC2 controller cannot handle this discrepancy without knwowing +// the actual interval, therefore we set bRefresh to 0 to let the transfer +// execute every 1 ms, which is the same as bInterval. +// +// Rant: +// WTF USB-IF? Why have two fields that mean the same thing? Why not just use +// bInterval for both data and synch endpoints? Why is bRefresh even necessary? +// +// Note: +// For the moment DWC2 driver doesn't have proper support for bInterval > 1 +// for isochronous IN endpoints. The implementation would be complex and CPU +// intensive (cfr. +// https://github.com/torvalds/linux/blob/master/drivers/usb/dwc2/gadget.c) +// It MAY work in some cases if you are lucky, but it's not guaranteed. +//---------------------------------------------------------------------------+ #endif diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 85acd990a..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) << (n) ) -#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 @@ -44,7 +44,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -112,7 +112,7 @@ enum #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_USBTMC_DESC_LEN) -uint8_t const desc_fs_configuration[] = +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -122,7 +122,7 @@ uint8_t const desc_fs_configuration[] = #if TUD_OPT_HIGH_SPEED -uint8_t const desc_hs_configuration[] = +static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -131,10 +131,10 @@ uint8_t const desc_hs_configuration[] = }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, @@ -158,6 +158,23 @@ uint8_t const* tud_descriptor_device_qualifier_cb(void) return (uint8_t const*) &desc_device_qualifier; } +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + + // if link speed is high return fullspeed config, and vice versa + // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG + memcpy(desc_other_speed_config, + (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, + CONFIG_TOTAL_LEN); + + desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; + + return desc_other_speed_config; +} + #endif // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -187,7 +204,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer 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 b3e19b0f0..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) << (n) ) -#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 @@ -63,7 +63,7 @@ char const* string_desc_arr[] = { //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -384,7 +384,7 @@ static uint8_t * get_hs_configuration_desc(void) { } // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = { +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, 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 e78e452fc..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) << (n) ) -#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 @@ -68,7 +68,7 @@ char const* string_desc_arr[] = { //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -551,7 +551,7 @@ static uint8_t * get_hs_configuration_desc(void) { } // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = { +static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, 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 2b69a5b56..0ef41a68e 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -33,14 +33,14 @@ * Auto ProductID layout's Bitmap: * [MSB] MIDI | HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#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 //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -228,7 +228,7 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = +static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer |
