From 53a65344fc7a553de2615d3a0d4f5cdce7f1d014 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 14 Mar 2023 11:48:54 +0000 Subject: [PATCH 1/2] Improve mixer control protocol to avoid deadlock --- lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc | 32 +++++++++++++++---- lib_xua/src/core/mixer/mixer.xc | 12 ++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc b/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc index 24f3502c..7ff9cedb 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc +++ b/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc @@ -155,6 +155,8 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl) #if (OUT_VOLUME_IN_MIXER) if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, SET_MIX_OUT_VOL); outuint(c_mix_ctl, i-1); outuint(c_mix_ctl, x); @@ -181,6 +183,8 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl) #if (IN_VOLUME_IN_MIXER) if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, SET_MIX_IN_VOL); outuint(c_mix_ctl, i-1); outuint(c_mix_ctl, x); @@ -228,6 +232,8 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl) #if (OUT_VOLUME_IN_MIXER) if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, SET_MIX_OUT_VOL); outuint(c_mix_ctl, channel-1); outuint(c_mix_ctl, x); @@ -250,6 +256,8 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl) #if (IN_VOLUME_IN_MIXER) if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, SET_MIX_IN_VOL); outuint(c_mix_ctl, channel-1); outuint(c_mix_ctl, x); @@ -267,6 +275,8 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl) void UpdateMixerOutputRouting(chanend c_mix_ctl, unsigned map, unsigned dst, unsigned src) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, map); outuint(c_mix_ctl, dst); outuint(c_mix_ctl, src); @@ -275,6 +285,8 @@ void UpdateMixerOutputRouting(chanend c_mix_ctl, unsigned map, unsigned dst, uns void UpdateMixMap(chanend c_mix_ctl, int mix, int input, int src) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, SET_MIX_MAP); outuint(c_mix_ctl, mix); /* Mix bus */ outuint(c_mix_ctl, input); /* Mixer input (cn) */ @@ -284,6 +296,8 @@ void UpdateMixMap(chanend c_mix_ctl, int mix, int input, int src) void UpdateMixerWeight(chanend c_mix_ctl, int mix, int index, unsigned mult) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, SET_MIX_MULT); outuint(c_mix_ctl, mix); outuint(c_mix_ctl, index); @@ -561,7 +575,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) { volsOut[ sp.wValue&0xff ] = (buffer, unsigned char[])[0] | (((int) (signed char) (buffer, unsigned char[])[1]) << 8); - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); return XUD_DoSetRequestStatus(ep0_in); } } @@ -570,7 +584,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) { volsIn[ sp.wValue&0xff ] = (buffer, unsigned char[])[0] | (((int) (signed char) (buffer, unsigned char[])[1]) << 8); - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); return XUD_DoSetRequestStatus(ep0_in); } } @@ -1014,6 +1028,8 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, GET_STREAM_LEVELS); outuint(c_mix_ctl, i); outct(c_mix_ctl, XS1_CT_END); @@ -1029,6 +1045,8 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, GET_INPUT_LEVELS); outuint(c_mix_ctl, (i - NUM_USB_CHAN_OUT)); outct(c_mix_ctl, XS1_CT_END); @@ -1051,6 +1069,8 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { if (!isnull(c_mix_ctl)) { + outct(c_mix_ctl, XS1_CT_END); + inct(c_mix_ctl); outuint(c_mix_ctl, GET_OUTPUT_LEVELS); outuint(c_mix_ctl, i); outct(c_mix_ctl, XS1_CT_END); @@ -1198,12 +1218,12 @@ XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket { case FU_USBOUT: volsOut[ sp.wValue & 0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); return XUD_DoSetRequestStatus(ep0_in); case FU_USBIN: volsIn[ sp.wValue & 0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); return XUD_DoSetRequestStatus(ep0_in); } } @@ -1217,12 +1237,12 @@ XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket { case FU_USBOUT: mutesOut[ sp.wValue & 0xff ] = buffer[0]; - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); return XUD_DoSetRequestStatus(ep0_in); case FU_USBIN: mutesIn[ sp.wValue & 0xff ] = buffer[0]; - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); return XUD_DoSetRequestStatus(ep0_in); } } diff --git a/lib_xua/src/core/mixer/mixer.xc b/lib_xua/src/core/mixer/mixer.xc index db19d0d0..cd00124c 100644 --- a/lib_xua/src/core/mixer/mixer.xc +++ b/lib_xua/src/core/mixer/mixer.xc @@ -361,6 +361,7 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) #endif #if (MAX_MIX_COUNT > 0) || (IN_VOLUME_IN_MIXER) || (OUT_VOLUME_IN_MIXER) || defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS) unsigned cmd; + unsigned char ct; #endif unsigned request = 0; @@ -381,9 +382,18 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) #if (MAX_MIX_COUNT > 0) || (IN_VOLUME_IN_MIXER) || (OUT_VOLUME_IN_MIXER) || defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS) select { - case inuint_byref(c_mix_ctl, cmd): + /* Check if EP0 intends to send us a control command */ + case inct_byref(c_mix_ctl, ct): { int mix, index, val; + + /* Handshake back to tell EP0 we are ready for an update */ + outct(c_mix_ctl, XS1_CT_END); + + /* Receive command from EP0 */ + cmd = inuint(c_mix_ctl); + + /* Interpret control command */ switch (cmd) { #if (MAX_MIX_COUNT > 0) From 7703fc1a7d254806297b65b19bf3276218ac6140 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 14 Mar 2023 11:49:08 +0000 Subject: [PATCH 2/2] Fixed build warning when mixer not enabled --- lib_xua/src/core/mixer/fastmix.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_xua/src/core/mixer/fastmix.S b/lib_xua/src/core/mixer/fastmix.S index 6a04a84e..49f91c7f 100644 --- a/lib_xua/src/core/mixer/fastmix.S +++ b/lib_xua/src/core/mixer/fastmix.S @@ -11,6 +11,8 @@ #error #endif +#if (MAX_MIX_COUNT > 0) + #define DOMIX_TOP(i) \ .cc_top doMix##i.function,doMix##i; \ .align 16 ;\ @@ -180,5 +182,5 @@ setPtr_go: #undef N #undef BODY - +#endif