Clock selection tidies and improvements (#355)

- Tidy up use of “tmp” variable when setting digital stream clock validity
- Simplify clock selection values
- Add better checks to clock selection
- Removed un-required clock selection code based on ADAT/SPDIF enabled
This commit is contained in:
Ross Owen
2023-12-06 16:08:00 +00:00
committed by GitHub
parent 1f74f8c601
commit b0db22a50b
4 changed files with 67 additions and 71 deletions

View File

@@ -1,13 +1,11 @@
// Copyright 2018-2022 XMOS LIMITED. // Copyright 2018-2023 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
unsigned adatCounter = 0; unsigned adatCounter = 0;
unsigned adatSamples[8]; unsigned adatSamples[8];
#pragma unsafe arrays #pragma unsafe arrays
static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samplesFromHost[], int smux, int handshake) static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samplesFromHost[], int smux, int handshake)
{ {
/* Do some re-arranging for SMUX.. */ /* Do some re-arranging for SMUX.. */
unsafe unsafe
{ {
@@ -29,7 +27,6 @@ static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samp
if(adatCounter == smux) if(adatCounter == smux)
{ {
#ifdef ADAT_TX_USE_SHARED_BUFF #ifdef ADAT_TX_USE_SHARED_BUFF
unsafe unsafe
{ {

View File

@@ -232,7 +232,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
unsigned clkMode = CLOCK_INTERNAL; /* Current clocking mode in operation */ unsigned clkMode = CLOCK_INTERNAL; /* Current clocking mode in operation */
unsigned tmp; unsigned tmp;
/* start in no-SMUX (8-channel) mode */ /* Start in no-SMUX (8-channel) mode */
int smux = 0; int smux = 0;
#ifdef LEVEL_METER_LEDS #ifdef LEVEL_METER_LEDS
@@ -281,21 +281,21 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
} }
/* Init clock unit state */ /* Init clock unit state */
clockFreq[CLOCK_INTERNAL] = 0;
clockId[CLOCK_INTERNAL] = ID_CLKSRC_INT;
clockValid[CLOCK_INTERNAL] = 0;
clockInt[CLOCK_INTERNAL] = 0;
#if (XUA_SPDIF_RX_EN) #if (XUA_SPDIF_RX_EN)
clockFreq[CLOCK_SPDIF_INDEX] = 0; clockFreq[CLOCK_SPDIF] = 0;
clockValid[CLOCK_SPDIF_INDEX] = 0; clockValid[CLOCK_SPDIF] = 0;
clockInt[CLOCK_SPDIF_INDEX] = 0; clockInt[CLOCK_SPDIF] = 0;
clockId[CLOCK_SPDIF_INDEX] = ID_CLKSRC_SPDIF; clockId[CLOCK_SPDIF] = ID_CLKSRC_SPDIF;
#endif #endif
clockFreq[CLOCK_INTERNAL_INDEX] = 0;
clockId[CLOCK_INTERNAL_INDEX] = ID_CLKSRC_INT;
clockValid[CLOCK_INTERNAL_INDEX] = 0;
clockInt[CLOCK_INTERNAL_INDEX] = 0;
#if (XUA_ADAT_RX_EN) #if (XUA_ADAT_RX_EN)
clockFreq[CLOCK_ADAT_INDEX] = 0; clockFreq[CLOCK_ADAT] = 0;
clockInt[CLOCK_ADAT_INDEX] = 0; clockInt[CLOCK_ADAT] = 0;
clockValid[CLOCK_ADAT_INDEX] = 0; clockValid[CLOCK_ADAT] = 0;
clockId[CLOCK_ADAT_INDEX] = ID_CLKSRC_ADAT; clockId[CLOCK_ADAT] = ID_CLKSRC_ADAT;
#endif #endif
#if (XUA_SPDIF_RX_EN) #if (XUA_SPDIF_RX_EN)
spdifCounters.receivedSamples = 0; spdifCounters.receivedSamples = 0;
@@ -389,13 +389,9 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
case SET_SEL: case SET_SEL:
/* Update clock mode */ /* Update clock mode */
tmp = inuint(c_clk_ctl); clkMode = inuint(c_clk_ctl);
chkct(c_clk_ctl, XS1_CT_END); chkct(c_clk_ctl, XS1_CT_END);
if(tmp!=0)
{
clkMode = tmp;
}
#ifdef CLOCK_VALIDITY_CALL #ifdef CLOCK_VALIDITY_CALL
switch(clkMode) switch(clkMode)
{ {
@@ -404,12 +400,12 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
break; break;
#if (XUA_ADAT_RX_EN) #if (XUA_ADAT_RX_EN)
case CLOCK_ADAT: case CLOCK_ADAT:
VendorClockValidity(clockValid[CLOCK_ADAT_INDEX]); VendorClockValidity(clockValid[CLOCK_ADAT]);
break; break;
#endif #endif
#if (XUA_SPDIF_RX_EN) #if (XUA_SPDIF_RX_EN)
case CLOCK_SPDIF: case CLOCK_SPDIF:
VendorClockValidity(clockValid[CLOCK_SPDIF_INDEX]); VendorClockValidity(clockValid[CLOCK_SPDIF]);
break; break;
#endif #endif
} }
@@ -483,25 +479,23 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
#endif #endif
break; break;
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) #if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
case t_external when timerafter(timeNextClockDetection) :> void: case t_external when timerafter(timeNextClockDetection) :> void:
{
timeNextClockDetection += (LOCAL_CLOCK_INCREMENT); int valid;
timeNextClockDetection += (LOCAL_CLOCK_INCREMENT);
#if (XUA_SPDIF_RX_EN) #if (XUA_SPDIF_RX_EN)
tmp = spdifCounters.samplesPerTick; /* Returns 1 if valid clock found */
valid = validSamples(spdifCounters, CLOCK_SPDIF);
/* Returns 1 if valid clock found */ setClockValidity(c_clk_int, CLOCK_SPDIF, valid, clkMode);
tmp = validSamples(spdifCounters, CLOCK_SPDIF_INDEX);
setClockValidity(c_clk_int, CLOCK_SPDIF_INDEX, tmp, clkMode);
#endif #endif
#if (XUA_ADAT_RX_EN) #if (XUA_ADAT_RX_EN)
tmp = validSamples(adatCounters, CLOCK_ADAT_INDEX); /* Returns 1 if valid clock found */
setClockValidity(c_clk_int, CLOCK_ADAT_INDEX, tmp, clkMode); valid = validSamples(adatCounters, CLOCK_ADAT);
setClockValidity(c_clk_int, CLOCK_ADAT, valid, clkMode);
#endif #endif
}
break; break;
#endif #endif
#if (XUA_SPDIF_RX_EN) #if (XUA_SPDIF_RX_EN)
@@ -530,7 +524,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
case SPDIF_FRAME_Y: case SPDIF_FRAME_Y:
/* Only store sample if not in overflow and stream is reasonably valid */ /* Only store sample if not in overflow and stream is reasonably valid */
if(!spdifOverflow && clockValid[CLOCK_SPDIF_INDEX]) if(!spdifOverflow && clockValid[CLOCK_SPDIF])
{ {
/* Store left and right sample pair to buffer */ /* Store left and right sample pair to buffer */
spdifSamples[spdifWr] = spdifLeft; spdifSamples[spdifWr] = spdifLeft;
@@ -562,7 +556,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
spdifCounters.samples += 1; spdifCounters.samples += 1;
if(clkMode == CLOCK_SPDIF && clockValid[CLOCK_SPDIF_INDEX]) if(clkMode == CLOCK_SPDIF && clockValid[CLOCK_SPDIF])
{ {
spdifCounters.receivedSamples+=1; spdifCounters.receivedSamples+=1;
@@ -611,7 +605,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
if (adatChannel == 8) if (adatChannel == 8)
{ {
/* only store left samples if not in overflow and stream is reasonably valid */ /* only store left samples if not in overflow and stream is reasonably valid */
if (!adatOverflow && clockValid[CLOCK_ADAT_INDEX]) if (!adatOverflow && clockValid[CLOCK_ADAT])
{ {
/* Unpick the SMUX.. */ /* Unpick the SMUX.. */
if(smux == 2) if(smux == 2)
@@ -668,7 +662,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
{ {
adatCounters.samples += 1; adatCounters.samples += 1;
if (clkMode == CLOCK_ADAT && clockValid[CLOCK_ADAT_INDEX]) if (clkMode == CLOCK_ADAT && clockValid[CLOCK_ADAT])
{ {
adatCounters.receivedSamples += 1; adatCounters.receivedSamples += 1;
@@ -738,7 +732,6 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
spdifOverflow = 0; spdifOverflow = 0;
} }
} }
#endif #endif
#if (XUA_ADAT_RX_EN) #if (XUA_ADAT_RX_EN)
if (adatUnderflow) if (adatUnderflow)

View File

@@ -456,34 +456,35 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
(buffer, unsigned char[])[0] = 1; (buffer, unsigned char[])[0] = 1;
return XUD_DoGetRequest(ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength); return XUD_DoGetRequest(ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength);
break; break;
#if (XUA_SPDIF_RX_EN)
case ID_CLKSRC_SPDIF: case ID_CLKSRC_SPDIF:
/* Interogate clockgen thread for validity */ /* Interogate clockgen thread for validity */
if (!isnull(c_clk_ctl)) if (!isnull(c_clk_ctl))
{ {
outuint(c_clk_ctl, GET_VALID); outuint(c_clk_ctl, GET_VALID);
outuint(c_clk_ctl, CLOCK_SPDIF_INDEX); outuint(c_clk_ctl, CLOCK_SPDIF);
outct(c_clk_ctl, XS1_CT_END); outct(c_clk_ctl, XS1_CT_END);
(buffer, unsigned char[])[0] = inuint(c_clk_ctl); (buffer, unsigned char[])[0] = inuint(c_clk_ctl);
chkct(c_clk_ctl, XS1_CT_END); chkct(c_clk_ctl, XS1_CT_END);
return XUD_DoGetRequest(ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength); return XUD_DoGetRequest(ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength);
} }
break; break;
#endif
#if (XUA_ADAT_RX_EN)
case ID_CLKSRC_ADAT: case ID_CLKSRC_ADAT:
if (!isnull(c_clk_ctl)) if (!isnull(c_clk_ctl))
{ {
outuint(c_clk_ctl, GET_VALID); outuint(c_clk_ctl, GET_VALID);
outuint(c_clk_ctl, CLOCK_ADAT_INDEX); outuint(c_clk_ctl, CLOCK_ADAT);
outct(c_clk_ctl, XS1_CT_END); outct(c_clk_ctl, XS1_CT_END);
(buffer, unsigned char[])[0] = inuint(c_clk_ctl); (buffer, unsigned char[])[0] = inuint(c_clk_ctl);
chkct(c_clk_ctl, XS1_CT_END); chkct(c_clk_ctl, XS1_CT_END);
return XUD_DoGetRequest(ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength); return XUD_DoGetRequest(ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength);
} }
break; break;
#endif
default: default:
//Unknown Unit ID in Clock Valid Control Request //Unknown Unit ID in Clock Valid Control Request
@@ -513,19 +514,23 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
return result; return result;
} }
/* Check for correct datalength for clock sel */
if(datalength == 1) if(datalength == 1)
{ {
if (!isnull(c_clk_ctl)) int clockIndex = (int) (buffer, unsigned char[])[0];
{ clockIndex -= 1; /* Index to/from host is 1-based */
outuint(c_clk_ctl, SET_SEL);
outuint(c_clk_ctl, (buffer, unsigned char[])[0]);
outct(c_clk_ctl, XS1_CT_END);
}
/* Send 0 Length as status stage */
return XUD_DoSetRequestStatus(ep0_in);
}
if((clockIndex >= 0) && (clockIndex < CLOCK_COUNT))
{
if(!isnull(c_clk_ctl))
{
outuint(c_clk_ctl, SET_SEL);
outuint(c_clk_ctl, clockIndex);
outct(c_clk_ctl, XS1_CT_END);
}
/* Send 0 Length as status stage */
return XUD_DoSetRequestStatus(ep0_in);
}
}
} }
else else
{ {
@@ -533,13 +538,15 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
(buffer, unsigned char[])[0] = 1; (buffer, unsigned char[])[0] = 1;
if (!isnull(c_clk_ctl)) if (!isnull(c_clk_ctl))
{ {
int clockIndex;
outuint(c_clk_ctl, GET_SEL); outuint(c_clk_ctl, GET_SEL);
outct(c_clk_ctl, XS1_CT_END); outct(c_clk_ctl, XS1_CT_END);
(buffer, unsigned char[])[0] = inuint(c_clk_ctl); clockIndex = inuint(c_clk_ctl);
clockIndex += 1; /* Index to/from host is 1-based */
(buffer, unsigned char[])[0] = (unsigned char) clockIndex;
chkct(c_clk_ctl, XS1_CT_END); chkct(c_clk_ctl, XS1_CT_END);
} }
return XUD_DoGetRequest( ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength ); return XUD_DoGetRequest( ep0_out, ep0_in, (buffer, unsigned char[]), 1, sp.wLength);
} }
} }
break; break;

View File

@@ -10,20 +10,19 @@
#define SET_SEL 1 /* Set value of clock selector */ #define SET_SEL 1 /* Set value of clock selector */
#define GET_FREQ 2 /* Get current freq */ #define GET_FREQ 2 /* Get current freq */
#define GET_VALID 3 /* Get current validity */ #define GET_VALID 3 /* Get current validity */
#define SET_SMUX 7 /* Set SMUX mode (ADAT) */
#define CLOCK_INTERNAL 1 enum
#define CLOCK_SPDIF 2 {
#if (XUA_SPDIF_RX_EN) CLOCK_INTERNAL = 0,
#define CLOCK_ADAT 3 #if XUA_SPDIF_RX_EN
#else CLOCK_SPDIF,
#define CLOCK_ADAT 2
#endif #endif
#if XUA_ADAT_RX_EN
#define CLOCK_INTERNAL_INDEX (CLOCK_INTERNAL - 1) CLOCK_ADAT,
#define CLOCK_ADAT_INDEX (CLOCK_ADAT - 1) #endif
#define CLOCK_SPDIF_INDEX (CLOCK_SPDIF - 1) CLOCK_COUNT
};
#define SET_SMUX 7
/* c_audioControl */ /* c_audioControl */
#define SET_SAMPLE_FREQ 4 #define SET_SAMPLE_FREQ 4