Add in timestamp machinery
This commit is contained in:
@@ -25,8 +25,15 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_sync);
|
||||
* \param c_clk_ctl channel connected to Endpoint0() for configuration of the
|
||||
* clock
|
||||
* \param c_clk_int channel connected to the decouple() thread for clock
|
||||
interrupts
|
||||
* interrupts
|
||||
* \param p_for_mclk_count_aud port used for counting mclk and providing a timestamp
|
||||
*/
|
||||
void clockGen(streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interface pll_ref_if i_pll_ref, chanend c_audio, chanend c_clk_ctl, chanend c_clk_int);
|
||||
void clockGen( streaming chanend ?c_spdif_rx,
|
||||
chanend ?c_adat_rx,
|
||||
client interface pll_ref_if i_pll_ref,
|
||||
chanend c_audio,
|
||||
chanend c_clk_ctl,
|
||||
chanend c_clk_int,
|
||||
port ?p_for_mclk_count_aud);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,7 +8,14 @@
|
||||
#include "xua_commands.h"
|
||||
#include "xua_clocking.h"
|
||||
|
||||
|
||||
#ifdef __XS3A__
|
||||
#define USE_SW_PLL 1
|
||||
#else
|
||||
#define USE_SW_PLL 0
|
||||
#endif
|
||||
|
||||
#if USE_SW_PLL
|
||||
extern "C"
|
||||
{
|
||||
#include "sw_pll.h"
|
||||
@@ -45,6 +52,7 @@ static int clockValid[NUM_CLOCKS]; /* Store current val
|
||||
static int clockInt[NUM_CLOCKS]; /* Interupt flag for clocks */
|
||||
static int clockId[NUM_CLOCKS];
|
||||
|
||||
|
||||
[[distributable]]
|
||||
void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_pll_ref)
|
||||
{
|
||||
@@ -86,6 +94,17 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_pll_ref)
|
||||
}
|
||||
}
|
||||
|
||||
void do_sw_pll_control(sw_pll_state_t sw_pll, unsigned short mclk_time_stamp, chanend c_sigma_delta)
|
||||
{
|
||||
static unsigned count = 0;
|
||||
count++;
|
||||
if(count == 30)
|
||||
{
|
||||
printuintln(mclk_time_stamp);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN)
|
||||
static int abs(int x)
|
||||
@@ -222,6 +241,72 @@ static inline int validSamples(Counter &counter, int clockIndex)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_SW_PLL
|
||||
void SigmaDeltaTask(chanend c_sigma_delta){
|
||||
while(1)
|
||||
{
|
||||
c_sigma_delta :> int _;
|
||||
}
|
||||
}
|
||||
|
||||
void InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk)
|
||||
{
|
||||
/* Autogenerated SDM App PLL setup by dco_model.py using 22.5792_1M profile */
|
||||
/* Input freq: 24000000
|
||||
F: 134
|
||||
R: 0
|
||||
f: 8
|
||||
p: 18
|
||||
OD: 5
|
||||
ACD: 5
|
||||
*/
|
||||
|
||||
#define APP_PLL_CTL_REG_22 0x0A808600
|
||||
#define APP_PLL_DIV_REG_22 0x80000005
|
||||
#define APP_PLL_FRAC_REG_22 0x80000812
|
||||
#define SW_PLL_SDM_CTRL_MID_22 498283
|
||||
#define SW_PLL_SDM_RATE_22 1000000
|
||||
|
||||
/* Autogenerated SDM App PLL setup by dco_model.py using 24.576_1M profile */
|
||||
/* Input freq: 24000000
|
||||
F: 146
|
||||
R: 0
|
||||
f: 4
|
||||
p: 10
|
||||
OD: 5
|
||||
ACD: 5
|
||||
*/
|
||||
|
||||
#define APP_PLL_CTL_REG_24 0x0A809200
|
||||
#define APP_PLL_DIV_REG_24 0x80000005
|
||||
#define APP_PLL_FRAC_REG_24 0x8000040A
|
||||
#define SW_PLL_SDM_CTRL_MID_24 478151
|
||||
#define SW_PLL_SDM_RATE_24 1000000
|
||||
|
||||
|
||||
const uint32_t app_pll_ctl_reg[2] = {APP_PLL_CTL_REG_22, APP_PLL_CTL_REG_24};
|
||||
const uint32_t app_pll_div_reg[2] = {APP_PLL_DIV_REG_22, APP_PLL_DIV_REG_24};
|
||||
const uint32_t app_pll_frac_reg[2] = {APP_PLL_FRAC_REG_22, APP_PLL_FRAC_REG_24};
|
||||
const uint32_t sw_pll_sdm_ctrl_mid[2] = {SW_PLL_SDM_CTRL_MID_22, SW_PLL_SDM_CTRL_MID_24};
|
||||
// const uint32_t sw_pll_sdm_rate[2] = {SW_PLL_SDM_RATE_22, SW_PLL_SDM_RATE_24};
|
||||
|
||||
const int clkIndex = mClk == MCLK_48 ? 1 : 0;
|
||||
|
||||
sw_pll_sdm_init(&sw_pll,
|
||||
SW_PLL_15Q16(0.0),
|
||||
SW_PLL_15Q16(32.0),
|
||||
SW_PLL_15Q16(0.25),
|
||||
0, /* LOOP COUNT Don't care for this API */
|
||||
0, /* PLL_RATIO Don't care for this API */
|
||||
0, /* No jitter compensation needed */
|
||||
app_pll_ctl_reg[clkIndex],
|
||||
app_pll_div_reg[clkIndex],
|
||||
app_pll_frac_reg[clkIndex],
|
||||
sw_pll_sdm_ctrl_mid[clkIndex],
|
||||
3000 /* PPM_RANGE FOR PFD Don't care for this API*/ );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEVEL_METER_LEDS
|
||||
void VendorLedRefresh(unsigned levelData[]);
|
||||
unsigned g_inputLevelData[NUM_USB_CHAN_IN];
|
||||
@@ -232,7 +317,13 @@ extern int samples_to_host_inputs_buff[NUM_USB_CHAN_IN];
|
||||
int VendorAudCoreReqs(unsigned cmd, chanend c);
|
||||
|
||||
#pragma unsafe arrays
|
||||
void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interface pll_ref_if i_pll_ref, chanend c_dig_rx, chanend c_clk_ctl, chanend c_clk_int)
|
||||
void clockGen ( streaming chanend ?c_spdif_rx,
|
||||
chanend ?c_adat_rx,
|
||||
client interface pll_ref_if i_pll_ref,
|
||||
chanend c_dig_rx,
|
||||
chanend c_clk_ctl,
|
||||
chanend c_clk_int,
|
||||
port ?p_for_mclk_count_aud)
|
||||
{
|
||||
timer t_local;
|
||||
unsigned timeNextEdge, timeLastEdge, timeNextClockDetection;
|
||||
@@ -249,6 +340,9 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
|
||||
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
timer t_external;
|
||||
unsigned short mclk_time_stamp = 0;
|
||||
/* Get MCLK count */
|
||||
asm volatile(" getts %0, res[%1]" : "=r" (mclk_time_stamp) : "r" (p_for_mclk_count_aud));
|
||||
#endif
|
||||
|
||||
#if (XUA_SPDIF_RX_EN)
|
||||
@@ -340,9 +434,21 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
|
||||
/* Initial ref clock output and get timestamp */
|
||||
i_pll_ref.init();
|
||||
|
||||
#if USE_SW_PLL
|
||||
chan c_sigma_delta;
|
||||
sw_pll_state_t sw_pll;
|
||||
InitSWPLL(sw_pll, MCLK_48);
|
||||
|
||||
par
|
||||
{
|
||||
SigmaDeltaTask(c_sigma_delta);
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
while(1)
|
||||
{
|
||||
// TMP
|
||||
c_sigma_delta <: 0;
|
||||
select
|
||||
{
|
||||
#ifdef LEVEL_METER_LEDS
|
||||
@@ -513,6 +619,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
|
||||
case c_spdif_rx :> spdifRxData:
|
||||
|
||||
/* Record time of sample */
|
||||
asm volatile(" getts %0, res[%1]" : "=r" (mclk_time_stamp) : "r" (p_for_mclk_count_aud));
|
||||
t_local :> spdifRxTime;
|
||||
|
||||
/* Check parity and ignore if bad */
|
||||
@@ -582,10 +689,12 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
|
||||
/* Setup for next edge */
|
||||
timeNextEdge = spdifRxTime + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
|
||||
|
||||
#if USE_SW_PLL
|
||||
do_sw_pll_control(sw_pll, mclk_time_stamp, c_sigma_delta);
|
||||
#else
|
||||
/* Toggle edge */
|
||||
i_pll_ref.toggle_timed(1);
|
||||
printstr("s\n");
|
||||
|
||||
#endif
|
||||
/* Reset counters */
|
||||
spdifCounters.receivedSamples = 0;
|
||||
}
|
||||
@@ -597,6 +706,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
|
||||
/* receive sample from ADAT rx thread (streaming channel with CT_END) */
|
||||
case inuint_byref(c_adat_rx, tmp):
|
||||
/* record time of sample */
|
||||
asm volatile(" getts %0, res[%1]" : "=r" (mclk_time_stamp) : "r" (p_for_mclk_count_aud));
|
||||
t_local :> adatReceivedTime;
|
||||
|
||||
/* Sync is: 1 | (user_byte << 4) */
|
||||
@@ -689,10 +799,13 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
|
||||
/* Setup for next edge */
|
||||
timeNextEdge = adatReceivedTime + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
|
||||
|
||||
#if USE_SW_PLL
|
||||
do_sw_pll_control(sw_pll, mclk_time_stamp, c_sigma_delta);
|
||||
#else
|
||||
/* Toggle edge */
|
||||
i_pll_ref.toggle_timed(1);
|
||||
printstr("a\n");
|
||||
|
||||
#endif
|
||||
|
||||
/* Reset counters */
|
||||
adatCounters.receivedSamples = 0;
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ on tile[XUD_TILE] : in port p_spdif_rx = PORT_SPDIF_IN;
|
||||
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) || (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
/* Reference to external clock multiplier */
|
||||
on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF;
|
||||
on tile[AUDIO_IO_TILE] : port p_for_mclk_count_aud = PORT_MCLK_COUNT_2;
|
||||
#endif
|
||||
|
||||
#ifdef MIDI
|
||||
@@ -309,6 +310,7 @@ void usb_audio_io(chanend ?c_aud_in,
|
||||
#endif
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
, port p_for_mclk_count_aud
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -318,6 +320,12 @@ void usb_audio_io(chanend ?c_aud_in,
|
||||
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
chan c_dig_rx;
|
||||
|
||||
/* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/
|
||||
unsigned x = 0;
|
||||
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
||||
asm("setclk res[%0], %1"::"r"(p_for_mclk_count_aud), "r"(x));
|
||||
|
||||
#else
|
||||
#define c_dig_rx null
|
||||
#endif
|
||||
@@ -385,7 +393,7 @@ void usb_audio_io(chanend ?c_aud_in,
|
||||
* However, due to the use of an interface the pll reference signal port can be on another tile
|
||||
*/
|
||||
thread_speed();
|
||||
clockGen(c_spdif_rx, c_adat_rx, i_pll_ref, c_dig_rx, c_clk_ctl, c_clk_int);
|
||||
clockGen(c_spdif_rx, c_adat_rx, i_pll_ref, c_dig_rx, c_clk_ctl, c_clk_int, p_for_mclk_count_aud);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -437,7 +445,7 @@ int main()
|
||||
#define c_adat_rx null
|
||||
#endif
|
||||
|
||||
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
chan c_spdif_tx;
|
||||
#endif
|
||||
|
||||
@@ -575,6 +583,7 @@ int main()
|
||||
|
||||
on tile[AUDIO_IO_TILE]:
|
||||
{
|
||||
|
||||
/* Audio I/O task, includes mixing etc */
|
||||
usb_audio_io(c_mix_out
|
||||
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
@@ -595,6 +604,7 @@ int main()
|
||||
#endif
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
, i_pll_ref
|
||||
, p_for_mclk_count_aud
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user