Update UAC2 naming

Signed-off-by: HiFiPhile <admin@hifiphile.com>
This commit is contained in:
HiFiPhile
2025-09-27 14:58:08 +02:00
committed by Mengsk
parent 24bc2ff57a
commit 78121a8d3f
16 changed files with 1114 additions and 739 deletions

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -80,7 +80,7 @@ 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
audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state
// Audio test data
@ -195,7 +195,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);
@ -215,7 +215,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);
@ -242,25 +242,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 == 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] = (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;
@ -275,10 +275,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);
@ -342,9 +342,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
// 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 +366,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 +409,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 +437,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));

View File

@ -64,15 +64,15 @@
/* Standard AC Interface Descriptor(4.7.1) */\
TUD_AUDIO_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_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\
/* 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_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS | AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS, /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC2_ENTITY_INPUT_TERMINAL, /*_srcid*/ UAC2_ENTITY_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ UAC2_ENTITY_FEATURE_UNIT, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\
/* 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),\
@ -80,23 +80,23 @@
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
#endif

View File

@ -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);

View File

@ -93,19 +93,19 @@ enum
/* Standard AC Interface Descriptor(4.7.1) */\
TUD_AUDIO_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_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\
/* Clock Source Descriptor(4.7.2.1) */\
TUD_AUDIO_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_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
/* 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),\
@ -113,23 +113,23 @@ enum
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\
/* 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),\
@ -137,22 +137,22 @@ enum
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
#endif

View File

@ -142,17 +142,17 @@ void tud_resume_cb(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->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 +165,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 +177,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 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) {
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 +199,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 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) {
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 +227,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 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) {
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);
@ -262,7 +262,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);
@ -277,7 +277,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);
@ -387,11 +387,11 @@ void audio_control_task(void) {
}
// 6.1 Interrupt Data Message
const audio_interrupt_data_t data = {
const audio20_interrupt_data_t data = {
.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
};

View File

@ -91,19 +91,19 @@ enum
/* Standard AC Interface Descriptor(4.7.1) */\
TUD_AUDIO_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_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\
/* Clock Source Descriptor(4.7.2.1) */\
TUD_AUDIO_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_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
/* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */\
TUD_AUDIO_DESC_STD_AC_INT_EP(/*_ep*/ _epint, /*_interval*/ 0x01), \
/* Standard AS Interface Descriptor(4.9.1) */\
@ -113,23 +113,23 @@ enum
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\
/* 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),\
@ -137,22 +137,22 @@ enum
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* 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),\
/* 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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
#endif

View File

@ -154,17 +154,17 @@ void tud_resume_cb(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->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 %lu\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 +177,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));
}
@ -189,16 +189,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 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) {
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: %ld\r\n", current_sample_rate);
@ -211,23 +211,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 tud_audio_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));
}
@ -239,24 +239,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 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_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);
@ -270,7 +270,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);
@ -285,7 +285,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_FEATURE_UNIT)
return tud_audio_feature_unit_set_request(rhport, request, buf);

View File

@ -53,15 +53,15 @@
/* Standard AC Interface Descriptor(4.7.1) */\
TUD_AUDIO_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_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\
/* 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_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO20_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\
/* 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_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO20_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_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS,/*_stridx*/ 0x00),\
/* 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),\
@ -69,13 +69,13 @@
/* 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),\
/* 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_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_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),\
/* 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_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\
/* 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)\