forked from PAWPAW-Mirror/lib_xua
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:
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user