forked from PAWPAW-Mirror/lib_xua
Compare commits
23 Commits
v3.5.0
...
experiment
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd8d2675d3 | ||
|
|
7930a5d59c | ||
|
|
158d79335c | ||
|
|
ebc09e1c4f | ||
|
|
a7943a8859 | ||
|
|
77fad35497 | ||
|
|
50966dda90 | ||
|
|
e7b5faed66 | ||
|
|
7f72c4b842 | ||
|
|
d119755313 | ||
|
|
2228575e09 | ||
|
|
b6972295e9 | ||
|
|
39802f3620 | ||
|
|
5bf53fa453 | ||
|
|
2f11eda7d8 | ||
|
|
1574137dda | ||
|
|
c7e782179c | ||
|
|
badcb71c80 | ||
|
|
dff72573f8 | ||
|
|
aaaf1e9652 | ||
|
|
d6b23cf960 | ||
|
|
fa8329edaa | ||
|
|
83d86e885f |
@@ -1,6 +1,15 @@
|
||||
lib_xua Change Log
|
||||
==================
|
||||
|
||||
3.5.1
|
||||
-----
|
||||
|
||||
* FIXED: Respect I2S_CHANS_PER_FRAME when calculating bit-clock rates
|
||||
|
||||
* Changes to dependencies:
|
||||
|
||||
- lib_spdif: 5.0.0 -> 5.0.1
|
||||
|
||||
3.5.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2017-2022 XMOS LIMITED.
|
||||
// Copyright 2017-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <xs1.h>
|
||||
#include <platform.h>
|
||||
#include "xua.h"
|
||||
#include "../../shared/apppll.h"
|
||||
|
||||
on tile[0]: out port p_ctrl = XS1_PORT_8D;
|
||||
|
||||
@@ -35,11 +34,6 @@ void ctrlPort()
|
||||
void AudioHwInit()
|
||||
{
|
||||
/* Wait for power supply to come up */
|
||||
delay_milliseconds(100);
|
||||
|
||||
/* Use xCORE Secondary PLL to generate *fixed* master clock */
|
||||
AppPllEnable_SampleRate(DEFAULT_FREQ);
|
||||
|
||||
delay_milliseconds(100);
|
||||
|
||||
/* DAC setup: For basic I2S input we don't need any register setup. DACs will clock auto detect etc.
|
||||
@@ -48,9 +42,12 @@ void AudioHwInit()
|
||||
*/
|
||||
}
|
||||
|
||||
/* Configures the external audio hardware for the required sample frequency */
|
||||
/* Configures the external audio hardware for the required sample frequency
|
||||
* Note, the application PLL in xcore.ai will be configured to the correct master clock frequency
|
||||
* by lib_xua
|
||||
*/
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
||||
{
|
||||
AppPllEnable_SampleRate(samFreq);
|
||||
/* Nothing required since the DAC's will auto detect the sample rate from the clocks */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2017-2022 XMOS LIMITED.
|
||||
// Copyright 2017-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <xs1.h>
|
||||
#include <platform.h>
|
||||
#include "xua.h"
|
||||
#include "../../shared/apppll.h"
|
||||
|
||||
on tile[0]: out port p_ctrl = XS1_PORT_8D;
|
||||
|
||||
@@ -35,11 +34,6 @@ void ctrlPort()
|
||||
void AudioHwInit()
|
||||
{
|
||||
/* Wait for power supply to come up */
|
||||
delay_milliseconds(100);
|
||||
|
||||
/* Use xCORE Secondary PLL to generate *fixed* master clock */
|
||||
AppPllEnable_SampleRate(DEFAULT_FREQ);
|
||||
|
||||
delay_milliseconds(100);
|
||||
|
||||
/* DAC setup: For basic I2S input we don't need any register setup. DACs will clock auto detect etc.
|
||||
@@ -48,9 +42,12 @@ void AudioHwInit()
|
||||
*/
|
||||
}
|
||||
|
||||
/* Configures the external audio hardware for the required sample frequency */
|
||||
/* Configures the external audio hardware for the required sample frequency
|
||||
* Note, the application PLL in xcore.ai will be configured to the correct master clock frequency
|
||||
* by lib_xua
|
||||
*/
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
||||
{
|
||||
AppPllEnable_SampleRate(samFreq);
|
||||
/* Nothing required since the DAC's will auto detect the sample rate from the clocks */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
// Copyright 2022 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <stdint.h>
|
||||
#include "xassert.h"
|
||||
|
||||
// App PLL setup
|
||||
#define APP_PLL_CTL_BYPASS (0) // 0 = no bypass, 1 = bypass.
|
||||
#define APP_PLL_CTL_INPUT_SEL (0) // 0 = XTAL, 1 = sysPLL
|
||||
#define APP_PLL_CTL_ENABLE (1) // 0 = disabled, 1 = enabled.
|
||||
|
||||
// 24MHz in, 24.576MHz out, integer mode
|
||||
// Found exact solution: IN 24000000.0, OUT 24576000.0, VCO 2457600000.0, RD 5, FD 512, OD 10, FOD 10
|
||||
#define APP_PLL_CTL_OD_48 (4) // Output divider = (OD+1)
|
||||
#define APP_PLL_CTL_F_48 (511) // FB divider = (F+1)/2
|
||||
#define APP_PLL_CTL_R_48 (4) // Ref divider = (R+1)
|
||||
|
||||
#define APP_PLL_CTL_48 ((APP_PLL_CTL_BYPASS << 29) | (APP_PLL_CTL_INPUT_SEL << 28) | (APP_PLL_CTL_ENABLE << 27) |\
|
||||
(APP_PLL_CTL_OD_48 << 23) | (APP_PLL_CTL_F_48 << 8) | APP_PLL_CTL_R_48)
|
||||
|
||||
// Fractional divide is M/N
|
||||
#define APP_PLL_FRAC_EN_48 (0) // 0 = disabled
|
||||
#define APP_PLL_FRAC_NPLUS1_CYCLES_48 (0) // M value is this reg value + 1.
|
||||
#define APP_PLL_FRAC_TOTAL_CYCLES_48 (0) // N value is this reg value + 1.
|
||||
#define APP_PLL_FRAC_48 ((APP_PLL_FRAC_EN_48 << 31) | (APP_PLL_FRAC_NPLUS1_CYCLES_48 << 8) | APP_PLL_FRAC_TOTAL_CYCLES_48)
|
||||
|
||||
// 24MHz in, 22.5792MHz out (44.1kHz * 512), frac mode
|
||||
// Found exact solution: IN 24000000.0, OUT 22579200.0, VCO 2257920000.0, RD 5, FD 470.400 (m = 2, n = 5), OD 5, FOD 10
|
||||
#define APP_PLL_CTL_OD_441 (4) // Output divider = (OD+1)
|
||||
#define APP_PLL_CTL_F_441 (469) // FB divider = (F+1)/2
|
||||
#define APP_PLL_CTL_R_441 (4) // Ref divider = (R+1)
|
||||
|
||||
#define APP_PLL_CTL_441 ((APP_PLL_CTL_BYPASS << 29) | (APP_PLL_CTL_INPUT_SEL << 28) | (APP_PLL_CTL_ENABLE << 27) |\
|
||||
(APP_PLL_CTL_OD_441 << 23) | (APP_PLL_CTL_F_441 << 8) | APP_PLL_CTL_R_441)
|
||||
|
||||
#define APP_PLL_FRAC_EN_44 (1) // 1 = enabled
|
||||
#define APP_PLL_FRAC_NPLUS1_CYCLES_44 (1) // M value is this reg value + 1.
|
||||
#define APP_PLL_FRAC_TOTAL_CYCLES_44 (4) // N value is this reg value + 1.define APP_PLL_CTL_R_441 (4) // Ref divider = (R+1)
|
||||
#define APP_PLL_FRAC_44 ((APP_PLL_FRAC_EN_44 << 31) | (APP_PLL_FRAC_NPLUS1_CYCLES_44 << 8) | APP_PLL_FRAC_TOTAL_CYCLES_44)
|
||||
|
||||
#define APP_PLL_DIV_INPUT_SEL (1) // 0 = sysPLL, 1 = app_PLL
|
||||
#define APP_PLL_DIV_DISABLE (0) // 1 = disabled (pin connected to X1D11), 0 = enabled divider output to pin.
|
||||
#define APP_PLL_DIV_VALUE (4) // Divide by N+1 - remember there's a /2 also afterwards for 50/50 duty cycle.
|
||||
#define APP_PLL_DIV ((APP_PLL_DIV_INPUT_SEL << 31) | (APP_PLL_DIV_DISABLE << 16) | APP_PLL_DIV_VALUE)
|
||||
|
||||
/* TODO support more than two freqs..*/
|
||||
void AppPllEnable(int32_t clkFreq_hz)
|
||||
{
|
||||
switch(clkFreq_hz)
|
||||
{
|
||||
case 44100*512:
|
||||
|
||||
// Disable the PLL
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, (APP_PLL_CTL_441 & 0xF7FFFFFF));
|
||||
// Enable the PLL to invoke a reset on the appPLL.
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_441);
|
||||
// Must write the CTL register twice so that the F and R divider values are captured using a running clock.
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_441);
|
||||
// Now disable and re-enable the PLL so we get the full 5us reset time with the correct F and R values.
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, (APP_PLL_CTL_441 & 0xF7FFFFFF));
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_441);
|
||||
|
||||
// Set the fractional divider if used
|
||||
write_node_config_reg(tile[0], XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, APP_PLL_FRAC_44);
|
||||
|
||||
break;
|
||||
|
||||
case 48000*512:
|
||||
|
||||
// Disable the PLL
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, (APP_PLL_CTL_48 & 0xF7FFFFFF));
|
||||
// Enable the PLL to invoke a reset on the appPLL.
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_48);
|
||||
// Must write the CTL register twice so that the F and R divider values are captured using a running clock.
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_48);
|
||||
// Now disable and re-enable the PLL so we get the full 5us reset time with the correct F and R values.
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, (APP_PLL_CTL_48 & 0xF7FFFFFF));
|
||||
write_node_config_reg(tile[1], XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_48);
|
||||
|
||||
// Set the fractional divider if used
|
||||
write_node_config_reg(tile[0], XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, APP_PLL_FRAC_48);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for PLL output frequency to stabilise due to fractional divider enable
|
||||
delay_microseconds(100);
|
||||
|
||||
// Turn on the clock output
|
||||
write_node_config_reg(tile[0], XS1_SSWITCH_SS_APP_CLK_DIVIDER_NUM, APP_PLL_DIV);
|
||||
}
|
||||
|
||||
void AppPllEnable_SampleRate(int32_t sampleRate_hz)
|
||||
{
|
||||
assert(sampleRate_hz >= 22050);
|
||||
|
||||
if(sampleRate_hz % 22050 == 0)
|
||||
{
|
||||
AppPllEnable(44100*512);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppPllEnable(48000*512);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "dfu_interface.h"
|
||||
#endif
|
||||
|
||||
#include "xua_clocking.h"
|
||||
|
||||
/** The audio driver thread.
|
||||
*
|
||||
* This function drives I2S ports and handles samples to/from other digital
|
||||
@@ -34,6 +36,8 @@
|
||||
*
|
||||
* \param p_i2s_adc Nullable array of ports for I2S data input lines
|
||||
*
|
||||
* \param i_SoftPll Interface to software PLL task
|
||||
*
|
||||
* \param c_spdif_tx Channel connected to S/PDIF transmiter core from lib_spdif
|
||||
*
|
||||
* \param c_dig Channel connected to the clockGen() thread for
|
||||
@@ -47,6 +51,9 @@ void XUA_AudioHub(chanend ?c_aud,
|
||||
buffered _XUA_CLK_DIR port:32 ?p_bclk,
|
||||
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
||||
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
|
||||
#if (XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||
, client interface SoftPll_if i_SoftPll
|
||||
#endif
|
||||
#if (XUA_SPDIF_TX_EN) || defined(__DOXYGEN__)
|
||||
, chanend c_spdif_tx
|
||||
#endif
|
||||
@@ -63,21 +70,28 @@ void XUA_AudioHub(chanend ?c_aud,
|
||||
|
||||
void SpdifTxWrapper(chanend c_spdif_tx);
|
||||
|
||||
/* These functions must be implemented for the CODEC/ADC/DAC arrangement of a specific design */
|
||||
|
||||
/* Any required clocking and CODEC initialisation - run once at start up */
|
||||
/* TODO Provide default implementation of this */
|
||||
void AudioHwInit();
|
||||
|
||||
/* Configure audio hardware (clocking, CODECs etc) for a specific mClk/Sample frquency - run on every sample frequency change */
|
||||
/* TODO Provide default implementation of this */
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode,
|
||||
unsigned sampRes_DAC, unsigned sampRes_ADC);
|
||||
|
||||
#endif // __XC__
|
||||
|
||||
void UserBufferManagementInit();
|
||||
|
||||
/**
|
||||
* @brief User buffer management code
|
||||
*
|
||||
* This function is called at the sample rate of the USB Audio stack (e.g,. 48 kHz) and between the two parameter arrays
|
||||
* contain a full multi-channel audio-frame. The first array carries all the data that has been received from the USB host
|
||||
* and is to be presented to the audio interfaces. The second array carries all the data received from the interfaces and
|
||||
* is to be presented to the USB host. The user can chose to intercept and overwrite the samples stored in these arrays.
|
||||
*
|
||||
* \param sampsFromUsbToAudio Samples received from USB host and to be presented to audio interfaces
|
||||
*
|
||||
* \param sampsFromAudioToUsb Samples received from the audio interfaces and to be presented to the USB host
|
||||
*/
|
||||
void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]);
|
||||
|
||||
/**
|
||||
* @brief User buffer managment init code
|
||||
*
|
||||
* This function is called once, before the first call to UserBufferManagement(), and can be used to initialise any
|
||||
* related user state
|
||||
*/
|
||||
void UserBufferManagementInit();
|
||||
|
||||
#endif // _XUA_AUDIOHUB_H_
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2011-2022 XMOS LIMITED.
|
||||
// Copyright 2011-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#ifndef __XUA_BUFFER_H__
|
||||
#define __XUA_BUFFER_H__
|
||||
#ifndef _XUA_BUFFER_H_
|
||||
#define _XUA_BUFFER_H_
|
||||
|
||||
#if __XC__
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself)
|
||||
* \param c_aud Channel connected to XUA_AudioHub() core
|
||||
* \param i_pll_ref Interface to task that toggles reference pin to CS2100
|
||||
* \param c_swpll_update Channel connected to software PLL task. Expects master clock counts based on USB frames.
|
||||
*/
|
||||
void XUA_Buffer(
|
||||
chanend c_aud_out,
|
||||
@@ -51,8 +52,13 @@ void XUA_Buffer(
|
||||
, chanend c_hid
|
||||
#endif
|
||||
, chanend c_aud
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOXYGEN__)
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOYXGEN__)
|
||||
#if (!XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
#endif
|
||||
#if (XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||
, chanend c_swpll_update
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -81,10 +87,16 @@ void XUA_Buffer_Ep(chanend c_aud_out,
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
, chanend c_buff_ctrl
|
||||
#endif
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOXYGEN__)
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOYXGEN__)
|
||||
#if (!XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
#endif
|
||||
#if (XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||
, chanend c_swpll_update
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
/** Manage the data transfer between the USB audio buffer and the
|
||||
* Audio I/O driver.
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2011-2022 XMOS LIMITED.
|
||||
// Copyright 2011-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#ifndef _CLOCKING_H_
|
||||
#define _CLOCKING_H_
|
||||
|
||||
#include <xs1.h>
|
||||
#include "xua.h"
|
||||
|
||||
interface pll_ref_if
|
||||
{
|
||||
@@ -28,5 +29,46 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_sync);
|
||||
interrupts
|
||||
*/
|
||||
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);
|
||||
|
||||
#if (XUA_USE_APP_PLL)
|
||||
struct SoftPllState
|
||||
{
|
||||
// Count we expect on MCLK port timer at SW PLL check point.
|
||||
// Note, we expect wrapping so this is essentiually a modulus
|
||||
unsigned expectedClkMod;
|
||||
unsigned initialSetting;
|
||||
unsigned initialErrorMult;
|
||||
unsigned setting;
|
||||
|
||||
int phaseError;
|
||||
|
||||
/* Integrated phase error */
|
||||
int phaseErrorInt;
|
||||
|
||||
/* IIR filter */
|
||||
int iir_y;
|
||||
|
||||
/* Delta sigma modulator */
|
||||
unsigned ds_in;
|
||||
int ds_x1;
|
||||
int ds_x2;
|
||||
int ds_x3;
|
||||
};
|
||||
|
||||
void AppPllEnable(tileref tile, int mclkFreq_hz);
|
||||
void AppPllGetSettings(int clkFreq_hz, struct SoftPllState &pllState);
|
||||
void AppPllUpdate(tileref tile, unsigned short mclk_pt, struct SoftPllState &pllState);
|
||||
|
||||
interface SoftPll_if
|
||||
{
|
||||
void init(int mclk_hz);
|
||||
};
|
||||
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
||||
[[distributable]]
|
||||
#endif
|
||||
void XUA_SoftPll(tileref tile, server interface SoftPll_if i_softPll, chanend c_update);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include "xua_conf.h"
|
||||
#endif
|
||||
|
||||
/* Default tile arrangement */
|
||||
/*
|
||||
* Tile arrangement defines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Location (tile) of audio I/O. Default: 0
|
||||
@@ -55,12 +57,9 @@
|
||||
#define PLL_REF_TILE AUDIO_IO_TILE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Disable USB functionalty just leaving AudioHub
|
||||
/*
|
||||
* Channel based defines
|
||||
*/
|
||||
#ifndef XUA_USB_EN
|
||||
#define XUA_USB_EN (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of input channels (device to host). Default: NONE (Must be defined by app)
|
||||
@@ -79,7 +78,18 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of DSD output channels. Default: 0 (disabled)
|
||||
* @brief Number of PDM microphones in the design.
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#ifndef XUA_NUM_PDM_MICS
|
||||
#define XUA_NUM_PDM_MICS (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of DSD output channels.
|
||||
*
|
||||
* Default: 0 (disabled)
|
||||
*/
|
||||
#if defined(DSD_CHANS_DAC) && (DSD_CHANS_DAC != 0)
|
||||
#if defined(NATIVE_DSD) && (NATIVE_DSD == 0)
|
||||
@@ -91,6 +101,34 @@
|
||||
#define DSD_CHANS_DAC 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of I2S channesl to DAC/CODEC. Must be a multiple of 2.
|
||||
*
|
||||
* Default: NONE (Must be defined by app)
|
||||
*/
|
||||
#ifndef I2S_CHANS_DAC
|
||||
#error I2S_CHANS_DAC not defined
|
||||
#define I2S_CHANS_DAC 2 /* Define anyway for doxygen */
|
||||
#else
|
||||
#define I2S_WIRES_DAC (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of I2S channels from ADC/CODEC. Must be a multiple of 2.
|
||||
*
|
||||
* Default: NONE (Must be defined by app)
|
||||
*/
|
||||
#ifndef I2S_CHANS_ADC
|
||||
#error I2S_CHANS_ADC not defined
|
||||
#define I2S_CHANS_ADC 2 /* Define anyway for doxygen */
|
||||
#else
|
||||
#define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Defines relating to the interface to external audio hardware i.e. DAC/ADC
|
||||
*/
|
||||
|
||||
#define XUA_PCM_FORMAT_I2S (0)
|
||||
#define XUA_PCM_FORMAT_TDM (1)
|
||||
/**
|
||||
@@ -120,30 +158,17 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Number of IS2 channesl to DAC/CODEC. Must be a multiple of 2.
|
||||
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
||||
*
|
||||
* Default: NONE (Must be defined by app)
|
||||
* Default: 32 bits
|
||||
*/
|
||||
#ifndef I2S_CHANS_DAC
|
||||
#error I2S_CHANS_DAC not defined
|
||||
#define I2S_CHANS_DAC 2 /* Define anyway for doxygen */
|
||||
#else
|
||||
#define I2S_WIRES_DAC (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)
|
||||
#ifndef XUA_I2S_N_BITS
|
||||
#define XUA_I2S_N_BITS (32)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Number of I2S channels from ADC/CODEC. Must be a multiple of 2.
|
||||
*
|
||||
* Default: NONE (Must be defined by app)
|
||||
*/
|
||||
#ifndef I2S_CHANS_ADC
|
||||
#error I2S_CHANS_ADC not defined
|
||||
#define I2S_CHANS_ADC 2 /* Define anyway for doxygen */
|
||||
#else
|
||||
#define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME)
|
||||
#if (XUA_I2S_N_BITS != 16) && (XUA_I2S_N_BITS != 32)
|
||||
#error Unsupported value for XUA_I2S_N_BITS (only values 16/32 supported)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -197,35 +222,32 @@
|
||||
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
||||
*
|
||||
* Default: 32 bits
|
||||
/*
|
||||
* Clocking related defines
|
||||
*/
|
||||
#ifndef XUA_I2S_N_BITS
|
||||
#define XUA_I2S_N_BITS (32)
|
||||
#endif
|
||||
|
||||
#if (XUA_I2S_N_BITS != 16) && (XUA_I2S_N_BITS != 32)
|
||||
#error Unsupported value for XUA_I2S_N_BITS (only values 16/32 supported)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Max supported sample frequency for device (Hz). Default: 192000
|
||||
* @brief Max supported sample frequency for device (Hz).
|
||||
*
|
||||
* Default: 192000Hz
|
||||
*/
|
||||
#ifndef MAX_FREQ
|
||||
#define MAX_FREQ (192000)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Min supported sample frequency for device (Hz). Default 44100
|
||||
* @brief Min supported sample frequency for device (Hz).
|
||||
*
|
||||
* Default: 44100Hz
|
||||
*/
|
||||
#ifndef MIN_FREQ
|
||||
#define MIN_FREQ (44100)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Master clock defines for 44100 rates (in Hz). Default: NONE (Must be defined by app)
|
||||
* @brief Master clock defines for 44100 rates (in Hz).
|
||||
*
|
||||
* Default: NONE (Must be defined by app)
|
||||
*/
|
||||
#ifndef MCLK_441
|
||||
#error MCLK_441 not defined
|
||||
@@ -233,7 +255,9 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Master clock defines for 48000 rates (in Hz). Default: NONE (Must be defined by app)
|
||||
* @brief Master clock defines for 48000 rates (in Hz).
|
||||
*
|
||||
* Default: NONE (Must be defined by app)
|
||||
*/
|
||||
#ifndef MCLK_48
|
||||
#error MCLK_48 not defined
|
||||
@@ -241,26 +265,66 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default device sample frequency. A safe default should be used. Default: MIN_FREQ
|
||||
* @brief Enable/disable the use of the secondary/application PLL for generating master-clocks.
|
||||
* Only available on xcore.ai devices.
|
||||
*
|
||||
* Default: Enabled (for xcore.ai devices)
|
||||
*/
|
||||
#ifndef XUA_USE_APP_PLL
|
||||
#if defined(__XS3A__)
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
/* Currently must use an external CS2100 device for syncing to external digital streams */
|
||||
#define XUA_USE_APP_PLL (0)
|
||||
#else
|
||||
#define XUA_USE_APP_PLL (1)
|
||||
#endif
|
||||
#else
|
||||
#define XUA_USE_APP_PLL (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default device sample frequency. A safe default should be used.
|
||||
*
|
||||
* Default: MIN_FREQ
|
||||
*/
|
||||
#ifndef DEFAULT_FREQ
|
||||
#define DEFAULT_FREQ (MIN_FREQ)
|
||||
#endif
|
||||
|
||||
/* Audio Class Defines */
|
||||
#define DEFAULT_MCLK (((DEFAULT_FREQ % 7350) == 0) ? MCLK_441 : MCLK_48)
|
||||
|
||||
/**
|
||||
* @brief USB Audio Class Version. Default: 2 (Audio Class version 2.0)
|
||||
* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
||||
*
|
||||
* 0: XMOS is I2S master. 1: CODEC is I2s master.
|
||||
*
|
||||
* Default: 0 (XMOS is master)
|
||||
*/
|
||||
#ifndef CODEC_MASTER
|
||||
#define CODEC_MASTER (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Audio Class defines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB Audio Class Version
|
||||
*
|
||||
* Default: 2 (Audio Class version 2.0)
|
||||
*/
|
||||
#ifndef AUDIO_CLASS
|
||||
#define AUDIO_CLASS 2
|
||||
#define AUDIO_CLASS (2)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Whether or not to fall back to Audio Class 1.0 in USB Full-speed. Default: 0 (Disabled)
|
||||
* @brief Enable/disable fall back to Audio Class 1.0 in USB Full-speed.
|
||||
*
|
||||
* Default: Disabled
|
||||
*/
|
||||
#ifndef AUDIO_CLASS_FALLBACK
|
||||
#define AUDIO_CLASS_FALLBACK 0 /* Default to not falling back to UAC 1 */
|
||||
#define AUDIO_CLASS_FALLBACK (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -289,14 +353,17 @@
|
||||
#error AUDIO_CLASS set to 1 and FULL_SPEED_AUDIO_2 enabled!
|
||||
#endif
|
||||
|
||||
|
||||
/* Feature defines */
|
||||
/*
|
||||
* Feature defines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Number of PDM microphones in the design. Default: None
|
||||
* @brief Disable USB functionalty just leaving AudioHub
|
||||
*
|
||||
* Default: Enabled
|
||||
*/
|
||||
#ifndef XUA_NUM_PDM_MICS
|
||||
#define XUA_NUM_PDM_MICS (0)
|
||||
#ifndef XUA_USB_EN
|
||||
#define XUA_USB_EN (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -461,12 +528,11 @@
|
||||
* You must also supply your own function to deal with the HID endpoint(s)
|
||||
* in this case.
|
||||
*/
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if (HID_CONTROLS) || defined (__DOXYGEN__)
|
||||
#define XUA_HID_ENABLED (1)
|
||||
#define XUA_OR_STATIC_HID_ENABLED (1)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__static_hid_report_h_exists__)
|
||||
#define XUA_OR_STATIC_HID_ENABLED (1)
|
||||
#endif
|
||||
@@ -482,17 +548,6 @@
|
||||
#define HID_OUT_REQUIRED (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
||||
*
|
||||
* 0: XMOS is I2S master. 1: CODEC is I2s master.
|
||||
*
|
||||
* Default: 0 (XMOS is master)
|
||||
*/
|
||||
#ifndef CODEC_MASTER
|
||||
#define CODEC_MASTER (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Serial Number String used by the device
|
||||
*
|
||||
|
||||
@@ -8,9 +8,9 @@ An application using the USB audio framework needs to have defines set for confi
|
||||
Defaults for these defines are found in ``xua_conf_default.h``.
|
||||
|
||||
These defines should be over-ridden in an optional header file ``xua_conf.h`` file or in the ``Makefile``
|
||||
for a relevant build configuration.
|
||||
for a relevant build configuration.
|
||||
|
||||
This section fully documents all of the settable defines and their default values (where appropriate).
|
||||
This section fully documents all of the settable defines and their default values (where appropriate).
|
||||
|
||||
Code Location (tile)
|
||||
--------------------
|
||||
@@ -25,12 +25,12 @@ Code Location (tile)
|
||||
Channel Counts
|
||||
--------------
|
||||
|
||||
.. doxygendefine:: NUM_USB_CHAN_OUT
|
||||
.. doxygendefine:: NUM_USB_CHAN_IN
|
||||
.. doxygendefine:: I2S_CHANS_DAC
|
||||
.. doxygendefine:: I2S_CHANS_ADC
|
||||
.. doxygendefine:: NUM_USB_CHAN_OUT
|
||||
.. doxygendefine:: NUM_USB_CHAN_IN
|
||||
.. doxygendefine:: I2S_CHANS_DAC
|
||||
.. doxygendefine:: I2S_CHANS_ADC
|
||||
|
||||
Frequencies and Clocks
|
||||
Frequencies and Clocks
|
||||
----------------------
|
||||
|
||||
.. doxygendefine:: MAX_FREQ
|
||||
@@ -38,6 +38,7 @@ Frequencies and Clocks
|
||||
.. doxygendefine:: DEFAULT_FREQ
|
||||
.. doxygendefine:: MCLK_441
|
||||
.. doxygendefine:: MCLK_48
|
||||
.. doxygendefine:: XUA_USE_APP_PLL
|
||||
|
||||
Audio Class
|
||||
-----------
|
||||
|
||||
@@ -1,74 +1,49 @@
|
||||
Required User Function Definitions
|
||||
==================================
|
||||
|newpage|
|
||||
|
||||
The following functions need to be defined by an application using the XMOS USB Audio framework.
|
||||
User Function Definitions
|
||||
=========================
|
||||
|
||||
The following functions can be defined by an application using `lib_xua`.
|
||||
|
||||
.. note:: Default, empty, implementations of these functions are provided in `lib_xua`. These are marked
|
||||
as weak symbols so the application can simply define its own version of them.
|
||||
|
||||
External Audio Hardware Configuration Functions
|
||||
-----------------------------------------------
|
||||
|
||||
.. c:function:: void AudioHwInit(chanend ?c_codec)
|
||||
The following functions can be optionally used by the design to configure external audio hardware.
|
||||
As a minimum, in most applications, it is expected that a implementation of `AudioHwConfig()` will need
|
||||
to be provided.
|
||||
|
||||
This function is called when the audio core starts after the
|
||||
device boots up and should initialize the external audio harware e.g. clocking, DAC, ADC etc
|
||||
.. doxygenfunction:: AudioHwInit
|
||||
.. doxygenfunction:: AudioHwConfig
|
||||
.. doxygenfunction:: AudioHwConfig_Mute
|
||||
.. doxygenfunction:: AudioHwConfig_UnMute
|
||||
|
||||
:param c_codec: An optional chanend that was original passed into
|
||||
:c:func:`audio` that can be used to communicate
|
||||
with other cores.
|
||||
|
||||
|
||||
.. c:function:: void AudioHwConfig(unsigned samFreq, unsigned mclk, chanend ?c_codec, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
||||
|
||||
This function is called when the audio core starts or changes
|
||||
sample rate. It should configure the extenal audio hardware to run at the specified
|
||||
sample rate given the supplied master clock frequency.
|
||||
|
||||
:param samFreq: The sample frequency in Hz that the hardware should be configured to (in Hz).
|
||||
|
||||
:param mclk: The master clock frequency that is required in Hz.
|
||||
|
||||
:param c_codec: An optional chanend that was original passed into
|
||||
:c:func:`audio` that can be used to communicate
|
||||
with other cores.
|
||||
|
||||
:param dsdMode: Signifies if the audio hardware should be configured for DSD operation
|
||||
|
||||
:param sampRes_DAC: The sample resolution of the DAC stream
|
||||
|
||||
:param sampRes_ADC: The sample resolution of the ADC stream
|
||||
|
||||
|
||||
Audio Streaming Functions
|
||||
-------------------------
|
||||
Audio Stream Start/Stop Functions
|
||||
---------------------------------
|
||||
|
||||
The following functions can be optionally used by the design. They can be useful for mute lines etc.
|
||||
|
||||
.. c:function:: void AudioStreamStart(void)
|
||||
.. doxygenfunction:: UserAudioStreamStart
|
||||
.. doxygenfunction:: UserAudioStreamStop
|
||||
.. doxygenfunction:: UserAudioInputStreamStart
|
||||
.. doxygenfunction:: UserAudioInputStreamStop
|
||||
.. doxygenfunction:: UserAudioOutputStreamStart
|
||||
.. doxygenfunction:: UserAudioOutputStreamStop
|
||||
|
||||
This function is called when the audio stream from device to host
|
||||
starts.
|
||||
|
||||
.. c:function:: void AudioStreamStop(void)
|
||||
|
||||
This function is called when the audio stream from device to host stops.
|
||||
|
||||
Host Active
|
||||
-----------
|
||||
Host Active Functions
|
||||
---------------------
|
||||
|
||||
The following function can be used to signal that the device is connected to a valid host.
|
||||
|
||||
This is called on a change in state.
|
||||
|
||||
.. c:function:: void AudioStreamStart(int active)
|
||||
|
||||
:param active: Indicates if the host is active or not. 1 for active else 0.
|
||||
|
||||
.. doxygenfunction:: UserHostActive
|
||||
|
||||
HID Controls
|
||||
------------
|
||||
|
||||
The following function is called when the device wishes to read physical user input (buttons etc).
|
||||
The function should write relevant HID bits into this array. The bit ordering and functionality is defined by the HID report descriptor used.
|
||||
|
||||
.. c:function:: void UserReadHIDButtons(unsigned char hidData[])
|
||||
|
||||
:param hidData: The function should write relevant HID bits into this array. The bit ordering and functionality is defined by the HID report descriptor used.
|
||||
|
||||
.. doxygenfunction:: UserHIDGetData
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
|
||||
|newpage|
|
||||
|
||||
Synchronisation
|
||||
===============
|
||||
Synchronisation & Clocking
|
||||
==========================
|
||||
|
||||
The codebase supports "Synchronous" and "Asynchronous" modes for USB transfer as defined by the
|
||||
The codebase supports "Synchronous" and "Asynchronous" modes for USB transfer as defined by the
|
||||
USB specification(s).
|
||||
|
||||
Asynchronous mode (``XUA_SYNCMODE_ASYNC``) has the advantage that the device is clock-master. This means that
|
||||
a high-quality local master-clock source can be utilised. It also has the benefit that the device may
|
||||
synchronise it's master clock to an external digital input stream e.g. S/PDIF and thus avoiding sample-rate
|
||||
Asynchronous mode (``XUA_SYNCMODE_ASYNC``) has the advantage that the device is clock-master. This means that
|
||||
a high-quality local master-clock source can be utilised. It also has the benefit that the device may
|
||||
synchronise it's master clock to an external digital input stream e.g. S/PDIF thus avoiding sample-rate
|
||||
conversion.
|
||||
|
||||
The drawback of this mode is that it burdens the host with syncing to the device which some hosts
|
||||
The drawback of this mode is that it burdens the host with syncing to the device which some hosts
|
||||
may not support. This is especially pertinent to embedded hosts, however, most PC's and mobile devices
|
||||
will indeed support this mode.
|
||||
|
||||
Synchronous mode (``XUA_SYNCMODE_SYNC``) is an option if the target host does not support asynchronous mode
|
||||
or if it is desirable to synchronise many devices to a single host. It should be noted, however, that input
|
||||
or if it is desirable to synchronise many devices to a single host. It should be noted, however, that input
|
||||
from digital streams, such as S/PDIF, are not currently supported in this mode.
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
The selection of synchronisation mode is done at build time and cannot be changed dynamically.
|
||||
|
||||
Setting the synchronisation mode of the device is done using the define in :ref:`opt_sync_defines`
|
||||
@@ -39,10 +39,17 @@ Setting the synchronisation mode of the device is done using the define in :ref:
|
||||
- USB synchronisation mode
|
||||
- ``XUA_SYNCMODE_ASYNC``
|
||||
|
||||
When operating in synchronous mode an external Cirrus Logic CS2100 device is required for master clock
|
||||
generation. The codebase expects to drive a synchronisation signal to this external device
|
||||
When operating in asynchronous mode xcore.ai based devices will be configured, by default, to use their internal
|
||||
"Applications" PLL to generated an appropriate master-clock signal. To disable this ``XUA_USE_APP_PLL`` should be
|
||||
set to ``0``. For all other devices the developer is expected to supply external master-clock generation circuitry.
|
||||
|
||||
The programmer should ensure the define in :ref:`opt_sync_ref_defines` is set appropriately.
|
||||
When operating in synchronous mode an xcore.ai based device, by default, will be configured to used it's internal
|
||||
"application" PLL to generate a master-clock synchronised to the USB host.
|
||||
|
||||
xcore-200 based devices do not have this application PLL and so an external Cirrus Logic CS2100 device is required
|
||||
for master clock generation. The codebase expects to drive a synchronisation signal to this external device.
|
||||
|
||||
In this case the developer should ensure the define in :ref:`opt_sync_ref_defines` is set appropriately.
|
||||
|
||||
.. _opt_sync_ref_defines:
|
||||
|
||||
@@ -57,10 +64,33 @@ The programmer should ensure the define in :ref:`opt_sync_ref_defines` is set ap
|
||||
- Tile location of reference to CS2100 device
|
||||
- ``AUDIO_IO_TILE``
|
||||
|
||||
The codebase expects this reference signal port to be defined in the application XN file as ``PORT_PLL_REF``.
|
||||
The codebase expects this reference signal port to be defined in the application XN file as ``PORT_PLL_REF``.
|
||||
This may be a port of any bit-width, however, connection to bit[0] is assumed::
|
||||
|
||||
<Port Location="XS1_PORT_1A" Name="PORT_PLL_REF"/>
|
||||
|
||||
Configuration of the external CS2100 device (typically via I2C) is beyond the scope of this document.
|
||||
|
||||
Note, in all cases the master-clocks are generated (when using the xcore.ai Application PLL) or should be generated
|
||||
(if using external circuitry) to match the defines in :ref:`opt_sync_mclk_defines`.
|
||||
|
||||
.. _opt_sync_mclk_defines:
|
||||
|
||||
.. list-table:: Master clock frequencies
|
||||
:header-rows: 1
|
||||
:widths: 20 80 20
|
||||
|
||||
* - Define
|
||||
- Description
|
||||
- Default
|
||||
* - ``MCLK_48``
|
||||
- Master clock frequency (in Hz)used for sample-rates related to 48KHz
|
||||
- NOTE
|
||||
* - ``MCLK_441``
|
||||
- Master clock frequency (in Hz) used for sample-rates related to 44.1KHz
|
||||
- NONE
|
||||
|
||||
.. note::
|
||||
|
||||
The master clock defines above are critical for proper operation and default values are not provided.
|
||||
If they are not defined by the devloper a build error will be emmited.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
XMOSNEWSTYLE = 2
|
||||
DOXYGEN_DIRS=../../api
|
||||
DOXYGEN_DIRS=../../api ../../src/core/user/audiostream ../../src/core/user/hostactive ../../src/core/user/hid ../../src/core/user/audiohw
|
||||
SOURCE_INCLUDE_DIRS=../../../lib_xua
|
||||
SPHINX_MASTER_DOC=lib_xua
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION = 3.5.0
|
||||
VERSION = 3.5.1
|
||||
|
||||
DEBUG ?= 0
|
||||
|
||||
@@ -55,6 +55,7 @@ INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS) \
|
||||
src/core/user/audiostream \
|
||||
src/core/user/hid \
|
||||
src/core/user/hostactive \
|
||||
src/core/user/audiohw \
|
||||
src/hid \
|
||||
src/midi
|
||||
|
||||
@@ -70,6 +71,7 @@ SOURCE_DIRS = src/core \
|
||||
src/core/support \
|
||||
src/core/user/audiostream \
|
||||
src/core/user/hostactive \
|
||||
src/core/user/audiohw \
|
||||
src/core/xuduser \
|
||||
src/dfu \
|
||||
src/hid \
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
#include <string.h>
|
||||
#include <xassert.h>
|
||||
|
||||
|
||||
#include "xua.h"
|
||||
|
||||
#include "audiohw.h"
|
||||
|
||||
#include "audioports.h"
|
||||
#include "mic_array_conf.h"
|
||||
#if (XUA_SPDIF_TX_EN)
|
||||
@@ -86,7 +87,7 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
|
||||
unsigned syncError = 0;
|
||||
unsigned lrval = 0;
|
||||
const unsigned lrval_mask = (0xffffffff << (32 - XUA_I2S_N_BITS));
|
||||
|
||||
|
||||
if(XUA_I2S_N_BITS != 32)
|
||||
{
|
||||
asm volatile("in %0, res[%1]":"=r"(lrval):"r"(p_lrclk):"memory");
|
||||
@@ -306,7 +307,7 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
||||
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
|
||||
unsigned sample;
|
||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index]));
|
||||
|
||||
|
||||
sample = bitrev(sample);
|
||||
if(XUA_I2S_N_BITS != 32)
|
||||
{
|
||||
@@ -635,6 +636,9 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
buffered _XUA_CLK_DIR port:32 ?p_bclk,
|
||||
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
||||
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
|
||||
#if (XUA_USE_APP_PLL)
|
||||
, client interface SoftPll_if i_softPll
|
||||
#endif
|
||||
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
, chanend c_spdif_out
|
||||
#endif
|
||||
@@ -662,6 +666,12 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
unsigned divide;
|
||||
unsigned firstRun = 1;
|
||||
|
||||
#if (XUA_USE_APP_PLL)
|
||||
/* Use xCORE.ai Secondary PLL to generate master clock
|
||||
* This could be "fixed" for async mode or adjusted if in sync mode */
|
||||
i_softPll.init(DEFAULT_MCLK);
|
||||
#endif
|
||||
|
||||
/* Clock master clock-block from master-clock port */
|
||||
/* Note, marked unsafe since other cores may be using this mclk port */
|
||||
configure_clock_src(clk_audio_mclk, p_mclk_in);
|
||||
@@ -687,6 +697,8 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Perform required CODEC/ADC/DAC initialisation */
|
||||
AudioHwInit();
|
||||
|
||||
@@ -715,13 +727,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
/* Calculate master clock to bit clock (or DSD clock) divide for current sample freq
|
||||
* e.g. 11.289600 / (176400 * 64) = 1 */
|
||||
{
|
||||
unsigned numBits = XUA_I2S_N_BITS * 2;
|
||||
|
||||
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||
{
|
||||
/* TDM has 8 channels */
|
||||
numBits *= 4;
|
||||
}
|
||||
unsigned numBits = XUA_I2S_N_BITS * I2S_CHANS_PER_FRAME;
|
||||
|
||||
#if (DSD_CHANS_DAC > 0)
|
||||
if(dsdMode == DSD_MODE_DOP)
|
||||
@@ -804,8 +810,19 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
curFreq *= 16;
|
||||
}
|
||||
#endif
|
||||
/* Configure Clocking/CODEC/DAC/ADC for SampleFreq/MClk */
|
||||
|
||||
/* User should mute audio hardware */
|
||||
AudioHwConfig_Mute();
|
||||
|
||||
#if (XUA_USE_APP_PLL)
|
||||
i_softPll.init(mClk);
|
||||
#endif
|
||||
|
||||
/* User code should configure audio harware for SampleFreq/MClk etc */
|
||||
AudioHwConfig(curFreq, mClk, dsdMode, curSamRes_DAC, curSamRes_ADC);
|
||||
|
||||
/* User should unmute audio hardware */
|
||||
AudioHwConfig_UnMute();
|
||||
}
|
||||
|
||||
if(!firstRun)
|
||||
|
||||
@@ -394,7 +394,7 @@ __builtin_unreachable();
|
||||
unsigned l;
|
||||
unsafe
|
||||
{
|
||||
mult = multInPtr[i];
|
||||
mult = multInPtr[i];
|
||||
}
|
||||
{h, l} = macs(mult, sample, 0, 0);
|
||||
sample = h << 3;
|
||||
@@ -427,7 +427,7 @@ __builtin_unreachable();
|
||||
unsigned l;
|
||||
unsafe
|
||||
{
|
||||
mult = multInPtr[i];
|
||||
mult = multInPtr[i];
|
||||
}
|
||||
{h, l} = macs(mult, sample, 0, 0);
|
||||
sample = h << 3;
|
||||
@@ -461,7 +461,7 @@ __builtin_unreachable();
|
||||
unsigned l;
|
||||
unsafe
|
||||
{
|
||||
mult = multInPtr[i];
|
||||
mult = multInPtr[i];
|
||||
}
|
||||
{h, l} = macs(mult, sample, 0, 0);
|
||||
sample = h << 3;
|
||||
|
||||
@@ -105,7 +105,11 @@ void XUA_Buffer(
|
||||
#endif
|
||||
, chanend c_aud
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
#if(XUA_USE_APP_PLL)
|
||||
, chanend c_swpll_update
|
||||
#else
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -141,7 +145,11 @@ void XUA_Buffer(
|
||||
, c_buff_ctrl
|
||||
#endif
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
, i_pll_ref
|
||||
#if(XUA_USE_APP_PLL)
|
||||
, c_swpll_update
|
||||
#else
|
||||
, i_pll_ref
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -190,8 +198,12 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
, chanend c_buff_ctrl
|
||||
#endif
|
||||
#if XUA_SYNCMODE == XUA_SYNCMODE_SYNC
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
#if (XUA_USE_APP_PLL)
|
||||
, chanend c_swpll_update
|
||||
#else
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -247,7 +259,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#if (NUM_USB_CHAN_IN > 0)
|
||||
unsigned bufferIn = 1;
|
||||
#endif
|
||||
unsigned sofCount = 0;
|
||||
int sofCount = 0;
|
||||
int pllUpdate = 0;
|
||||
|
||||
unsigned mod_from_last_time = 0;
|
||||
#ifdef FB_TOLERANCE_TEST
|
||||
@@ -294,7 +307,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
unsigned iap_ea_native_interface_alt_setting = 0;
|
||||
unsigned iap_ea_native_control_to_send = 0;
|
||||
unsigned iap_ea_native_incoming = 0;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -357,12 +369,16 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#ifndef LOCAL_CLOCK_MARGIN
|
||||
#define LOCAL_CLOCK_MARGIN (1000)
|
||||
#endif
|
||||
|
||||
#if (!XUA_USE_APP_PLL)
|
||||
timer t_sofCheck;
|
||||
unsigned timeLastEdge;
|
||||
unsigned timeNextEdge;
|
||||
t_sofCheck :> timeLastEdge;
|
||||
timeNextEdge + LOCAL_CLOCK_INCREMENT;
|
||||
i_pll_ref.toggle();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
@@ -427,7 +443,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
/* Reset FB */
|
||||
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
||||
* to stabilise (i.e. sofCount == 128 to fire) */
|
||||
sofCount = 1;
|
||||
sofCount = 0;
|
||||
pllUpdate = 0;
|
||||
clocks = 0;
|
||||
clockcounter = 0;
|
||||
mod_from_last_time = 0;
|
||||
@@ -502,13 +519,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
}
|
||||
#endif
|
||||
/* Pass on sample freq change to decouple() via global flag (saves a chanend) */
|
||||
/* Note: freqChange flags now used to communicate other commands also */
|
||||
/* Note: freqChange_flag now used to communicate other commands also */
|
||||
SET_SHARED_GLOBAL0(g_freqChange, cmd); /* Set command */
|
||||
SET_SHARED_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && (!XUA_USE_APP_PLL)
|
||||
case t_sofCheck when timerafter(timeNextEdge) :> void:
|
||||
i_pll_ref.toggle();
|
||||
timeLastEdge = timeNextEdge;
|
||||
@@ -528,7 +545,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
unsigned usbSpeed;
|
||||
int framesPerSec;
|
||||
GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed);
|
||||
static int sofCount = 0;
|
||||
|
||||
framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000;
|
||||
|
||||
@@ -539,12 +555,27 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
sofCount += 1000;
|
||||
if (sofCount == framesPerSec)
|
||||
{
|
||||
sofCount = 0;
|
||||
pllUpdate++;
|
||||
#if (!XUA_USE_APP_PLL)
|
||||
/* Port is accessed via interface to allow flexibilty with location */
|
||||
i_pll_ref.toggle();
|
||||
t_sofCheck :> timeLastEdge;
|
||||
sofCount = 0;
|
||||
timeNextEdge = timeLastEdge + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
|
||||
#endif
|
||||
}
|
||||
#if (XUA_USE_APP_PLL)
|
||||
// Update PLL @ 100Hz
|
||||
if(pllUpdate == 10)
|
||||
{
|
||||
pllUpdate = 0;
|
||||
unsigned short mclk_pt;
|
||||
asm volatile("getts %0, res[%1]" : "=r" (mclk_pt) : "r" (p_off_mclk));
|
||||
outuint(c_swpll_update, mclk_pt);
|
||||
outct(c_swpll_update, XS1_CT_END);
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
||||
|
||||
/* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to
|
||||
@@ -646,7 +677,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
clockcounter = 0;
|
||||
}
|
||||
#else
|
||||
|
||||
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
||||
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
|
||||
* expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format.
|
||||
@@ -897,8 +927,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if XUA_HID_ENABLED
|
||||
/* HID Report Data */
|
||||
#if (XUA_HID_ENABLED)
|
||||
/* HID Report Data */
|
||||
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||
hid_ready_flag = 0U;
|
||||
unsigned reportTime;
|
||||
@@ -911,7 +941,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
|
||||
#ifdef MIDI
|
||||
/* Received word from MIDI thread - Check for ACK or Data */
|
||||
/* Received word from MIDI thread - Check for ACK or Data */
|
||||
case midi_get_ack_or_data(c_midi, is_ack, datum):
|
||||
if (is_ack)
|
||||
{
|
||||
|
||||
457
lib_xua/src/core/clocking/apppll.xc
Normal file
457
lib_xua/src/core/clocking/apppll.xc
Normal file
@@ -0,0 +1,457 @@
|
||||
// Copyright 2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <print.h>
|
||||
#include <platform.h>
|
||||
#include "xua.h"
|
||||
#include "xassert.h"
|
||||
#include <stdio.h>
|
||||
#if (XUA_USE_APP_PLL)
|
||||
|
||||
/*
|
||||
* Functions for interacting with the secondary/application PLL
|
||||
*/
|
||||
|
||||
#ifndef __XS3A__
|
||||
#error App PLL not included in device
|
||||
#endif
|
||||
|
||||
/*
|
||||
* App PLL settings used for syncing to external clocks
|
||||
*/
|
||||
|
||||
// Define the PLL settings to generate the required frequencies.
|
||||
// All settings allow greater than +-1000ppm lock range.
|
||||
// Comment out the following line for 2us update.
|
||||
|
||||
//#define FAST_FRAC_REG_WRITE
|
||||
|
||||
// OPTION 1 - 1us register update rate - Lowest jitter
|
||||
// 10ps jitter 100Hz-40kHz. Low freq noise floor -100dBc
|
||||
|
||||
#ifdef FAST_FRAC_REG_WRITE
|
||||
|
||||
#define FRAC_REG_WRITE_DLY (100)
|
||||
|
||||
// Found solution: IN 24.000MHz, OUT 22.578947MHz, VCO 3251.37MHz, RD 1, FD 135.474 (m = 9, n = 19), OD 6, FOD 6, ERR -11.189ppm
|
||||
#define APP_PLL_CTL_SYNC_22M (0x0A808600)
|
||||
#define APP_PLL_DIV_SYNC_22M (0x80000005)
|
||||
#define APP_PLL_FRAC_SYNC_22M (0x80000812)
|
||||
#define APP_PLL_ERR_MULT_22M (627) // round(135(divider)*100Hz*1048576/22579200)
|
||||
#define APP_PLL_MOD_INIT_22M (498283)
|
||||
|
||||
// Fout = Fin*divider/(2*2*6*6) = (fin/144) * divider = (24/144) * divider. = 1/6 * divider.
|
||||
// To achieve frequency f, Fraction Setting = (6*f) - 135
|
||||
// So to achieve 22.5792MHz, Fraction Setting = (6*22.5792) - 135 = 0.4752
|
||||
// Numerical input = round((Fraction setting * 2^20) = 0.4752 * 1048576 = 498283
|
||||
|
||||
//Found solution: IN 24.000MHz, OUT 24.575758MHz, VCO 3538.91MHz, RD 1, FD 147.455 (m = 5, n = 11), OD 6, FOD 6, ERR -9.864ppm
|
||||
#define APP_PLL_CTL_SYNC_24M (0x0A809200)
|
||||
#define APP_PLL_DIV_SYNC_24M (0x80000005)
|
||||
#define APP_PLL_FRAC_SYNC_24M (0x8000040A)
|
||||
#define APP_PLL_ERR_MULT_24M (627) // round(147(divider)*100Hz*1048576/24576000)
|
||||
#define APP_PLL_MOD_INIT_24M (478151)
|
||||
|
||||
// Fout = Fin*divider/(2*2*6*6) = (fin/144) * divider = (24/144) * divider. = 1/6 * divider.
|
||||
// To achieve frequency f, Fraction Setting = (6*f) - 147
|
||||
// So to achieve 24.576MHz, Fraction Setting = (6*24.576) - 147 = 0.456
|
||||
// Numerical input = round((Fraction setting * 2^20) = 0.456 * 1048576 = 478151
|
||||
|
||||
#else
|
||||
|
||||
// OPTION 2 - 2us register update rate - Higher jitter
|
||||
// 50ps jitter 100Hz-40kHz. Low freq noise floor -93dBc
|
||||
|
||||
#define FRAC_REG_WRITE_DLY (200)
|
||||
|
||||
//Found solution: IN 24.000MHz, OUT 22.579186MHz, VCO 3522.35MHz, RD 2, FD 293.529 (m = 9, n = 17), OD 3, FOD 13, ERR -0.641ppm
|
||||
#define APP_PLL_CTL_SYNC_22M (0x09012401)
|
||||
#define APP_PLL_DIV_SYNC_22M (0x8000000C)
|
||||
#define APP_PLL_FRAC_SYNC_22M (0x80000810)
|
||||
#define APP_PLL_ERR_MULT_22M (1361) // round(293(divider)*100Hz*1048576/22579200)
|
||||
#define APP_PLL_MOD_INIT_22M (555326)
|
||||
|
||||
// Fout = (Fin/2)*divider/(2*2*3*13) = (fin/312) * divider = (24/312) * divider. = 1/13 * divider.
|
||||
// To achieve frequency f, Fraction Setting = (13*f) - 293
|
||||
// So to achieve 22.5792MHz, Fraction Setting = (13*22.5792) - 293 = 0.5296
|
||||
// Numerical input = round((Fraction setting * 2^20) = 0.5296 * 1048576 = 555326
|
||||
|
||||
//Found solution: IN 24.000MHz, OUT 24.576125MHz, VCO 3342.35MHz, RD 2, FD 278.529 (m = 9, n = 17), OD 2, FOD 17, ERR 5.069ppm - Runs VCO out fractionally out of spec at 835MHz
|
||||
#define APP_PLL_CTL_SYNC_24M (0x08811501)
|
||||
#define APP_PLL_DIV_SYNC_24M (0x80000010)
|
||||
#define APP_PLL_FRAC_SYNC_24M (0x80000810)
|
||||
#define APP_PLL_ERR_MULT_24M (1186) // round(278(divider)*100Hz*1048576/24576000)
|
||||
#define APP_PLL_MOD_INIT_24M (553648)
|
||||
|
||||
// Fout = (Fin/2)*divider/(2*2*2*17) = (fin/272) * divider = (24/272) * divider. = 3/34 * divider.
|
||||
// To achieve frequency f, Fraction Setting = ((34/3)*f) - 278
|
||||
// So to achieve 24.576MHz, Fraction Setting = ((34/3)*24.576) - 278 = 0.528
|
||||
// Numerical input = round((Fraction setting * 2^20) = 0.528 * 1048576 = 553648
|
||||
#endif
|
||||
|
||||
/*
|
||||
* App PLL settings used for low jitter fixed local clocks
|
||||
*/
|
||||
|
||||
//Found solution: IN 24.000MHz, OUT 49.151786MHz, VCO 3145.71MHz, RD 1, FD 131.071 (m = 1, n = 14), OD 8, FOD 2, ERR -4.36ppm
|
||||
// Measure: 100Hz-40kHz: ~7ps
|
||||
// 100Hz-1MHz: 70ps.
|
||||
// 100Hz high pass: 118ps.
|
||||
#define APP_PLL_CTL_FIXED_49M (0x0B808200)
|
||||
#define APP_PLL_DIV_FIXED_49M (0x80000001)
|
||||
#define APP_PLL_FRAC_FIXED_49M (0x8000000D)
|
||||
|
||||
//Found solution: IN 24.000MHz, OUT 45.157895MHz, VCO 2709.47MHz, RD 1, FD 112.895 (m = 17, n = 19), OD 5, FOD 3, ERR -11.19ppm
|
||||
// Measure: 100Hz-40kHz: 6.5ps
|
||||
// 100Hz-1MHz: 67ps.
|
||||
// 100Hz high pass: 215ps.
|
||||
#define APP_PLL_CTL_FIXED_45M (0x0A006F00)
|
||||
#define APP_PLL_DIV_FIXED_45M (0x80000002)
|
||||
#define APP_PLL_FRAC_FIXED_45M (0x80001012)
|
||||
|
||||
// Found solution: IN 24.000MHz, OUT 24.576000MHz, VCO 2457.60MHz, RD 1, FD 102.400 (m = 2, n = 5), OD 5, FOD 5, ERR 0.0ppm
|
||||
// Measure: 100Hz-40kHz: ~8ps
|
||||
// 100Hz-1MHz: 63ps.
|
||||
// 100Hz high pass: 127ps.
|
||||
#define APP_PLL_CTL_FIXED_24M (0x0A006500)
|
||||
#define APP_PLL_DIV_FIXED_24M (0x80000004)
|
||||
#define APP_PLL_FRAC_FIXED_24M (0x80000104)
|
||||
|
||||
// Found solution: IN 24.000MHz, OUT 22.579186MHz, VCO 3522.35MHz, RD 1, FD 146.765 (m = 13, n = 17), OD 3, FOD 13, ERR -0.641ppm
|
||||
// Measure: 100Hz-40kHz: 7ps
|
||||
// 100Hz-1MHz: 67ps.
|
||||
// 100Hz high pass: 260ps.
|
||||
#define APP_PLL_CTL_FIXED_22M (0x09009100)
|
||||
#define APP_PLL_DIV_FIXED_22M (0x8000000C)
|
||||
#define APP_PLL_FRAC_FIXED_22M (0x80000C10)
|
||||
|
||||
#define APP_PLL_CTL_FIXED_12M (0x0A006500)
|
||||
#define APP_PLL_DIV_FIXED_12M (0x80000009)
|
||||
#define APP_PLL_FRAC_FIXED_12M (0x80000104)
|
||||
|
||||
#define APP_PLL_CTL_FIXED_11M (0x09009100)
|
||||
#define APP_PLL_DIV_FIXED_11M (0x80000009)
|
||||
#define APP_PLL_FRAC_FIXED_11M (0x80000C10)
|
||||
|
||||
#define APP_PLL_CTL_ENABLE (1 << 27)
|
||||
#define APP_PLL_CLK_OUTPUT_ENABLE (1 << 16)
|
||||
|
||||
static void set_app_pll_init(tileref tile, int app_pll_ctrl)
|
||||
{
|
||||
// Disable the PLL
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, (app_pll_ctrl & ~APP_PLL_CTL_ENABLE));
|
||||
|
||||
// Enable the PLL to invoke a reset on the appPLL.
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, app_pll_ctrl);
|
||||
|
||||
// Must write the CTL register twice so that the F and R divider values are captured using a running clock.
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, app_pll_ctrl);
|
||||
|
||||
// Now disable and re-enable the PLL so we get the full 5us reset time with the correct F and R values.
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, (app_pll_ctrl & 0xF7FFFFFF));
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, app_pll_ctrl);
|
||||
|
||||
// Wait for PLL to lock.
|
||||
delay_microseconds(500);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AppPllEnable(tileref tile, int clkFreq_hz)
|
||||
{
|
||||
unsigned app_pll_ctrl, app_pll_div, app_pll_frac;
|
||||
|
||||
/* Decide on App PLL settings */
|
||||
if(XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
{
|
||||
switch(clkFreq_hz)
|
||||
{
|
||||
case 44100 * 512:
|
||||
app_pll_ctrl = APP_PLL_CTL_SYNC_22M;
|
||||
app_pll_div = APP_PLL_DIV_SYNC_22M;
|
||||
app_pll_frac = APP_PLL_FRAC_SYNC_22M;
|
||||
break;
|
||||
|
||||
case 48000 * 512:
|
||||
app_pll_ctrl = APP_PLL_CTL_SYNC_24M;
|
||||
app_pll_div = APP_PLL_DIV_SYNC_24M;
|
||||
app_pll_frac = APP_PLL_FRAC_SYNC_24M;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(clkFreq_hz)
|
||||
{
|
||||
case 44100 * 256:
|
||||
app_pll_ctrl = APP_PLL_CTL_FIXED_11M;
|
||||
app_pll_div = APP_PLL_DIV_FIXED_11M;
|
||||
app_pll_frac = APP_PLL_FRAC_FIXED_11M;
|
||||
break;
|
||||
|
||||
case 48000 * 256:
|
||||
app_pll_ctrl = APP_PLL_CTL_FIXED_12M;
|
||||
app_pll_div = APP_PLL_DIV_FIXED_12M;
|
||||
app_pll_frac = APP_PLL_FRAC_FIXED_12M;
|
||||
break;
|
||||
|
||||
case 44100 * 512:
|
||||
app_pll_ctrl = APP_PLL_CTL_FIXED_22M;
|
||||
app_pll_div = APP_PLL_DIV_FIXED_22M;
|
||||
app_pll_frac = APP_PLL_FRAC_FIXED_22M;
|
||||
break;
|
||||
|
||||
case 48000 * 512:
|
||||
app_pll_ctrl = APP_PLL_CTL_FIXED_24M;
|
||||
app_pll_div = APP_PLL_DIV_FIXED_24M;
|
||||
app_pll_frac = APP_PLL_FRAC_FIXED_24M;
|
||||
break;
|
||||
|
||||
case 44100 * 1024:
|
||||
app_pll_ctrl = APP_PLL_CTL_FIXED_45M;
|
||||
app_pll_div = APP_PLL_DIV_FIXED_45M;
|
||||
app_pll_frac = APP_PLL_FRAC_FIXED_45M;
|
||||
break;
|
||||
|
||||
case 48000 * 1024:
|
||||
app_pll_ctrl = APP_PLL_CTL_FIXED_49M;
|
||||
app_pll_div = APP_PLL_DIV_FIXED_49M;
|
||||
app_pll_frac = APP_PLL_FRAC_FIXED_49M;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise the AppPLL and get it running.
|
||||
set_app_pll_init(tile, app_pll_ctrl);
|
||||
|
||||
// Write the fractional-n register, note, the top bit is set to enable the frac-n block.
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, app_pll_frac);
|
||||
|
||||
// And then write the clock divider register to enable the output
|
||||
write_node_config_reg(tile, XS1_SSWITCH_SS_APP_CLK_DIVIDER_NUM, app_pll_div);
|
||||
|
||||
// Wait for PLL output frequency to stabilise due to fractional divider enable
|
||||
delay_microseconds(100);
|
||||
}
|
||||
|
||||
void SoftPllInit(int clkFreq_hz, struct SoftPllState &pllState)
|
||||
{
|
||||
switch(clkFreq_hz)
|
||||
{
|
||||
case 44100 * 512:
|
||||
pllState.expectedClkMod = 29184; // Count we expect on MCLK port timer at SW PLL check point. For 100Hz, 10ms.
|
||||
pllState.initialSetting = APP_PLL_MOD_INIT_22M;
|
||||
pllState.initialErrorMult = APP_PLL_ERR_MULT_22M;
|
||||
break;
|
||||
|
||||
case 48000 * 512:
|
||||
pllState.expectedClkMod = 49152;
|
||||
pllState.initialSetting = APP_PLL_MOD_INIT_24M;
|
||||
pllState.initialErrorMult = APP_PLL_ERR_MULT_24M;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
pllState.ds_in = pllState.initialSetting;
|
||||
pllState.ds_x1 = 0;
|
||||
pllState.ds_x2 = 0;
|
||||
pllState.ds_x3 = 0;
|
||||
pllState.iir_y = 0;
|
||||
pllState.phaseError = 0;
|
||||
pllState.phaseErrorInt = 0;
|
||||
}
|
||||
|
||||
int SoftPllUpdate(tileref tile, unsigned short mclk_pt, unsigned short mclk_pt_last, struct SoftPllState &pllState, int fastLock)
|
||||
{
|
||||
int freq_error, error_p, error_i;
|
||||
|
||||
unsigned expectedClksMod = pllState.expectedClkMod;
|
||||
unsigned initialSetting = pllState.initialSetting;
|
||||
unsigned init_err_mult = pllState.initialErrorMult;
|
||||
|
||||
int newSetting;
|
||||
unsigned short expectedPt;
|
||||
|
||||
int set = -1;
|
||||
int diff;
|
||||
|
||||
// expectedClkMod is the value of the port counter that we expect given the desired MCLK in the 10ms time period we are running at.
|
||||
expectedPt = mclk_pt_last + expectedClksMod;
|
||||
|
||||
// Handle wrapping
|
||||
if (porttimeafter(mclk_pt, expectedPt))
|
||||
{
|
||||
diff = -(short)(expectedPt - mclk_pt);
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = (short)(mclk_pt - expectedPt);
|
||||
}
|
||||
|
||||
// TODO Add a bounds checker on diff to make sure it's roughly where we expect.
|
||||
// If it isn't we should ignore it as it's either a glitch or from clock start/stop.
|
||||
|
||||
if(fastLock) // Fast lock - set DCO based on measured frequency error in first cycle
|
||||
{
|
||||
initialSetting = initialSetting - (diff * init_err_mult); // init_err_mult is the dco input change to cause an output frequency offset equating to a measured input freq error of 1.
|
||||
diff = 0; // reset diff to zero so following code does not see any error in this cycle.
|
||||
}
|
||||
|
||||
// Absolute frequency error for last measurement cycle. If diff is positive, port timer was beyond where it should have been, so MCLK was too fast. So this needs to describe a negative error.
|
||||
freq_error = -diff;
|
||||
|
||||
// Phase error is the integral of frequency error.
|
||||
pllState.phaseError += freq_error;
|
||||
|
||||
// Integral of phase error for use in PI loop below.
|
||||
pllState.phaseErrorInt += pllState.phaseError;
|
||||
|
||||
error_p = (pllState.phaseError << 5); // << 5 => Kp = 32
|
||||
error_i = (pllState.phaseErrorInt >> 2); // >> 2 => Ki = 0.25
|
||||
|
||||
// input to filter (x) is output of PI controller
|
||||
int x = (error_p + error_i);
|
||||
|
||||
// Filter some noise into DCO to reduce jitter
|
||||
// First order IIR, make A=0.125
|
||||
// y = y + A(x-y)
|
||||
pllState.iir_y += ((x-pllState.iir_y)>>3);
|
||||
|
||||
newSetting = pllState.iir_y;
|
||||
|
||||
// Only output new frequency tune value if different to the previous setting
|
||||
if (newSetting != pllState.setting)
|
||||
{
|
||||
set = (initialSetting + newSetting); // init_set is our calculation of the setting required after measuring one cycle, should be accurate to +- 1MCLK.
|
||||
|
||||
if (set < 0)
|
||||
set = 0;
|
||||
else if (set > 0xFFFFF)
|
||||
set = 0xFFFFF;
|
||||
}
|
||||
|
||||
pllState.setting = newSetting;
|
||||
|
||||
// Return the setting to the NCO thread. -1 means no update
|
||||
return set;
|
||||
}
|
||||
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
||||
[[distributable]]
|
||||
#endif
|
||||
void XUA_SoftPll(tileref tile, server interface SoftPll_if i_softPll, chanend c_update)
|
||||
{
|
||||
#if (XUA_SYNCMODE != XUA_SYNCMODE_ASYNC)
|
||||
unsigned frac_val;
|
||||
int ds_out;
|
||||
timer tmr;
|
||||
int time;
|
||||
unsigned mclk_pt;
|
||||
unsigned short mclk_pt_last;
|
||||
tmr :> time;
|
||||
#endif
|
||||
struct SoftPllState pllState;
|
||||
int running = 0;
|
||||
int firstUpdate = 1;
|
||||
int fastLock = 1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
select
|
||||
{
|
||||
/* Interface used for basic frequency setting such that it can be distributed
|
||||
* when the update code is not required */
|
||||
case i_softPll.init(int mclk_hz):
|
||||
AppPllEnable(tile, mclk_hz);
|
||||
SoftPllInit(mclk_hz, pllState);
|
||||
running = 1;
|
||||
firstUpdate = 1;
|
||||
fastLock = 1;
|
||||
break;
|
||||
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Channel used for update such that other side is not blocked */
|
||||
/* TODO add CT handshake before opening route */
|
||||
case inuint_byref(c_update, mclk_pt):
|
||||
inct(c_update);
|
||||
|
||||
if(firstUpdate)
|
||||
{
|
||||
firstUpdate = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int setting = SoftPllUpdate(tile, (unsigned short) mclk_pt, mclk_pt_last, pllState, fastLock);
|
||||
|
||||
fastLock = 0;
|
||||
|
||||
if(setting != -1)
|
||||
{
|
||||
pllState.ds_in = setting;
|
||||
// Limit input range for modulator stability.
|
||||
if(pllState.ds_in > 980000)
|
||||
pllState.ds_in = 980000;
|
||||
if(pllState.ds_in < 60000)
|
||||
pllState.ds_in = 60000;
|
||||
}
|
||||
}
|
||||
|
||||
mclk_pt_last = (unsigned short) mclk_pt;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Third order, 9 level output delta sigma. 20 bit unsigned input.
|
||||
ds_out = ((pllState.ds_x3<<4) + (pllState.ds_x3<<1)) >> 13;
|
||||
if (ds_out > 8)
|
||||
ds_out = 8;
|
||||
if (ds_out < 0)
|
||||
ds_out = 0;
|
||||
pllState.ds_x3 += (pllState.ds_x2>>5) - (ds_out<<9) - (ds_out<<8);
|
||||
pllState.ds_x2 += (pllState.ds_x1>>5) - (ds_out<<14);
|
||||
pllState.ds_x1 += pllState.ds_in - (ds_out<<17);
|
||||
|
||||
if (ds_out == 0)
|
||||
frac_val = 0x00000007; // 0/8
|
||||
else
|
||||
frac_val = ((ds_out - 1) << 8) | 0x80000007; // 1/8 to 8/8
|
||||
|
||||
// Now write the register.
|
||||
// We need to write the register at a specific period at a fast rate.
|
||||
// This period needs to be (div ref clk period (ns) * how many times we repeat same value)
|
||||
// In this case, div ref clk = 24/3 = 8MHz. So div ref clk period = 125ns.
|
||||
// We're using fraction denominators of 8, so these repeat every 8*125ns = 1us.
|
||||
// So minimum period we could use is 1us and multiples thereof.
|
||||
// The slower we write, the higher our jitter will be.
|
||||
|
||||
time += FRAC_REG_WRITE_DLY; // Time the reg write.
|
||||
tmr when timerafter(time) :> void;
|
||||
|
||||
// Write the register. Because we are timing the reg writes accurately we do not need to use reg write with ack.
|
||||
// This saves a lot of time. Additionally, apparently we can shorten the time for this reg write by only setting up the channel once and just doing a few instructions to do the write each time.
|
||||
// We can hard code this in assembler.
|
||||
if(running)
|
||||
{
|
||||
write_node_config_reg_no_ack(tile, XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, frac_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
398
lib_xua/src/core/clocking/fractions_80_top.h
Normal file
398
lib_xua/src/core/clocking/fractions_80_top.h
Normal file
@@ -0,0 +1,398 @@
|
||||
// Copyright 2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
// Header file listing fraction options searched
|
||||
// These values to go in the bottom 16 bits of the secondary PLL fractional-n divider register.
|
||||
short frac_values_80[391] = {
|
||||
0x3C4B, // Index: 0 Fraction: 61/76 = 0.8026
|
||||
0x3846, // Index: 1 Fraction: 57/71 = 0.8028
|
||||
0x3441, // Index: 2 Fraction: 53/66 = 0.8030
|
||||
0x303C, // Index: 3 Fraction: 49/61 = 0.8033
|
||||
0x2C37, // Index: 4 Fraction: 45/56 = 0.8036
|
||||
0x2832, // Index: 5 Fraction: 41/51 = 0.8039
|
||||
0x242D, // Index: 6 Fraction: 37/46 = 0.8043
|
||||
0x2028, // Index: 7 Fraction: 33/41 = 0.8049
|
||||
0x3D4C, // Index: 8 Fraction: 62/77 = 0.8052
|
||||
0x1C23, // Index: 9 Fraction: 29/36 = 0.8056
|
||||
0x3542, // Index: 10 Fraction: 54/67 = 0.8060
|
||||
0x181E, // Index: 11 Fraction: 25/31 = 0.8065
|
||||
0x2D38, // Index: 12 Fraction: 46/57 = 0.8070
|
||||
0x1419, // Index: 13 Fraction: 21/26 = 0.8077
|
||||
0x3A48, // Index: 14 Fraction: 59/73 = 0.8082
|
||||
0x252E, // Index: 15 Fraction: 38/47 = 0.8085
|
||||
0x3643, // Index: 16 Fraction: 55/68 = 0.8088
|
||||
0x1014, // Index: 17 Fraction: 17/21 = 0.8095
|
||||
0x3F4E, // Index: 18 Fraction: 64/79 = 0.8101
|
||||
0x2E39, // Index: 19 Fraction: 47/58 = 0.8103
|
||||
0x1D24, // Index: 20 Fraction: 30/37 = 0.8108
|
||||
0x2A34, // Index: 21 Fraction: 43/53 = 0.8113
|
||||
0x3744, // Index: 22 Fraction: 56/69 = 0.8116
|
||||
0x0C0F, // Index: 23 Fraction: 13/16 = 0.8125
|
||||
0x3C4A, // Index: 24 Fraction: 61/75 = 0.8133
|
||||
0x2F3A, // Index: 25 Fraction: 48/59 = 0.8136
|
||||
0x222A, // Index: 26 Fraction: 35/43 = 0.8140
|
||||
0x3845, // Index: 27 Fraction: 57/70 = 0.8143
|
||||
0x151A, // Index: 28 Fraction: 22/27 = 0.8148
|
||||
0x3440, // Index: 29 Fraction: 53/65 = 0.8154
|
||||
0x1E25, // Index: 30 Fraction: 31/38 = 0.8158
|
||||
0x2730, // Index: 31 Fraction: 40/49 = 0.8163
|
||||
0x303B, // Index: 32 Fraction: 49/60 = 0.8167
|
||||
0x3946, // Index: 33 Fraction: 58/71 = 0.8169
|
||||
0x080A, // Index: 34 Fraction: 9/11 = 0.8182
|
||||
0x3A47, // Index: 35 Fraction: 59/72 = 0.8194
|
||||
0x313C, // Index: 36 Fraction: 50/61 = 0.8197
|
||||
0x2831, // Index: 37 Fraction: 41/50 = 0.8200
|
||||
0x1F26, // Index: 38 Fraction: 32/39 = 0.8205
|
||||
0x3642, // Index: 39 Fraction: 55/67 = 0.8209
|
||||
0x161B, // Index: 40 Fraction: 23/28 = 0.8214
|
||||
0x3B48, // Index: 41 Fraction: 60/73 = 0.8219
|
||||
0x242C, // Index: 42 Fraction: 37/45 = 0.8222
|
||||
0x323D, // Index: 43 Fraction: 51/62 = 0.8226
|
||||
0x404E, // Index: 44 Fraction: 65/79 = 0.8228
|
||||
0x0D10, // Index: 45 Fraction: 14/17 = 0.8235
|
||||
0x3C49, // Index: 46 Fraction: 61/74 = 0.8243
|
||||
0x2E38, // Index: 47 Fraction: 47/57 = 0.8246
|
||||
0x2027, // Index: 48 Fraction: 33/40 = 0.8250
|
||||
0x333E, // Index: 49 Fraction: 52/63 = 0.8254
|
||||
0x1216, // Index: 50 Fraction: 19/23 = 0.8261
|
||||
0x3D4A, // Index: 51 Fraction: 62/75 = 0.8267
|
||||
0x2A33, // Index: 52 Fraction: 43/52 = 0.8269
|
||||
0x171C, // Index: 53 Fraction: 24/29 = 0.8276
|
||||
0x343F, // Index: 54 Fraction: 53/64 = 0.8281
|
||||
0x1C22, // Index: 55 Fraction: 29/35 = 0.8286
|
||||
0x3E4B, // Index: 56 Fraction: 63/76 = 0.8289
|
||||
0x2128, // Index: 57 Fraction: 34/41 = 0.8293
|
||||
0x262E, // Index: 58 Fraction: 39/47 = 0.8298
|
||||
0x2B34, // Index: 59 Fraction: 44/53 = 0.8302
|
||||
0x303A, // Index: 60 Fraction: 49/59 = 0.8305
|
||||
0x3540, // Index: 61 Fraction: 54/65 = 0.8308
|
||||
0x3A46, // Index: 62 Fraction: 59/71 = 0.8310
|
||||
0x3F4C, // Index: 63 Fraction: 64/77 = 0.8312
|
||||
0x0405, // Index: 64 Fraction: 5/6 = 0.8333
|
||||
0x414E, // Index: 65 Fraction: 66/79 = 0.8354
|
||||
0x3C48, // Index: 66 Fraction: 61/73 = 0.8356
|
||||
0x3742, // Index: 67 Fraction: 56/67 = 0.8358
|
||||
0x323C, // Index: 68 Fraction: 51/61 = 0.8361
|
||||
0x2D36, // Index: 69 Fraction: 46/55 = 0.8364
|
||||
0x2830, // Index: 70 Fraction: 41/49 = 0.8367
|
||||
0x232A, // Index: 71 Fraction: 36/43 = 0.8372
|
||||
0x424F, // Index: 72 Fraction: 67/80 = 0.8375
|
||||
0x1E24, // Index: 73 Fraction: 31/37 = 0.8378
|
||||
0x3843, // Index: 74 Fraction: 57/68 = 0.8382
|
||||
0x191E, // Index: 75 Fraction: 26/31 = 0.8387
|
||||
0x2E37, // Index: 76 Fraction: 47/56 = 0.8393
|
||||
0x1418, // Index: 77 Fraction: 21/25 = 0.8400
|
||||
0x3944, // Index: 78 Fraction: 58/69 = 0.8406
|
||||
0x242B, // Index: 79 Fraction: 37/44 = 0.8409
|
||||
0x343E, // Index: 80 Fraction: 53/63 = 0.8413
|
||||
0x0F12, // Index: 81 Fraction: 16/19 = 0.8421
|
||||
0x3A45, // Index: 82 Fraction: 59/70 = 0.8429
|
||||
0x2A32, // Index: 83 Fraction: 43/51 = 0.8431
|
||||
0x1A1F, // Index: 84 Fraction: 27/32 = 0.8438
|
||||
0x404C, // Index: 85 Fraction: 65/77 = 0.8442
|
||||
0x252C, // Index: 86 Fraction: 38/45 = 0.8444
|
||||
0x3039, // Index: 87 Fraction: 49/58 = 0.8448
|
||||
0x3B46, // Index: 88 Fraction: 60/71 = 0.8451
|
||||
0x0A0C, // Index: 89 Fraction: 11/13 = 0.8462
|
||||
0x3C47, // Index: 90 Fraction: 61/72 = 0.8472
|
||||
0x313A, // Index: 91 Fraction: 50/59 = 0.8475
|
||||
0x262D, // Index: 92 Fraction: 39/46 = 0.8478
|
||||
0x424E, // Index: 93 Fraction: 67/79 = 0.8481
|
||||
0x1B20, // Index: 94 Fraction: 28/33 = 0.8485
|
||||
0x2C34, // Index: 95 Fraction: 45/53 = 0.8491
|
||||
0x3D48, // Index: 96 Fraction: 62/73 = 0.8493
|
||||
0x1013, // Index: 97 Fraction: 17/20 = 0.8500
|
||||
0x3842, // Index: 98 Fraction: 57/67 = 0.8507
|
||||
0x272E, // Index: 99 Fraction: 40/47 = 0.8511
|
||||
0x3E49, // Index: 100 Fraction: 63/74 = 0.8514
|
||||
0x161A, // Index: 101 Fraction: 23/27 = 0.8519
|
||||
0x333C, // Index: 102 Fraction: 52/61 = 0.8525
|
||||
0x1C21, // Index: 103 Fraction: 29/34 = 0.8529
|
||||
0x3F4A, // Index: 104 Fraction: 64/75 = 0.8533
|
||||
0x2228, // Index: 105 Fraction: 35/41 = 0.8537
|
||||
0x282F, // Index: 106 Fraction: 41/48 = 0.8542
|
||||
0x2E36, // Index: 107 Fraction: 47/55 = 0.8545
|
||||
0x343D, // Index: 108 Fraction: 53/62 = 0.8548
|
||||
0x3A44, // Index: 109 Fraction: 59/69 = 0.8551
|
||||
0x404B, // Index: 110 Fraction: 65/76 = 0.8553
|
||||
0x0506, // Index: 111 Fraction: 6/7 = 0.8571
|
||||
0x424D, // Index: 112 Fraction: 67/78 = 0.8590
|
||||
0x3C46, // Index: 113 Fraction: 61/71 = 0.8592
|
||||
0x363F, // Index: 114 Fraction: 55/64 = 0.8594
|
||||
0x3038, // Index: 115 Fraction: 49/57 = 0.8596
|
||||
0x2A31, // Index: 116 Fraction: 43/50 = 0.8600
|
||||
0x242A, // Index: 117 Fraction: 37/43 = 0.8605
|
||||
0x434E, // Index: 118 Fraction: 68/79 = 0.8608
|
||||
0x1E23, // Index: 119 Fraction: 31/36 = 0.8611
|
||||
0x3740, // Index: 120 Fraction: 56/65 = 0.8615
|
||||
0x181C, // Index: 121 Fraction: 25/29 = 0.8621
|
||||
0x444F, // Index: 122 Fraction: 69/80 = 0.8625
|
||||
0x2B32, // Index: 123 Fraction: 44/51 = 0.8627
|
||||
0x3E48, // Index: 124 Fraction: 63/73 = 0.8630
|
||||
0x1215, // Index: 125 Fraction: 19/22 = 0.8636
|
||||
0x323A, // Index: 126 Fraction: 51/59 = 0.8644
|
||||
0x1F24, // Index: 127 Fraction: 32/37 = 0.8649
|
||||
0x2C33, // Index: 128 Fraction: 45/52 = 0.8654
|
||||
0x3942, // Index: 129 Fraction: 58/67 = 0.8657
|
||||
0x0C0E, // Index: 130 Fraction: 13/15 = 0.8667
|
||||
0x3A43, // Index: 131 Fraction: 59/68 = 0.8676
|
||||
0x2D34, // Index: 132 Fraction: 46/53 = 0.8679
|
||||
0x2025, // Index: 133 Fraction: 33/38 = 0.8684
|
||||
0x343C, // Index: 134 Fraction: 53/61 = 0.8689
|
||||
0x1316, // Index: 135 Fraction: 20/23 = 0.8696
|
||||
0x424C, // Index: 136 Fraction: 67/77 = 0.8701
|
||||
0x2E35, // Index: 137 Fraction: 47/54 = 0.8704
|
||||
0x1A1E, // Index: 138 Fraction: 27/31 = 0.8710
|
||||
0x3C45, // Index: 139 Fraction: 61/70 = 0.8714
|
||||
0x2126, // Index: 140 Fraction: 34/39 = 0.8718
|
||||
0x282E, // Index: 141 Fraction: 41/47 = 0.8723
|
||||
0x2F36, // Index: 142 Fraction: 48/55 = 0.8727
|
||||
0x363E, // Index: 143 Fraction: 55/63 = 0.8730
|
||||
0x3D46, // Index: 144 Fraction: 62/71 = 0.8732
|
||||
0x444E, // Index: 145 Fraction: 69/79 = 0.8734
|
||||
0x0607, // Index: 146 Fraction: 7/8 = 0.8750
|
||||
0x3F48, // Index: 147 Fraction: 64/73 = 0.8767
|
||||
0x3840, // Index: 148 Fraction: 57/65 = 0.8769
|
||||
0x3138, // Index: 149 Fraction: 50/57 = 0.8772
|
||||
0x2A30, // Index: 150 Fraction: 43/49 = 0.8776
|
||||
0x2328, // Index: 151 Fraction: 36/41 = 0.8780
|
||||
0x4049, // Index: 152 Fraction: 65/74 = 0.8784
|
||||
0x1C20, // Index: 153 Fraction: 29/33 = 0.8788
|
||||
0x3239, // Index: 154 Fraction: 51/58 = 0.8793
|
||||
0x1518, // Index: 155 Fraction: 22/25 = 0.8800
|
||||
0x3A42, // Index: 156 Fraction: 59/67 = 0.8806
|
||||
0x2429, // Index: 157 Fraction: 37/42 = 0.8810
|
||||
0x333A, // Index: 158 Fraction: 52/59 = 0.8814
|
||||
0x424B, // Index: 159 Fraction: 67/76 = 0.8816
|
||||
0x0E10, // Index: 160 Fraction: 15/17 = 0.8824
|
||||
0x434C, // Index: 161 Fraction: 68/77 = 0.8831
|
||||
0x343B, // Index: 162 Fraction: 53/60 = 0.8833
|
||||
0x252A, // Index: 163 Fraction: 38/43 = 0.8837
|
||||
0x3C44, // Index: 164 Fraction: 61/69 = 0.8841
|
||||
0x1619, // Index: 165 Fraction: 23/26 = 0.8846
|
||||
0x353C, // Index: 166 Fraction: 54/61 = 0.8852
|
||||
0x1E22, // Index: 167 Fraction: 31/35 = 0.8857
|
||||
0x454E, // Index: 168 Fraction: 70/79 = 0.8861
|
||||
0x262B, // Index: 169 Fraction: 39/44 = 0.8864
|
||||
0x2E34, // Index: 170 Fraction: 47/53 = 0.8868
|
||||
0x363D, // Index: 171 Fraction: 55/62 = 0.8871
|
||||
0x3E46, // Index: 172 Fraction: 63/71 = 0.8873
|
||||
0x464F, // Index: 173 Fraction: 71/80 = 0.8875
|
||||
0x0708, // Index: 174 Fraction: 8/9 = 0.8889
|
||||
0x4048, // Index: 175 Fraction: 65/73 = 0.8904
|
||||
0x383F, // Index: 176 Fraction: 57/64 = 0.8906
|
||||
0x3036, // Index: 177 Fraction: 49/55 = 0.8909
|
||||
0x282D, // Index: 178 Fraction: 41/46 = 0.8913
|
||||
0x2024, // Index: 179 Fraction: 33/37 = 0.8919
|
||||
0x3940, // Index: 180 Fraction: 58/65 = 0.8923
|
||||
0x181B, // Index: 181 Fraction: 25/28 = 0.8929
|
||||
0x424A, // Index: 182 Fraction: 67/75 = 0.8933
|
||||
0x292E, // Index: 183 Fraction: 42/47 = 0.8936
|
||||
0x3A41, // Index: 184 Fraction: 59/66 = 0.8939
|
||||
0x1012, // Index: 185 Fraction: 17/19 = 0.8947
|
||||
0x3B42, // Index: 186 Fraction: 60/67 = 0.8955
|
||||
0x2A2F, // Index: 187 Fraction: 43/48 = 0.8958
|
||||
0x444C, // Index: 188 Fraction: 69/77 = 0.8961
|
||||
0x191C, // Index: 189 Fraction: 26/29 = 0.8966
|
||||
0x3C43, // Index: 190 Fraction: 61/68 = 0.8971
|
||||
0x2226, // Index: 191 Fraction: 35/39 = 0.8974
|
||||
0x2B30, // Index: 192 Fraction: 44/49 = 0.8980
|
||||
0x343A, // Index: 193 Fraction: 53/59 = 0.8983
|
||||
0x3D44, // Index: 194 Fraction: 62/69 = 0.8986
|
||||
0x464E, // Index: 195 Fraction: 71/79 = 0.8987
|
||||
0x0809, // Index: 196 Fraction: 9/10 = 0.9000
|
||||
0x3F46, // Index: 197 Fraction: 64/71 = 0.9014
|
||||
0x363C, // Index: 198 Fraction: 55/61 = 0.9016
|
||||
0x2D32, // Index: 199 Fraction: 46/51 = 0.9020
|
||||
0x2428, // Index: 200 Fraction: 37/41 = 0.9024
|
||||
0x4047, // Index: 201 Fraction: 65/72 = 0.9028
|
||||
0x1B1E, // Index: 202 Fraction: 28/31 = 0.9032
|
||||
0x2E33, // Index: 203 Fraction: 47/52 = 0.9038
|
||||
0x4148, // Index: 204 Fraction: 66/73 = 0.9041
|
||||
0x1214, // Index: 205 Fraction: 19/21 = 0.9048
|
||||
0x4249, // Index: 206 Fraction: 67/74 = 0.9054
|
||||
0x2F34, // Index: 207 Fraction: 48/53 = 0.9057
|
||||
0x1C1F, // Index: 208 Fraction: 29/32 = 0.9062
|
||||
0x434A, // Index: 209 Fraction: 68/75 = 0.9067
|
||||
0x262A, // Index: 210 Fraction: 39/43 = 0.9070
|
||||
0x3035, // Index: 211 Fraction: 49/54 = 0.9074
|
||||
0x3A40, // Index: 212 Fraction: 59/65 = 0.9077
|
||||
0x444B, // Index: 213 Fraction: 69/76 = 0.9079
|
||||
0x090A, // Index: 214 Fraction: 10/11 = 0.9091
|
||||
0x464D, // Index: 215 Fraction: 71/78 = 0.9103
|
||||
0x3C42, // Index: 216 Fraction: 61/67 = 0.9104
|
||||
0x3237, // Index: 217 Fraction: 51/56 = 0.9107
|
||||
0x282C, // Index: 218 Fraction: 41/45 = 0.9111
|
||||
0x474E, // Index: 219 Fraction: 72/79 = 0.9114
|
||||
0x1E21, // Index: 220 Fraction: 31/34 = 0.9118
|
||||
0x3338, // Index: 221 Fraction: 52/57 = 0.9123
|
||||
0x484F, // Index: 222 Fraction: 73/80 = 0.9125
|
||||
0x1416, // Index: 223 Fraction: 21/23 = 0.9130
|
||||
0x3439, // Index: 224 Fraction: 53/58 = 0.9138
|
||||
0x1F22, // Index: 225 Fraction: 32/35 = 0.9143
|
||||
0x2A2E, // Index: 226 Fraction: 43/47 = 0.9149
|
||||
0x353A, // Index: 227 Fraction: 54/59 = 0.9153
|
||||
0x4046, // Index: 228 Fraction: 65/71 = 0.9155
|
||||
0x0A0B, // Index: 229 Fraction: 11/12 = 0.9167
|
||||
0x4248, // Index: 230 Fraction: 67/73 = 0.9178
|
||||
0x373C, // Index: 231 Fraction: 56/61 = 0.9180
|
||||
0x2C30, // Index: 232 Fraction: 45/49 = 0.9184
|
||||
0x2124, // Index: 233 Fraction: 34/37 = 0.9189
|
||||
0x383D, // Index: 234 Fraction: 57/62 = 0.9194
|
||||
0x1618, // Index: 235 Fraction: 23/25 = 0.9200
|
||||
0x393E, // Index: 236 Fraction: 58/63 = 0.9206
|
||||
0x2225, // Index: 237 Fraction: 35/38 = 0.9211
|
||||
0x2E32, // Index: 238 Fraction: 47/51 = 0.9216
|
||||
0x3A3F, // Index: 239 Fraction: 59/64 = 0.9219
|
||||
0x464C, // Index: 240 Fraction: 71/77 = 0.9221
|
||||
0x0B0C, // Index: 241 Fraction: 12/13 = 0.9231
|
||||
0x484E, // Index: 242 Fraction: 73/79 = 0.9241
|
||||
0x3C41, // Index: 243 Fraction: 61/66 = 0.9242
|
||||
0x3034, // Index: 244 Fraction: 49/53 = 0.9245
|
||||
0x2427, // Index: 245 Fraction: 37/40 = 0.9250
|
||||
0x3D42, // Index: 246 Fraction: 62/67 = 0.9254
|
||||
0x181A, // Index: 247 Fraction: 25/27 = 0.9259
|
||||
0x3E43, // Index: 248 Fraction: 63/68 = 0.9265
|
||||
0x2528, // Index: 249 Fraction: 38/41 = 0.9268
|
||||
0x3236, // Index: 250 Fraction: 51/55 = 0.9273
|
||||
0x3F44, // Index: 251 Fraction: 64/69 = 0.9275
|
||||
0x0C0D, // Index: 252 Fraction: 13/14 = 0.9286
|
||||
0x4146, // Index: 253 Fraction: 66/71 = 0.9296
|
||||
0x3438, // Index: 254 Fraction: 53/57 = 0.9298
|
||||
0x272A, // Index: 255 Fraction: 40/43 = 0.9302
|
||||
0x4247, // Index: 256 Fraction: 67/72 = 0.9306
|
||||
0x1A1C, // Index: 257 Fraction: 27/29 = 0.9310
|
||||
0x4348, // Index: 258 Fraction: 68/73 = 0.9315
|
||||
0x282B, // Index: 259 Fraction: 41/44 = 0.9318
|
||||
0x363A, // Index: 260 Fraction: 55/59 = 0.9322
|
||||
0x4449, // Index: 261 Fraction: 69/74 = 0.9324
|
||||
0x0D0E, // Index: 262 Fraction: 14/15 = 0.9333
|
||||
0x464B, // Index: 263 Fraction: 71/76 = 0.9342
|
||||
0x383C, // Index: 264 Fraction: 57/61 = 0.9344
|
||||
0x2A2D, // Index: 265 Fraction: 43/46 = 0.9348
|
||||
0x474C, // Index: 266 Fraction: 72/77 = 0.9351
|
||||
0x1C1E, // Index: 267 Fraction: 29/31 = 0.9355
|
||||
0x484D, // Index: 268 Fraction: 73/78 = 0.9359
|
||||
0x2B2E, // Index: 269 Fraction: 44/47 = 0.9362
|
||||
0x3A3E, // Index: 270 Fraction: 59/63 = 0.9365
|
||||
0x494E, // Index: 271 Fraction: 74/79 = 0.9367
|
||||
0x0E0F, // Index: 272 Fraction: 15/16 = 0.9375
|
||||
0x3C40, // Index: 273 Fraction: 61/65 = 0.9385
|
||||
0x2D30, // Index: 274 Fraction: 46/49 = 0.9388
|
||||
0x1E20, // Index: 275 Fraction: 31/33 = 0.9394
|
||||
0x2E31, // Index: 276 Fraction: 47/50 = 0.9400
|
||||
0x3E42, // Index: 277 Fraction: 63/67 = 0.9403
|
||||
0x0F10, // Index: 278 Fraction: 16/17 = 0.9412
|
||||
0x4044, // Index: 279 Fraction: 65/69 = 0.9420
|
||||
0x3033, // Index: 280 Fraction: 49/52 = 0.9423
|
||||
0x2022, // Index: 281 Fraction: 33/35 = 0.9429
|
||||
0x3134, // Index: 282 Fraction: 50/53 = 0.9434
|
||||
0x4246, // Index: 283 Fraction: 67/71 = 0.9437
|
||||
0x1011, // Index: 284 Fraction: 17/18 = 0.9444
|
||||
0x4448, // Index: 285 Fraction: 69/73 = 0.9452
|
||||
0x3336, // Index: 286 Fraction: 52/55 = 0.9455
|
||||
0x2224, // Index: 287 Fraction: 35/37 = 0.9459
|
||||
0x3437, // Index: 288 Fraction: 53/56 = 0.9464
|
||||
0x464A, // Index: 289 Fraction: 71/75 = 0.9467
|
||||
0x1112, // Index: 290 Fraction: 18/19 = 0.9474
|
||||
0x484C, // Index: 291 Fraction: 73/77 = 0.9481
|
||||
0x3639, // Index: 292 Fraction: 55/58 = 0.9483
|
||||
0x2426, // Index: 293 Fraction: 37/39 = 0.9487
|
||||
0x373A, // Index: 294 Fraction: 56/59 = 0.9492
|
||||
0x4A4E, // Index: 295 Fraction: 75/79 = 0.9494
|
||||
0x1213, // Index: 296 Fraction: 19/20 = 0.9500
|
||||
0x393C, // Index: 297 Fraction: 58/61 = 0.9508
|
||||
0x2628, // Index: 298 Fraction: 39/41 = 0.9512
|
||||
0x3A3D, // Index: 299 Fraction: 59/62 = 0.9516
|
||||
0x1314, // Index: 300 Fraction: 20/21 = 0.9524
|
||||
0x3C3F, // Index: 301 Fraction: 61/64 = 0.9531
|
||||
0x282A, // Index: 302 Fraction: 41/43 = 0.9535
|
||||
0x3D40, // Index: 303 Fraction: 62/65 = 0.9538
|
||||
0x1415, // Index: 304 Fraction: 21/22 = 0.9545
|
||||
0x3F42, // Index: 305 Fraction: 64/67 = 0.9552
|
||||
0x2A2C, // Index: 306 Fraction: 43/45 = 0.9556
|
||||
0x4043, // Index: 307 Fraction: 65/68 = 0.9559
|
||||
0x1516, // Index: 308 Fraction: 22/23 = 0.9565
|
||||
0x4245, // Index: 309 Fraction: 67/70 = 0.9571
|
||||
0x2C2E, // Index: 310 Fraction: 45/47 = 0.9574
|
||||
0x4346, // Index: 311 Fraction: 68/71 = 0.9577
|
||||
0x1617, // Index: 312 Fraction: 23/24 = 0.9583
|
||||
0x4548, // Index: 313 Fraction: 70/73 = 0.9589
|
||||
0x2E30, // Index: 314 Fraction: 47/49 = 0.9592
|
||||
0x4649, // Index: 315 Fraction: 71/74 = 0.9595
|
||||
0x1718, // Index: 316 Fraction: 24/25 = 0.9600
|
||||
0x484B, // Index: 317 Fraction: 73/76 = 0.9605
|
||||
0x3032, // Index: 318 Fraction: 49/51 = 0.9608
|
||||
0x494C, // Index: 319 Fraction: 74/77 = 0.9610
|
||||
0x1819, // Index: 320 Fraction: 25/26 = 0.9615
|
||||
0x4B4E, // Index: 321 Fraction: 76/79 = 0.9620
|
||||
0x3234, // Index: 322 Fraction: 51/53 = 0.9623
|
||||
0x4C4F, // Index: 323 Fraction: 77/80 = 0.9625
|
||||
0x191A, // Index: 324 Fraction: 26/27 = 0.9630
|
||||
0x3436, // Index: 325 Fraction: 53/55 = 0.9636
|
||||
0x1A1B, // Index: 326 Fraction: 27/28 = 0.9643
|
||||
0x3638, // Index: 327 Fraction: 55/57 = 0.9649
|
||||
0x1B1C, // Index: 328 Fraction: 28/29 = 0.9655
|
||||
0x383A, // Index: 329 Fraction: 57/59 = 0.9661
|
||||
0x1C1D, // Index: 330 Fraction: 29/30 = 0.9667
|
||||
0x3A3C, // Index: 331 Fraction: 59/61 = 0.9672
|
||||
0x1D1E, // Index: 332 Fraction: 30/31 = 0.9677
|
||||
0x3C3E, // Index: 333 Fraction: 61/63 = 0.9683
|
||||
0x1E1F, // Index: 334 Fraction: 31/32 = 0.9688
|
||||
0x3E40, // Index: 335 Fraction: 63/65 = 0.9692
|
||||
0x1F20, // Index: 336 Fraction: 32/33 = 0.9697
|
||||
0x4042, // Index: 337 Fraction: 65/67 = 0.9701
|
||||
0x2021, // Index: 338 Fraction: 33/34 = 0.9706
|
||||
0x4244, // Index: 339 Fraction: 67/69 = 0.9710
|
||||
0x2122, // Index: 340 Fraction: 34/35 = 0.9714
|
||||
0x4446, // Index: 341 Fraction: 69/71 = 0.9718
|
||||
0x2223, // Index: 342 Fraction: 35/36 = 0.9722
|
||||
0x4648, // Index: 343 Fraction: 71/73 = 0.9726
|
||||
0x2324, // Index: 344 Fraction: 36/37 = 0.9730
|
||||
0x484A, // Index: 345 Fraction: 73/75 = 0.9733
|
||||
0x2425, // Index: 346 Fraction: 37/38 = 0.9737
|
||||
0x4A4C, // Index: 347 Fraction: 75/77 = 0.9740
|
||||
0x2526, // Index: 348 Fraction: 38/39 = 0.9744
|
||||
0x4C4E, // Index: 349 Fraction: 77/79 = 0.9747
|
||||
0x2627, // Index: 350 Fraction: 39/40 = 0.9750
|
||||
0x2728, // Index: 351 Fraction: 40/41 = 0.9756
|
||||
0x2829, // Index: 352 Fraction: 41/42 = 0.9762
|
||||
0x292A, // Index: 353 Fraction: 42/43 = 0.9767
|
||||
0x2A2B, // Index: 354 Fraction: 43/44 = 0.9773
|
||||
0x2B2C, // Index: 355 Fraction: 44/45 = 0.9778
|
||||
0x2C2D, // Index: 356 Fraction: 45/46 = 0.9783
|
||||
0x2D2E, // Index: 357 Fraction: 46/47 = 0.9787
|
||||
0x2E2F, // Index: 358 Fraction: 47/48 = 0.9792
|
||||
0x2F30, // Index: 359 Fraction: 48/49 = 0.9796
|
||||
0x3031, // Index: 360 Fraction: 49/50 = 0.9800
|
||||
0x3132, // Index: 361 Fraction: 50/51 = 0.9804
|
||||
0x3233, // Index: 362 Fraction: 51/52 = 0.9808
|
||||
0x3334, // Index: 363 Fraction: 52/53 = 0.9811
|
||||
0x3435, // Index: 364 Fraction: 53/54 = 0.9815
|
||||
0x3536, // Index: 365 Fraction: 54/55 = 0.9818
|
||||
0x3637, // Index: 366 Fraction: 55/56 = 0.9821
|
||||
0x3738, // Index: 367 Fraction: 56/57 = 0.9825
|
||||
0x3839, // Index: 368 Fraction: 57/58 = 0.9828
|
||||
0x393A, // Index: 369 Fraction: 58/59 = 0.9831
|
||||
0x3A3B, // Index: 370 Fraction: 59/60 = 0.9833
|
||||
0x3B3C, // Index: 371 Fraction: 60/61 = 0.9836
|
||||
0x3C3D, // Index: 372 Fraction: 61/62 = 0.9839
|
||||
0x3D3E, // Index: 373 Fraction: 62/63 = 0.9841
|
||||
0x3E3F, // Index: 374 Fraction: 63/64 = 0.9844
|
||||
0x3F40, // Index: 375 Fraction: 64/65 = 0.9846
|
||||
0x4041, // Index: 376 Fraction: 65/66 = 0.9848
|
||||
0x4142, // Index: 377 Fraction: 66/67 = 0.9851
|
||||
0x4243, // Index: 378 Fraction: 67/68 = 0.9853
|
||||
0x4344, // Index: 379 Fraction: 68/69 = 0.9855
|
||||
0x4445, // Index: 380 Fraction: 69/70 = 0.9857
|
||||
0x4546, // Index: 381 Fraction: 70/71 = 0.9859
|
||||
0x4647, // Index: 382 Fraction: 71/72 = 0.9861
|
||||
0x4748, // Index: 383 Fraction: 72/73 = 0.9863
|
||||
0x4849, // Index: 384 Fraction: 73/74 = 0.9865
|
||||
0x494A, // Index: 385 Fraction: 74/75 = 0.9867
|
||||
0x4A4B, // Index: 386 Fraction: 75/76 = 0.9868
|
||||
0x4B4C, // Index: 387 Fraction: 76/77 = 0.9870
|
||||
0x4C4D, // Index: 388 Fraction: 77/78 = 0.9872
|
||||
0x4D4E, // Index: 389 Fraction: 78/79 = 0.9873
|
||||
0x4E4F, // Index: 390 Fraction: 79/80 = 0.9875
|
||||
};
|
||||
@@ -145,7 +145,7 @@ on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN;
|
||||
on tile[XUD_TILE] : in port p_spdif_rx = PORT_SPDIF_IN;
|
||||
#endif
|
||||
|
||||
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) || (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) || ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && (!XUA_USE_APP_PLL))
|
||||
/* Reference to external clock multiplier */
|
||||
on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF;
|
||||
#endif
|
||||
@@ -314,6 +314,9 @@ void usb_audio_io(chanend ?c_aud_in,
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
#endif
|
||||
#if (XUA_USE_APP_PLL)
|
||||
, client interface SoftPll_if i_softPll
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if (MIXER)
|
||||
@@ -364,6 +367,9 @@ void usb_audio_io(chanend ?c_aud_in,
|
||||
#define AUDIO_CHANNEL c_aud_in
|
||||
#endif
|
||||
XUA_AudioHub(AUDIO_CHANNEL, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc
|
||||
#if (XUA_USE_APP_PLL)
|
||||
, i_softPll
|
||||
#endif
|
||||
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
, c_spdif_tx
|
||||
#endif
|
||||
@@ -467,9 +473,14 @@ int main()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && !XUA_USE_APP_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
interface pll_ref_if i_pll_ref;
|
||||
#endif
|
||||
|
||||
#if (XUA_USE_APP_PLL)
|
||||
interface SoftPll_if i_softPll;
|
||||
chan c_swpll_update;
|
||||
#endif
|
||||
chan c_sof;
|
||||
chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */
|
||||
chan c_xud_in[ENDPOINT_COUNT_IN];
|
||||
@@ -491,7 +502,7 @@ int main()
|
||||
{
|
||||
USER_MAIN_CORES
|
||||
|
||||
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && XYA_USE_APP_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref);
|
||||
#endif
|
||||
on tile[XUD_TILE]:
|
||||
@@ -522,6 +533,10 @@ int main()
|
||||
c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg);
|
||||
}
|
||||
|
||||
#if (XUA_USE_APP_PLL)
|
||||
//XUA_SoftPll(tile[0], i_softPll, c_swpll_update);
|
||||
#endif
|
||||
|
||||
/* Core USB audio task, buffering, USB etc */
|
||||
{
|
||||
unsigned x;
|
||||
@@ -564,7 +579,11 @@ int main()
|
||||
#endif
|
||||
, c_mix_out
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
#if (!XUA_USE_APP_PLL)
|
||||
, i_pll_ref
|
||||
#else
|
||||
, c_swpll_update
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
//:
|
||||
@@ -579,6 +598,9 @@ int main()
|
||||
#endif /* XUA_USB_EN */
|
||||
}
|
||||
|
||||
#if(XUA_USE_APP_PLL)
|
||||
on tile[AUDIO_IO_TILE]: XUA_SoftPll(tile[0], i_softPll, c_swpll_update);
|
||||
#endif
|
||||
on tile[AUDIO_IO_TILE]:
|
||||
{
|
||||
/* Audio I/O task, includes mixing etc */
|
||||
@@ -601,6 +623,9 @@ int main()
|
||||
#endif
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
, i_pll_ref
|
||||
#endif
|
||||
#if (XUA_USE_APP_PLL)
|
||||
, i_softPll
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
29
lib_xua/src/core/user/audiohw/audiohw.c
Normal file
29
lib_xua/src/core/user/audiohw/audiohw.c
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/* Default implementations of AudioHwInit(), AudioHwConfig(), AudioHwConfig_Mute() and AudioHwConfig_UnMute() */
|
||||
|
||||
void AudioHwInit() __attribute__ ((weak));
|
||||
void AudioHwInit()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC) __attribute__ ((weak));
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void AudioHwConfig_Mute() __attribute__ ((weak));
|
||||
void AudioHwConfig_Mute()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void AudioHwConfig_UnMute() __attribute__ ((weak));
|
||||
void AudioHwConfig_UnMute()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
54
lib_xua/src/core/user/audiohw/audiohw.h
Normal file
54
lib_xua/src/core/user/audiohw/audiohw.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#ifndef _AUDIO_HW_H_
|
||||
#define _AUDIO_HW_H_
|
||||
|
||||
/* The functions below should be implemented for the external audio hardware arrangement of a specific design.
|
||||
* Note, default (empty) implementations of these are provided in audiohub_user.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief User audio hardware initialisation code
|
||||
*
|
||||
* This function is called when the device starts up and should contain user code to perform any required audio hardware initialisation
|
||||
*/
|
||||
void AudioHwInit(void);
|
||||
|
||||
/**
|
||||
* @brief User audio hardware configuration code
|
||||
*
|
||||
* This function is called when on sample rate change and should contain user code to configure audio hardware
|
||||
* (clocking, CODECs etc) for a specific mClk/Sample frequency
|
||||
*
|
||||
* \param samFreq The new sample frequency (in Hz)
|
||||
*
|
||||
* \param mClk The new master clock frequency (in Hz)
|
||||
*
|
||||
* \param dsdMode DSD mode, DSD_MODE_NATIVE, DSD_MODE_DOP or DSD_MODE_OFF
|
||||
*
|
||||
* \param sampRes_DAC Playback sample resolution (in bits)
|
||||
*
|
||||
* \param sampRes_ADC Record sample resolution (in bits)
|
||||
*/
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC);
|
||||
|
||||
/**
|
||||
* @brief User code mute audio hardware
|
||||
*
|
||||
* This function is called before AudioHwConfig() and should contain user code to mute audio hardware before a
|
||||
* sample rate change in order to reduced audible pops/clicks
|
||||
*
|
||||
* Note, if using the application PLL of a xcore.ai device this function will be called before the master-clock is
|
||||
* changed
|
||||
*/
|
||||
void AudioHwConfig_Mute(void);
|
||||
|
||||
/**
|
||||
* @brief User code to un-mute audio hardware
|
||||
*
|
||||
* This function is called after AudioHwConfig() and should contain user code to un-mute audio hardware after a
|
||||
* sample rate change
|
||||
*/
|
||||
void AudioHwConfig_UnMute(void);
|
||||
|
||||
#endif
|
||||
@@ -1,30 +1,51 @@
|
||||
// Copyright 2011-2021 XMOS LIMITED.
|
||||
// Copyright 2011-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#ifndef _AUDIOSTREAM_H_
|
||||
#define _AUDIOSTREAM_H_
|
||||
|
||||
/* Functions that handle functions that must occur on stream start/stop e.g. DAC mute/un-mute
|
||||
*
|
||||
* THESE NEED IMPLEMENTING FOR A SPECIFIC DESIGN
|
||||
*
|
||||
* */
|
||||
/* Functions that handle functionality that occur on stream start/stop e.g. DAC mute/un-mute.
|
||||
* They should be implemented for the external audio hardware arrangement of a specific design.
|
||||
*/
|
||||
|
||||
/* Any actions required for stream start e.g. DAC un-mute - run every stream start */
|
||||
/**
|
||||
* @brief User stream start code
|
||||
*
|
||||
* User code to perform any actions required at every stream start - either input or output
|
||||
*/
|
||||
void UserAudioStreamStart(void);
|
||||
|
||||
/* Any actions required on stream stop e.g. DAC mute - run every steam stop */
|
||||
/**
|
||||
* @brief User stream stop code
|
||||
*
|
||||
* User code to perform any actions required on every stream stop - either input or output*/
|
||||
void UserAudioStreamStop(void);
|
||||
|
||||
/* Any actions required on input stream start */
|
||||
/**
|
||||
* @brief User input stream stop code
|
||||
*
|
||||
* User code to perform any actions required on input stream start i.e. device to host
|
||||
*/
|
||||
void UserAudioInputStreamStart(void);
|
||||
|
||||
/* Any actions required on input stream stop */
|
||||
/**
|
||||
* @brief User input stream stop code
|
||||
*
|
||||
* User code to perform any actions required on input stream stop i.e. device to host
|
||||
*/
|
||||
void UserAudioInputStreamStop(void);
|
||||
|
||||
/* Any actions required on output stream start */
|
||||
/**
|
||||
* @brief User output stream start code
|
||||
*
|
||||
* User code to perform any actions required on output stream start i.e. host to device
|
||||
*/
|
||||
void UserAudioOutputStreamStart(void);
|
||||
|
||||
/* Any actions required on output stream stop */
|
||||
/**
|
||||
* @brief User output stream stop code
|
||||
*
|
||||
* User code to perfrom any actions required on output stream stop i.e. host to device
|
||||
*/
|
||||
void UserAudioOutputStreamStop(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
* @brief Human Interface Device (HID) API
|
||||
*
|
||||
* This file defines the Application Programming Interface (API) used to record HID
|
||||
* events and retrieve a HID Report for sending to a host.
|
||||
* events and retrieve a HID Report for sending to a host.
|
||||
* The using application has the responsibility to fulfill this API.
|
||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||
*/
|
||||
|
||||
#ifndef __USER_HID_H__
|
||||
#define __USER_HID_H__
|
||||
#ifndef _USER_HID_H_
|
||||
#define _USER_HID_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -34,22 +34,16 @@ typedef struct hidEvent_t {
|
||||
#define HID_MAX_DATA_BYTES ( 4 )
|
||||
#define HID_EVENT_INVALID_ID ( 0x100 )
|
||||
|
||||
#if XUA_HID_ENABLED
|
||||
|
||||
/**
|
||||
* \brief Get the data for the next HID Report
|
||||
*
|
||||
* \note This function returns the HID data as a list of unsigned char because the
|
||||
* \c XUD_SetReady_In() accepts data for transmission to the USB Host using
|
||||
* this type.
|
||||
*
|
||||
* \param[in] id The HID Report ID (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* Set to zero if the application provides only one HID Report
|
||||
* which does not include a Report ID
|
||||
* which does not include a Report ID
|
||||
* \param[out] hidData The HID data
|
||||
* If using Report IDs, this function places the Report ID in
|
||||
* the first element; otherwise the first element holds the
|
||||
* first byte of HID event data.
|
||||
* the first element; otherwise the first element holds the
|
||||
* first byte of HID event data.
|
||||
*
|
||||
* \returns The length of the HID Report in the \a hidData argument
|
||||
* \retval Zero means no new HID event data has been recorded for the given \a id
|
||||
@@ -61,5 +55,4 @@ size_t UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BY
|
||||
*/
|
||||
void UserHIDInit( void );
|
||||
|
||||
#endif /* ( 0 < HID_CONTROLS ) */
|
||||
#endif /* __USER_HID_H__ */
|
||||
#endif /* _USER_HID_H_ */
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
// Copyright 2013-2021 XMOS LIMITED.
|
||||
// Copyright 2013-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
* @brief User host active code
|
||||
*
|
||||
* This function can be used to perform user defined actions based on host present/not-present events.
|
||||
* This function is called on a change in state.
|
||||
*
|
||||
* \param active Indicates if the host is active or not. 1 for active, else 0
|
||||
*/
|
||||
void UserHostActive(int active);
|
||||
|
||||
@@ -3,10 +3,12 @@ TEST_FLAGS ?=
|
||||
|
||||
XCC_FLAGS_HS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
|
||||
-DBUS_SPEED=2 \
|
||||
-DXUA_USE_APP_PLL=0 \
|
||||
$(TEST_FLAGS)
|
||||
|
||||
XCC_FLAGS_FS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
|
||||
-DBUS_SPEED=1 \
|
||||
-DXUA_USE_APP_PLL=0 \
|
||||
$(TEST_FLAGS)
|
||||
|
||||
TARGET = test_xs3_600.xn
|
||||
|
||||
Reference in New Issue
Block a user