forked from PAWPAW-Mirror/lib_xua
Compare commits
67 Commits
v3.4.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 | ||
|
|
b1b28f1005 | ||
|
|
6d41cfcbea | ||
|
|
5404127dbf | ||
|
|
e5a270347a | ||
|
|
f509a12e7d | ||
|
|
4528bed740 | ||
|
|
e812ca3e8b | ||
|
|
2accc0429f | ||
|
|
36d5201365 | ||
|
|
cea580ba48 | ||
|
|
6815f12a90 | ||
|
|
799ad7ba86 | ||
|
|
3d7e66bdc0 | ||
|
|
a6387d5fef | ||
|
|
5ca0738b02 | ||
|
|
b0e732110d | ||
|
|
1702078e7c | ||
|
|
136ec2506c | ||
|
|
45e5ef7702 | ||
|
|
1ef5129fde | ||
|
|
b1fe49aff3 | ||
|
|
d3ad29e8a6 | ||
|
|
17944ad908 | ||
|
|
131dd252c0 | ||
|
|
23d043630f | ||
|
|
761a33f5e4 | ||
|
|
12ec1d7536 | ||
|
|
2dba6dce36 | ||
|
|
9cf931898e | ||
|
|
9b104af8cf | ||
|
|
c469dd6cde | ||
|
|
b238196f74 | ||
|
|
e9586b59d3 | ||
|
|
6d168b3209 | ||
|
|
d301fef6d7 | ||
|
|
1f4e9a99b8 | ||
|
|
981ea78be7 | ||
|
|
6cee90d876 | ||
|
|
79d14f8b59 | ||
|
|
05dcb8f3ab | ||
|
|
4e7ddb4036 | ||
|
|
e8fcc80415 | ||
|
|
71a657dc9a | ||
|
|
ccfca90451 |
@@ -1,6 +1,35 @@
|
|||||||
lib_xua Change Log
|
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
|
||||||
|
-----
|
||||||
|
|
||||||
|
* ADDED: Configurable word-length for I2S/TDM via XUA_I2S_N_BITS
|
||||||
|
* ADDED: Support for statically defined custom HID descriptor
|
||||||
|
* CHANGED: Rearranged main() such that adding custom code that uses lib_xud
|
||||||
|
is possible
|
||||||
|
* CHANGED: bNumConfigurations changed from 2 to 1, removing a work-around to
|
||||||
|
stop old Windows versions loading the composite driver
|
||||||
|
* FIXED: Memory corruption due to erroneous initialisation of mixer
|
||||||
|
weights when not in use (#152)
|
||||||
|
* FIXED: UserHostActive() not being called as expected (#326)
|
||||||
|
* FIXED: Exception when entering DSD mode (#327)
|
||||||
|
|
||||||
|
* Changes to dependencies:
|
||||||
|
|
||||||
|
- lib_spdif: 4.2.1 -> 5.0.0
|
||||||
|
|
||||||
|
- lib_xud: 2.2.2 -> 2.2.3
|
||||||
|
|
||||||
3.4.0
|
3.4.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|||||||
14
Jenkinsfile
vendored
14
Jenkinsfile
vendored
@@ -1,4 +1,4 @@
|
|||||||
@Library('xmos_jenkins_shared_library@v0.21.0') _
|
@Library('xmos_jenkins_shared_library@v0.24.0') _
|
||||||
|
|
||||||
getApproval()
|
getApproval()
|
||||||
|
|
||||||
@@ -145,12 +145,16 @@ pipeline {
|
|||||||
dir("${REPO}") {
|
dir("${REPO}") {
|
||||||
checkout scm
|
checkout scm
|
||||||
dir("${REPO}/host/xmosdfu") {
|
dir("${REPO}/host/xmosdfu") {
|
||||||
runVS('nmake /f Makefile.Win32')
|
withVS("vcvars32.bat") {
|
||||||
|
bat "nmake /f Makefile.Win32"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dir("host_usb_mixer_control") {
|
dir("host_usb_mixer_control") {
|
||||||
runVS('msbuild host_usb_mixer_control.vcxproj /property:Configuration=Release /property:Platform=x64')
|
withVS() {
|
||||||
sh 'mkdir Win/x64'
|
bat 'msbuild host_usb_mixer_control.vcxproj /property:Configuration=Release /property:Platform=x64'
|
||||||
sh 'mv bin/Release/x64/host_usb_mixer_control.exe Win/x64/xmos_mixer.exe'
|
}
|
||||||
|
bat 'mkdir Win\\x64'
|
||||||
|
bat 'mv bin/Release/x64/host_usb_mixer_control.exe Win/x64/xmos_mixer.exe'
|
||||||
archiveArtifacts artifacts: "Win/x64/xmos_mixer.exe", fingerprint: true
|
archiveArtifacts artifacts: "Win/x64/xmos_mixer.exe", fingerprint: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
README.rst
10
README.rst
@@ -1,10 +1,8 @@
|
|||||||
lib_xua
|
lib_xua
|
||||||
#######
|
#######
|
||||||
|
|
||||||
:Version: 3.4.0
|
:Version: 3.5.0
|
||||||
:Vendor: XMOS
|
:Vendor: XMOS
|
||||||
|
|
||||||
|
|
||||||
:Scope: General Use
|
:Scope: General Use
|
||||||
|
|
||||||
Summary
|
Summary
|
||||||
@@ -41,9 +39,9 @@ Key features of the various components in this repository are as follows
|
|||||||
|
|
||||||
- Synchronisation to external digital streams i.e. S/PDIF or ADAT (when in asynchronous mode)
|
- Synchronisation to external digital streams i.e. S/PDIF or ADAT (when in asynchronous mode)
|
||||||
|
|
||||||
- I2S slave & master modes
|
- I2S (slave/master modes with configurable word-length)
|
||||||
|
|
||||||
- TDM slave & master modes
|
- TDM (slave/master modes with configurable word-length)
|
||||||
|
|
||||||
- MIDI input/output (Compliant to USB Class Specification for MIDI devices)
|
- MIDI input/output (Compliant to USB Class Specification for MIDI devices)
|
||||||
|
|
||||||
@@ -53,6 +51,8 @@ Key features of the various components in this repository are as follows
|
|||||||
|
|
||||||
- Simple playback controls via USB Human Interface Device (HID) Class
|
- Simple playback controls via USB Human Interface Device (HID) Class
|
||||||
|
|
||||||
|
- Support for adding custom HID interfaces
|
||||||
|
|
||||||
Note, not all features may be supported at all sample frequencies, simultaneously or on all devices.
|
Note, not all features may be supported at all sample frequencies, simultaneously or on all devices.
|
||||||
Some features may also require specific host driver support.
|
Some features may also require specific host driver support.
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
#include "../../shared/apppll.h"
|
|
||||||
|
|
||||||
on tile[0]: out port p_ctrl = XS1_PORT_8D;
|
on tile[0]: out port p_ctrl = XS1_PORT_8D;
|
||||||
|
|
||||||
@@ -35,11 +34,6 @@ void ctrlPort()
|
|||||||
void AudioHwInit()
|
void AudioHwInit()
|
||||||
{
|
{
|
||||||
/* Wait for power supply to come up */
|
/* 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);
|
delay_milliseconds(100);
|
||||||
|
|
||||||
/* DAC setup: For basic I2S input we don't need any register setup. DACs will clock auto detect etc.
|
/* 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)
|
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.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
#include "../../shared/apppll.h"
|
|
||||||
|
|
||||||
on tile[0]: out port p_ctrl = XS1_PORT_8D;
|
on tile[0]: out port p_ctrl = XS1_PORT_8D;
|
||||||
|
|
||||||
@@ -35,11 +34,6 @@ void ctrlPort()
|
|||||||
void AudioHwInit()
|
void AudioHwInit()
|
||||||
{
|
{
|
||||||
/* Wait for power supply to come up */
|
/* 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);
|
delay_milliseconds(100);
|
||||||
|
|
||||||
/* DAC setup: For basic I2S input we don't need any register setup. DACs will clock auto detect etc.
|
/* 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)
|
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"
|
#include "dfu_interface.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "xua_clocking.h"
|
||||||
|
|
||||||
/** The audio driver thread.
|
/** The audio driver thread.
|
||||||
*
|
*
|
||||||
* This function drives I2S ports and handles samples to/from other digital
|
* 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 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_spdif_tx Channel connected to S/PDIF transmiter core from lib_spdif
|
||||||
*
|
*
|
||||||
* \param c_dig Channel connected to the clockGen() thread for
|
* \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 _XUA_CLK_DIR port:32 ?p_bclk,
|
||||||
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
||||||
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
|
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__)
|
#if (XUA_SPDIF_TX_EN) || defined(__DOXYGEN__)
|
||||||
, chanend c_spdif_tx
|
, chanend c_spdif_tx
|
||||||
#endif
|
#endif
|
||||||
@@ -63,21 +70,28 @@ void XUA_AudioHub(chanend ?c_aud,
|
|||||||
|
|
||||||
void SpdifTxWrapper(chanend c_spdif_tx);
|
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__
|
#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[]);
|
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_
|
#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.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#ifndef __XUA_BUFFER_H__
|
#ifndef _XUA_BUFFER_H_
|
||||||
#define __XUA_BUFFER_H__
|
#define _XUA_BUFFER_H_
|
||||||
|
|
||||||
#if __XC__
|
#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 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 c_aud Channel connected to XUA_AudioHub() core
|
||||||
* \param i_pll_ref Interface to task that toggles reference pin to CS2100
|
* \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(
|
void XUA_Buffer(
|
||||||
chanend c_aud_out,
|
chanend c_aud_out,
|
||||||
@@ -51,8 +52,13 @@ void XUA_Buffer(
|
|||||||
, chanend c_hid
|
, chanend c_hid
|
||||||
#endif
|
#endif
|
||||||
, chanend c_aud
|
, 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
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
|
#if (XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||||
|
, chanend c_swpll_update
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -81,10 +87,16 @@ void XUA_Buffer_Ep(chanend c_aud_out,
|
|||||||
#ifdef CHAN_BUFF_CTRL
|
#ifdef CHAN_BUFF_CTRL
|
||||||
, chanend c_buff_ctrl
|
, chanend c_buff_ctrl
|
||||||
#endif
|
#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
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
|
#if (XUA_USE_APP_PLL) || defined(__DOXYGEN__)
|
||||||
|
, chanend c_swpll_update
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/** Manage the data transfer between the USB audio buffer and the
|
/** Manage the data transfer between the USB audio buffer and the
|
||||||
* Audio I/O driver.
|
* 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.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
#ifndef _CLOCKING_H_
|
#ifndef _CLOCKING_H_
|
||||||
#define _CLOCKING_H_
|
#define _CLOCKING_H_
|
||||||
|
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
|
#include "xua.h"
|
||||||
|
|
||||||
interface pll_ref_if
|
interface pll_ref_if
|
||||||
{
|
{
|
||||||
@@ -28,5 +29,46 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_sync);
|
|||||||
interrupts
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
#include "xua_conf.h"
|
#include "xua_conf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default tile arrangement */
|
/*
|
||||||
|
* Tile arrangement defines
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of audio I/O. Default: 0
|
* @brief Location (tile) of audio I/O. Default: 0
|
||||||
@@ -55,12 +57,9 @@
|
|||||||
#define PLL_REF_TILE AUDIO_IO_TILE
|
#define PLL_REF_TILE AUDIO_IO_TILE
|
||||||
#endif
|
#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)
|
* @brief Number of input channels (device to host). Default: NONE (Must be defined by app)
|
||||||
@@ -79,7 +78,18 @@
|
|||||||
#endif
|
#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(DSD_CHANS_DAC) && (DSD_CHANS_DAC != 0)
|
||||||
#if defined(NATIVE_DSD) && (NATIVE_DSD == 0)
|
#if defined(NATIVE_DSD) && (NATIVE_DSD == 0)
|
||||||
@@ -91,9 +101,41 @@
|
|||||||
#define DSD_CHANS_DAC 0
|
#define DSD_CHANS_DAC 0
|
||||||
#endif
|
#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_I2S (0)
|
||||||
#define XUA_PCM_FORMAT_TDM (1)
|
#define XUA_PCM_FORMAT_TDM (1)
|
||||||
|
/**
|
||||||
|
* @brief Format of PCM audio interface. Should be set to XUA_PCM_FORMAT_I2S or XUA_PCM_FORMAT_TDM
|
||||||
|
*
|
||||||
|
* Default: XUA_PCM_FORMAT_I2S
|
||||||
|
*/
|
||||||
#ifdef XUA_PCM_FORMAT
|
#ifdef XUA_PCM_FORMAT
|
||||||
#if (XUA_PCM_FORMAT != XUA_PCM_FORMAT_I2S) && (XUA_PCM_FORMAT != XUA_PCM_FORMAT_TDM)
|
#if (XUA_PCM_FORMAT != XUA_PCM_FORMAT_I2S) && (XUA_PCM_FORMAT != XUA_PCM_FORMAT_TDM)
|
||||||
#error Bad value for XUA_PCM_FORMAT
|
#error Bad value for XUA_PCM_FORMAT
|
||||||
@@ -116,30 +158,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#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
|
#ifndef XUA_I2S_N_BITS
|
||||||
#error I2S_CHANS_DAC not defined
|
#define XUA_I2S_N_BITS (32)
|
||||||
#define I2S_CHANS_DAC 2 /* Define anyway for doxygen */
|
|
||||||
#else
|
|
||||||
#define I2S_WIRES_DAC (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)
|
|
||||||
#endif
|
#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)
|
||||||
* @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
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,22 +222,32 @@
|
|||||||
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clocking related defines
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Max supported sample frequency for device (Hz). Default: 192000
|
* @brief Max supported sample frequency for device (Hz).
|
||||||
|
*
|
||||||
|
* Default: 192000Hz
|
||||||
*/
|
*/
|
||||||
#ifndef MAX_FREQ
|
#ifndef MAX_FREQ
|
||||||
#define MAX_FREQ (192000)
|
#define MAX_FREQ (192000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Min supported sample frequency for device (Hz). Default 44100
|
* @brief Min supported sample frequency for device (Hz).
|
||||||
|
*
|
||||||
|
* Default: 44100Hz
|
||||||
*/
|
*/
|
||||||
#ifndef MIN_FREQ
|
#ifndef MIN_FREQ
|
||||||
#define MIN_FREQ (44100)
|
#define MIN_FREQ (44100)
|
||||||
#endif
|
#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
|
#ifndef MCLK_441
|
||||||
#error MCLK_441 not defined
|
#error MCLK_441 not defined
|
||||||
@@ -216,7 +255,9 @@
|
|||||||
#endif
|
#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
|
#ifndef MCLK_48
|
||||||
#error MCLK_48 not defined
|
#error MCLK_48 not defined
|
||||||
@@ -224,26 +265,66 @@
|
|||||||
#endif
|
#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
|
#ifndef DEFAULT_FREQ
|
||||||
#define DEFAULT_FREQ (MIN_FREQ)
|
#define DEFAULT_FREQ (MIN_FREQ)
|
||||||
#endif
|
#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
|
#ifndef AUDIO_CLASS
|
||||||
#define AUDIO_CLASS 2
|
#define AUDIO_CLASS (2)
|
||||||
#endif
|
#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
|
#ifndef AUDIO_CLASS_FALLBACK
|
||||||
#define AUDIO_CLASS_FALLBACK 0 /* Default to not falling back to UAC 1 */
|
#define AUDIO_CLASS_FALLBACK (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,14 +353,17 @@
|
|||||||
#error AUDIO_CLASS set to 1 and FULL_SPEED_AUDIO_2 enabled!
|
#error AUDIO_CLASS set to 1 and FULL_SPEED_AUDIO_2 enabled!
|
||||||
#endif
|
#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
|
#ifndef XUA_USB_EN
|
||||||
#define XUA_NUM_PDM_MICS (0)
|
#define XUA_USB_EN (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -432,14 +516,36 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
* HID may be required in two forms: the built-in XUA-HID reports, or a
|
||||||
|
* user-provided static HID. Some sections of code are always needed, they
|
||||||
|
* are enclosed in XUA_OR_STATIC_HID_ENABLED; code specific to XUA-HID
|
||||||
|
* reports are enclosed in XUA_HID_ENABLED.
|
||||||
*
|
*
|
||||||
* 0: XMOS is I2S master. 1: CODEC is I2s master.
|
* HID_CONTROLS implies that the XUA_HID is used, and hence defines both.
|
||||||
|
* In order to roll your own, do not enable HID_CONTROLS, but instead
|
||||||
|
* create a file static_hid_report.h that contains the static descriptor.
|
||||||
*
|
*
|
||||||
* Default: 0 (XMOS is master)
|
* You must also supply your own function to deal with the HID endpoint(s)
|
||||||
|
* in this case.
|
||||||
*/
|
*/
|
||||||
#ifndef CODEC_MASTER
|
#if (HID_CONTROLS) || defined (__DOXYGEN__)
|
||||||
#define CODEC_MASTER (0)
|
#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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable a HID OUT endpoint. Only use this if you supply your own HID control.
|
||||||
|
*
|
||||||
|
* 1 for enabled, 0 for disabled.
|
||||||
|
*
|
||||||
|
* Default 0 (Disabled)
|
||||||
|
*/
|
||||||
|
#ifndef HID_OUT_REQUIRED
|
||||||
|
#define HID_OUT_REQUIRED (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1146,7 +1252,7 @@ enum USBEndpointNumber_In
|
|||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
ENDPOINT_NUMBER_IN_MIDI,
|
ENDPOINT_NUMBER_IN_MIDI,
|
||||||
#endif
|
#endif
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
ENDPOINT_NUMBER_IN_HID,
|
ENDPOINT_NUMBER_IN_HID,
|
||||||
#endif
|
#endif
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
@@ -1173,6 +1279,9 @@ enum USBEndpointNumber_Out
|
|||||||
#ifdef IAP_EA_NATIVE_TRANS
|
#ifdef IAP_EA_NATIVE_TRANS
|
||||||
ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS,
|
ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS,
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#if XUA_OR_STATIC_HID_ENABLED && HID_OUT_REQUIRED
|
||||||
|
ENDPOINT_NUMBER_OUT_HID,
|
||||||
#endif
|
#endif
|
||||||
XUA_ENDPOINT_COUNT_OUT /* End marker */
|
XUA_ENDPOINT_COUNT_OUT /* End marker */
|
||||||
};
|
};
|
||||||
@@ -1194,7 +1303,8 @@ enum USBEndpointNumber_Out
|
|||||||
#define AUDIO_START_FROM_DFU (0x87654321)
|
#define AUDIO_START_FROM_DFU (0x87654321)
|
||||||
#define AUDIO_REBOOT_FROM_DFU (0xa5a5a5a5)
|
#define AUDIO_REBOOT_FROM_DFU (0xa5a5a5a5)
|
||||||
|
|
||||||
#define MAX_VOL (0x20000000)
|
/* Result of db_to_mult(MAX_VOLUME, 8, 29) */
|
||||||
|
#define MAX_VOLUME_MULT (0x20000000)
|
||||||
|
|
||||||
#if defined(LEVEL_METER_LEDS) && !defined(LEVEL_UPDATE_RATE)
|
#if defined(LEVEL_METER_LEDS) && !defined(LEVEL_UPDATE_RATE)
|
||||||
#define LEVEL_UPDATE_RATE (400000)
|
#define LEVEL_UPDATE_RATE (400000)
|
||||||
|
|||||||
@@ -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``.
|
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``
|
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)
|
Code Location (tile)
|
||||||
--------------------
|
--------------------
|
||||||
@@ -25,12 +25,12 @@ Code Location (tile)
|
|||||||
Channel Counts
|
Channel Counts
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
.. doxygendefine:: NUM_USB_CHAN_OUT
|
.. doxygendefine:: NUM_USB_CHAN_OUT
|
||||||
.. doxygendefine:: NUM_USB_CHAN_IN
|
.. doxygendefine:: NUM_USB_CHAN_IN
|
||||||
.. doxygendefine:: I2S_CHANS_DAC
|
.. doxygendefine:: I2S_CHANS_DAC
|
||||||
.. doxygendefine:: I2S_CHANS_ADC
|
.. doxygendefine:: I2S_CHANS_ADC
|
||||||
|
|
||||||
Frequencies and Clocks
|
Frequencies and Clocks
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
.. doxygendefine:: MAX_FREQ
|
.. doxygendefine:: MAX_FREQ
|
||||||
@@ -38,6 +38,7 @@ Frequencies and Clocks
|
|||||||
.. doxygendefine:: DEFAULT_FREQ
|
.. doxygendefine:: DEFAULT_FREQ
|
||||||
.. doxygendefine:: MCLK_441
|
.. doxygendefine:: MCLK_441
|
||||||
.. doxygendefine:: MCLK_48
|
.. doxygendefine:: MCLK_48
|
||||||
|
.. doxygendefine:: XUA_USE_APP_PLL
|
||||||
|
|
||||||
Audio Class
|
Audio Class
|
||||||
-----------
|
-----------
|
||||||
@@ -50,6 +51,15 @@ Audio Class
|
|||||||
Feature Configuration
|
Feature Configuration
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
I2S/TDM
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
.. doxygendefine:: I2S_CHANS_DAC
|
||||||
|
.. doxygendefine:: I2S_CHANS_ADC
|
||||||
|
.. doxygendefine:: CODEC_MASTER
|
||||||
|
.. doxygendefine:: XUA_I2S_N_BITS
|
||||||
|
.. doxygendefine:: XUA_PCM_FORMAT
|
||||||
|
|
||||||
MIDI
|
MIDI
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
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
|
.. doxygenfunction:: AudioHwInit
|
||||||
device boots up and should initialize the external audio harware e.g. clocking, DAC, ADC etc
|
.. 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)
|
Audio Stream Start/Stop Functions
|
||||||
|
---------------------------------
|
||||||
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
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
The following functions can be optionally used by the design. They can be useful for mute lines etc.
|
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
|
Host Active Functions
|
||||||
starts.
|
---------------------
|
||||||
|
|
||||||
.. c:function:: void AudioStreamStop(void)
|
|
||||||
|
|
||||||
This function is called when the audio stream from device to host stops.
|
|
||||||
|
|
||||||
Host Active
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The following function can be used to signal that the device is connected to a valid host.
|
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.
|
.. doxygenfunction:: UserHostActive
|
||||||
|
|
||||||
.. c:function:: void AudioStreamStart(int active)
|
|
||||||
|
|
||||||
:param active: Indicates if the host is active or not. 1 for active else 0.
|
|
||||||
|
|
||||||
|
|
||||||
HID Controls
|
HID Controls
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The following function is called when the device wishes to read physical user input (buttons etc).
|
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[])
|
.. doxygenfunction:: UserHIDGetData
|
||||||
|
|
||||||
: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.
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ Finally, a channel for the output samples must be declared, note, this should be
|
|||||||
|
|
||||||
The S/PDIF receiver should be called on the appropriate tile::
|
The S/PDIF receiver should be called on the appropriate tile::
|
||||||
|
|
||||||
SpdifReceive(p_spdif_rx, c_spdif_rx, 1, clk_spd_rx);
|
spdif_rx(c_spdif_rx,p_spdif_rx,clk_spd_rx,192000);
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
It is recomended to use the value 1 for the ``initial_divider`` parameter
|
It is recomended to use the value 192000 for the ``sample_freq_estimate`` parameter
|
||||||
|
|
||||||
With the steps above an S/PDIF stream can be captured by the xCORE. To be functionally useful the audio
|
With the steps above an S/PDIF stream can be captured by the xCORE. To be functionally useful the audio
|
||||||
master clock must be able to synchronise to this external digital stream. Additionally, the host can be
|
master clock must be able to synchronise to this external digital stream. Additionally, the host can be
|
||||||
|
|||||||
@@ -23,11 +23,14 @@ The defines in :ref:`opt_i2s_defines` effect the I2S implementation.
|
|||||||
- The desired number of input channels via I2S (0 for disabled)
|
- The desired number of input channels via I2S (0 for disabled)
|
||||||
- N/A (Must be defined)
|
- N/A (Must be defined)
|
||||||
* - ``XUA_PCM_FORMAT``
|
* - ``XUA_PCM_FORMAT``
|
||||||
- Enabled either TDM or I2S mode
|
- Enables either TDM or I2S mode
|
||||||
- ``XUA_PCM_FORMAT_I2S``
|
- ``XUA_PCM_FORMAT_I2S``
|
||||||
* - ``CODEC_MASTER``
|
* - ``CODEC_MASTER``
|
||||||
- Sets is xCORE is I2S master or slave
|
- Sets if xCORE is I2S master or slave
|
||||||
- ``0`` (xCORE is master)
|
- ``0`` (xCORE is master)
|
||||||
|
* - ``XUA_I2S_N_BITS``
|
||||||
|
- I2S/TDM word length (16, 32-bit supported)
|
||||||
|
- ``32``
|
||||||
|
|
||||||
The I2S code expects that the ports required for I2S (master clock, LR-clock, bit-clock and data lines) are be defined in the application XN file in the relevant `Tile``.
|
The I2S code expects that the ports required for I2S (master clock, LR-clock, bit-clock and data lines) are be defined in the application XN file in the relevant `Tile``.
|
||||||
For example::
|
For example::
|
||||||
@@ -42,8 +45,16 @@ For example::
|
|||||||
<Port Location="XS1_PORT_1G" Name="PORT_I2S_ADC1"/>
|
<Port Location="XS1_PORT_1G" Name="PORT_I2S_ADC1"/>
|
||||||
</Tile>
|
</Tile>
|
||||||
|
|
||||||
All of the I2S related ports must be 1-bit ports.
|
All of the I2S/TDM related ports must be 1-bit ports.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
TDM mode allows 8 channels (rather than 2) to be supplied on each dataline.
|
TDM mode allows 8 channels (rather than 2) to be supplied on each data-line.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Data output/input is in "I2S" format, rather than, say "left-justified" or "right-justified" formats.
|
||||||
|
I2S format specifies a single bit-clock delay after the LR-clock transition before sample-data is driven/received.
|
||||||
|
This also applies to TDM mode. TDM support in ADC/DAC hardware is quite varied, an "offset" value may need to be programmed into
|
||||||
|
the external device for compatible operation.
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ full listing of these ``TILE`` defines.
|
|||||||
- Description
|
- Description
|
||||||
- Default
|
- Default
|
||||||
* - ``AUDIO_IO_TILE``
|
* - ``AUDIO_IO_TILE``
|
||||||
- Tile on which I2S, ADAT Rx, S/PDIF Rx & mixer resides
|
- Tile on which I2S/TDM, ADAT Rx, S/PDIF Rx & mixer resides
|
||||||
- ``0``
|
- ``0``
|
||||||
* - ``XUD_TILE``
|
* - ``XUD_TILE``
|
||||||
- Tile on which USB resides, including buffering for all USB interfaces/endppoints
|
- Tile on which USB resides, including buffering for all USB interfaces/endppoints
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
|
|
||||||
|newpage|
|
|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).
|
USB specification(s).
|
||||||
|
|
||||||
Asynchronous mode (``XUA_SYNCMODE_ASYNC``) has the advantage that the device is clock-master. This means that
|
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
|
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
|
synchronise it's master clock to an external digital input stream e.g. S/PDIF thus avoiding sample-rate
|
||||||
conversion.
|
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
|
may not support. This is especially pertinent to embedded hosts, however, most PC's and mobile devices
|
||||||
will indeed support this mode.
|
will indeed support this mode.
|
||||||
|
|
||||||
Synchronous mode (``XUA_SYNCMODE_SYNC``) is an option if the target host does not support asynchronous 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.
|
from digital streams, such as S/PDIF, are not currently supported in this mode.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The selection of synchronisation mode is done at build time and cannot be changed dynamically.
|
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`
|
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
|
- USB synchronisation mode
|
||||||
- ``XUA_SYNCMODE_ASYNC``
|
- ``XUA_SYNCMODE_ASYNC``
|
||||||
|
|
||||||
When operating in synchronous mode an external Cirrus Logic CS2100 device is required for master clock
|
When operating in asynchronous mode xcore.ai based devices will be configured, by default, to use their internal
|
||||||
generation. The codebase expects to drive a synchronisation signal to this external device
|
"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:
|
.. _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
|
- Tile location of reference to CS2100 device
|
||||||
- ``AUDIO_IO_TILE``
|
- ``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::
|
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"/>
|
<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.
|
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.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Overview
|
|||||||
| +---------------------------------------------------------------------------------------------+
|
| +---------------------------------------------------------------------------------------------+
|
||||||
| | `USB Midi Device Class 1.0 <http://www.usb.org/developers/devclass_docs/midi10.pdf>`_ |
|
| | `USB Midi Device Class 1.0 <http://www.usb.org/developers/devclass_docs/midi10.pdf>`_ |
|
||||||
+---------------------------------+---------------------------------------------------------------------------------------------+
|
+---------------------------------+---------------------------------------------------------------------------------------------+
|
||||||
| Audio | I2S/TDM |
|
| Audio | I2S/TDM (16/32-bit) |
|
||||||
| +---------------------------------------------------------------------------------------------+
|
| +---------------------------------------------------------------------------------------------+
|
||||||
| | S/PDIF |
|
| | S/PDIF |
|
||||||
| +---------------------------------------------------------------------------------------------+
|
| +---------------------------------------------------------------------------------------------+
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ I2S/TDM
|
|||||||
|
|
||||||
I2S/TDM is typically fundamental to most products and is built into the ``XUA_AudioHub()`` core.
|
I2S/TDM is typically fundamental to most products and is built into the ``XUA_AudioHub()`` core.
|
||||||
|
|
||||||
In order to enable I2S on must declare an array of ports for the data-lines (one for each direction)::
|
In order to enable I2S/TDM on must declare an array of ports for the data-lines (one for each direction)::
|
||||||
|
|
||||||
/* Port declarations. Note, the defines come from the XN file */
|
/* Port declarations. Note, the defines come from the XN file */
|
||||||
buffered out port:32 p_i2s_dac[] = {PORT_I2S_DAC0}; /* I2S Data-line(s) */
|
buffered out port:32 p_i2s_dac[] = {PORT_I2S_DAC0}; /* I2S Data-line(s) */
|
||||||
@@ -22,7 +22,7 @@ Ports for the sample and bit clocks are also required::
|
|||||||
|
|
||||||
These ports must then be passed to the ``XUA_AudioHub()`` task appropriately.
|
These ports must then be passed to the ``XUA_AudioHub()`` task appropriately.
|
||||||
|
|
||||||
I2S functionality also requires two clock-blocks, one for bit and sample clock e.g.::
|
I2S/TDM functionality also requires two clock-blocks, one for bit-clock and another for the master clock e.g.::
|
||||||
|
|
||||||
/* Clock-block declarations */
|
/* Clock-block declarations */
|
||||||
clock clk_audio_bclk = on tile[0]: XS1_CLKBLK_4; /* Bit clock */
|
clock clk_audio_bclk = on tile[0]: XS1_CLKBLK_4; /* Bit clock */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
XMOSNEWSTYLE = 2
|
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
|
SOURCE_INCLUDE_DIRS=../../../lib_xua
|
||||||
SPHINX_MASTER_DOC=lib_xua
|
SPHINX_MASTER_DOC=lib_xua
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
VERSION = 3.4.0
|
VERSION = 3.5.1
|
||||||
|
|
||||||
DEBUG ?= 0
|
DEBUG ?= 0
|
||||||
|
|
||||||
@@ -11,9 +11,9 @@ endif
|
|||||||
DEPENDENT_MODULES = lib_locks(>=2.1.0) \
|
DEPENDENT_MODULES = lib_locks(>=2.1.0) \
|
||||||
lib_logging(>=3.1.1) \
|
lib_logging(>=3.1.1) \
|
||||||
lib_mic_array(>=4.5.0) \
|
lib_mic_array(>=4.5.0) \
|
||||||
lib_spdif(>=4.2.1) \
|
lib_spdif(>=5.0.0) \
|
||||||
lib_xassert(>=4.1.0) \
|
lib_xassert(>=4.1.0) \
|
||||||
lib_xud(>=2.2.2) \
|
lib_xud(>=2.2.3) \
|
||||||
lib_adat(>=1.0.0)
|
lib_adat(>=1.0.0)
|
||||||
|
|
||||||
MODULE_XCC_FLAGS = $(XCC_FLAGS) \
|
MODULE_XCC_FLAGS = $(XCC_FLAGS) \
|
||||||
@@ -35,7 +35,7 @@ XCC_FLAGS_dfu.xc = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
|||||||
XCC_FLAGS_flash_interface.c = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
XCC_FLAGS_flash_interface.c = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
||||||
XCC_FLAGS_flashlib_user.c = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
XCC_FLAGS_flashlib_user.c = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
||||||
|
|
||||||
OPTIONAL_HEADERS += xua_conf.h
|
OPTIONAL_HEADERS += xua_conf.h static_hid_report.h
|
||||||
|
|
||||||
EXPORT_INCLUDE_DIRS = api \
|
EXPORT_INCLUDE_DIRS = api \
|
||||||
src/core \
|
src/core \
|
||||||
@@ -55,6 +55,7 @@ INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS) \
|
|||||||
src/core/user/audiostream \
|
src/core/user/audiostream \
|
||||||
src/core/user/hid \
|
src/core/user/hid \
|
||||||
src/core/user/hostactive \
|
src/core/user/hostactive \
|
||||||
|
src/core/user/audiohw \
|
||||||
src/hid \
|
src/hid \
|
||||||
src/midi
|
src/midi
|
||||||
|
|
||||||
@@ -70,6 +71,7 @@ SOURCE_DIRS = src/core \
|
|||||||
src/core/support \
|
src/core/support \
|
||||||
src/core/user/audiostream \
|
src/core/user/audiostream \
|
||||||
src/core/user/hostactive \
|
src/core/user/hostactive \
|
||||||
|
src/core/user/audiohw \
|
||||||
src/core/xuduser \
|
src/core/xuduser \
|
||||||
src/dfu \
|
src/dfu \
|
||||||
src/hid \
|
src/hid \
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2018-2022 XMOS LIMITED.
|
// Copyright 2018-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
#if (DSD_CHANS_DAC != 0)
|
#if (DSD_CHANS_DAC != 0)
|
||||||
@@ -52,7 +52,7 @@ static inline void DoDsdDop(int &everyOther, unsigned samplesOut[], unsigned &ds
|
|||||||
/* When DSD is enabled and streaming is standard PCM, this function checks for a series of DoP markers in the upper byte.
|
/* When DSD is enabled and streaming is standard PCM, this function checks for a series of DoP markers in the upper byte.
|
||||||
If found it will exit deliver() with the command to restart in DoP mode.
|
If found it will exit deliver() with the command to restart in DoP mode.
|
||||||
When in DoP mode, this function will check for a single absence of the DoP marker and exit deliver() with the command
|
When in DoP mode, this function will check for a single absence of the DoP marker and exit deliver() with the command
|
||||||
to restart in I2S mode. */
|
to restart in I2S/PCM mode. */
|
||||||
static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSamFreq, unsigned samplesOut[], unsigned &dsdMarker)
|
static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSamFreq, unsigned samplesOut[], unsigned &dsdMarker)
|
||||||
{
|
{
|
||||||
/* Check for DSD - note we only move into DoP mode if valid DoP Freq */
|
/* Check for DSD - note we only move into DoP mode if valid DoP Freq */
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright 2018-2022 XMOS LIMITED.
|
// Copyright 2018-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
|
|
||||||
#include "dsd_support.h"
|
#include "dsd_support.h"
|
||||||
|
|
||||||
#if (DSD_CHANS_DAC != 0)
|
#if (DSD_CHANS_DAC != 0)
|
||||||
@@ -12,7 +11,7 @@ extern buffered out port:32 p_dsd_clk;
|
|||||||
extern unsigned dsdMode;
|
extern unsigned dsdMode;
|
||||||
|
|
||||||
#if !CODEC_MASTER
|
#if !CODEC_MASTER
|
||||||
void InitPorts_master(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, 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])
|
void InitPorts_master(buffered _XUA_CLK_DIR port:32 p_lrclk, 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 (DSD_CHANS_DAC > 0)
|
#if (DSD_CHANS_DAC > 0)
|
||||||
if(dsdMode == DSD_MODE_OFF)
|
if(dsdMode == DSD_MODE_OFF)
|
||||||
@@ -39,7 +38,12 @@ void InitPorts_master(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, bu
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
p_lrclk <: 0 @ tmp;
|
|
||||||
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_lrclk <: 0 @ tmp;
|
||||||
|
else
|
||||||
|
tmp = partout_timestamped(p_lrclk, XUA_I2S_N_BITS, 0);
|
||||||
|
|
||||||
tmp += 100;
|
tmp += 100;
|
||||||
|
|
||||||
/* Since BCLK is free-running, setup outputs/inputs at a known point in the future */
|
/* Since BCLK is free-running, setup outputs/inputs at a known point in the future */
|
||||||
@@ -47,19 +51,30 @@ void InitPorts_master(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, bu
|
|||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||||
{
|
{
|
||||||
p_i2s_dac[i] @ tmp <: 0;
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_i2s_dac[i] @ tmp <: 0;
|
||||||
|
else
|
||||||
|
partout_timed(p_i2s_dac[i], XUA_I2S_N_BITS, 0, tmp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
unsigned lrClkVal = 0x7FFFFFFF;
|
||||||
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||||
p_lrclk @ tmp <: 0x80000000;
|
{
|
||||||
|
lrClkVal = 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_lrclk @ tmp <: lrClkVal;
|
||||||
else
|
else
|
||||||
p_lrclk @ tmp <: 0x7FFFFFFF;
|
partout_timed(p_lrclk, XUA_I2S_N_BITS, lrClkVal, tmp);
|
||||||
|
|
||||||
#if (I2S_CHANS_ADC != 0)
|
#if (I2S_CHANS_ADC != 0)
|
||||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||||
{
|
{
|
||||||
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
||||||
|
|
||||||
|
if(XUA_I2S_N_BITS != 32)
|
||||||
|
set_port_shift_count(p_i2s_adc[i], XUA_I2S_N_BITS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */
|
#endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */
|
||||||
@@ -75,7 +90,7 @@ void InitPorts_master(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, bu
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void InitPorts_slave(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, 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])
|
void InitPorts_slave(buffered _XUA_CLK_DIR port:32 p_lrclk, 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 (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
@@ -92,7 +107,7 @@ void InitPorts_slave(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buf
|
|||||||
p_lrclk when pinseq(0) :> void @ tmp;
|
p_lrclk when pinseq(0) :> void @ tmp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tmp += (I2S_CHANS_PER_FRAME * 32) - 32 + 1 ;
|
tmp += ((I2S_CHANS_PER_FRAME * XUA_I2S_N_BITS) - XUA_I2S_N_BITS + 1) ;
|
||||||
/* E.g. 2 * 32 - 32 + 1 = 33 for stereo */
|
/* E.g. 2 * 32 - 32 + 1 = 33 for stereo */
|
||||||
/* E.g. 8 * 32 - 32 + 1 = 225 for 8 chan TDM */
|
/* E.g. 8 * 32 - 32 + 1 = 225 for 8 chan TDM */
|
||||||
|
|
||||||
@@ -100,7 +115,10 @@ void InitPorts_slave(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buf
|
|||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||||
{
|
{
|
||||||
p_i2s_dac[i] @ tmp <: 0;
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_i2s_dac[i] @ tmp <: 0;
|
||||||
|
else
|
||||||
|
partout_timed(p_i2s_dac[i], XUA_I2S_N_BITS, 0, tmp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -108,11 +126,15 @@ void InitPorts_slave(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buf
|
|||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||||
{
|
{
|
||||||
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
||||||
|
if(XUA_I2S_N_BITS != 32)
|
||||||
|
set_port_shift_count(p_i2s_adc[i], XUA_I2S_N_BITS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(tmp-1));
|
asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(tmp-1));
|
||||||
|
if(XUA_I2S_N_BITS != 32)
|
||||||
|
set_port_shift_count(p_lrclk, XUA_I2S_N_BITS);
|
||||||
#endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */
|
#endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,9 +15,12 @@
|
|||||||
#include <xclib.h>
|
#include <xclib.h>
|
||||||
#include <xs1_su.h>
|
#include <xs1_su.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <xassert.h>
|
||||||
|
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
|
|
||||||
|
#include "audiohw.h"
|
||||||
|
|
||||||
#include "audioports.h"
|
#include "audioports.h"
|
||||||
#include "mic_array_conf.h"
|
#include "mic_array_conf.h"
|
||||||
#if (XUA_SPDIF_TX_EN)
|
#if (XUA_SPDIF_TX_EN)
|
||||||
@@ -50,19 +53,6 @@ unsigned samplesOut[MAX(NUM_USB_CHAN_OUT, I2S_CHANS_DAC)];
|
|||||||
|
|
||||||
unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)];
|
unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)];
|
||||||
|
|
||||||
#ifdef XTA_TIMING_AUDIO
|
|
||||||
#pragma xta command "add exclusion received_command"
|
|
||||||
#pragma xta command "analyse path i2s_output_l i2s_output_r"
|
|
||||||
#pragma xta command "set required - 2000 ns"
|
|
||||||
|
|
||||||
#pragma xta command "add exclusion received_command"
|
|
||||||
#pragma xta command "add exclusion received_underflow"
|
|
||||||
#pragma xta command "add exclusion divide_1"
|
|
||||||
#pragma xta command "add exclusion deliver_return"
|
|
||||||
#pragma xta command "analyse path i2s_output_r i2s_output_l"
|
|
||||||
#pragma xta command "set required - 2000 ns"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (XUA_ADAT_TX_EN)
|
#if (XUA_ADAT_TX_EN)
|
||||||
extern buffered out port:32 p_adat_tx;
|
extern buffered out port:32 p_adat_tx;
|
||||||
#endif
|
#endif
|
||||||
@@ -76,7 +66,7 @@ void InitPorts_slave
|
|||||||
#else
|
#else
|
||||||
void InitPorts_master
|
void InitPorts_master
|
||||||
#endif
|
#endif
|
||||||
(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DIR port:32 p_bclk, buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
(buffered _XUA_CLK_DIR port:32 p_lrclk, 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]);
|
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]);
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +86,17 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
|
|||||||
#if CODEC_MASTER
|
#if CODEC_MASTER
|
||||||
unsigned syncError = 0;
|
unsigned syncError = 0;
|
||||||
unsigned lrval = 0;
|
unsigned lrval = 0;
|
||||||
p_lrclk :> lrval;
|
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");
|
||||||
|
set_port_shift_count(p_lrclk, XUA_I2S_N_BITS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p_lrclk :> lrval;
|
||||||
|
}
|
||||||
|
|
||||||
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||||
{
|
{
|
||||||
@@ -114,30 +114,46 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(frameCount == 0)
|
if(XUA_I2S_N_BITS == 32)
|
||||||
syncError += (lrval != 0x80000000);
|
{
|
||||||
|
if(frameCount == 0)
|
||||||
|
syncError = (lrval != 0x80000000);
|
||||||
|
else
|
||||||
|
syncError = (lrval != 0x7FFFFFFF);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
syncError += (lrval != 0x7FFFFFFF);
|
{
|
||||||
|
if(frameCount == 0)
|
||||||
|
syncError = ((lrval & lrval_mask) != 0x80000000);
|
||||||
|
else
|
||||||
|
syncError = ((lrval | (~lrval_mask)) != 0x7FFFFFFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return syncError;
|
return syncError;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
unsigned clkVal;
|
||||||
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||||
{
|
{
|
||||||
if(frameCount == (I2S_CHANS_PER_FRAME-1))
|
if(frameCount == (I2S_CHANS_PER_FRAME-1))
|
||||||
p_lrclk <: 0x80000000;
|
clkVal = 0x80000000;
|
||||||
else
|
else
|
||||||
p_lrclk <: 0x00000000;
|
clkVal = 0x00000000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(frameCount == 0)
|
if(frameCount == 0)
|
||||||
p_lrclk <: 0x80000000;
|
clkVal = 0x80000000;
|
||||||
else
|
else
|
||||||
p_lrclk <: 0x7fffffff;
|
clkVal = 0x7fffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_lrclk <: clkVal;
|
||||||
|
else
|
||||||
|
partout(p_lrclk, XUA_I2S_N_BITS, clkVal >> (32 - XUA_I2S_N_BITS));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -254,9 +270,9 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
if ((I2S_CHANS_DAC > 0 || I2S_CHANS_ADC > 0))
|
if ((I2S_CHANS_DAC > 0 || I2S_CHANS_ADC > 0))
|
||||||
{
|
{
|
||||||
#if CODEC_MASTER
|
#if CODEC_MASTER
|
||||||
InitPorts_slave(divide, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
|
InitPorts_slave(p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
|
||||||
#else
|
#else
|
||||||
InitPorts_master(divide, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
|
InitPorts_master(p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +306,17 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
// p_i2s_adc[index++] :> sample;
|
// p_i2s_adc[index++] :> sample;
|
||||||
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
|
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
|
||||||
unsigned sample;
|
unsigned sample;
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index]));
|
||||||
|
|
||||||
sample = bitrev(sample);
|
sample = bitrev(sample);
|
||||||
int chanIndex = ((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i; // channels 0, 2, 4.. on each line.
|
if(XUA_I2S_N_BITS != 32)
|
||||||
|
{
|
||||||
|
set_port_shift_count(p_i2s_adc[index], XUA_I2S_N_BITS);
|
||||||
|
sample <<= (32 - XUA_I2S_N_BITS);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
|
||||||
|
int chanIndex = ((frameCount-2) & (I2S_CHANS_PER_FRAME-1)) + i; // channels 0, 2, 4.. on each line.
|
||||||
|
|
||||||
#if (AUD_TO_USB_RATIO > 1)
|
#if (AUD_TO_USB_RATIO > 1)
|
||||||
if ((AUD_TO_USB_RATIO - 1) == audioToUsbRatioCounter)
|
if ((AUD_TO_USB_RATIO - 1) == audioToUsbRatioCounter)
|
||||||
@@ -344,7 +368,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
src_ff3v_fir_coefs[2-audioToUsbRatioCounter]);
|
src_ff3v_fir_coefs[2-audioToUsbRatioCounter]);
|
||||||
}
|
}
|
||||||
#endif /* (AUD_TO_USB_RATIO > 1) */
|
#endif /* (AUD_TO_USB_RATIO > 1) */
|
||||||
p_i2s_dac[index++] <: bitrev(samplesOut[frameCount +i]);
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_i2s_dac[index++] <: bitrev(samplesOut[frameCount +i]);
|
||||||
|
else
|
||||||
|
partout(p_i2s_dac[index++], XUA_I2S_N_BITS, bitrev(samplesOut[frameCount +i]));
|
||||||
}
|
}
|
||||||
#endif // (I2S_CHANS_DAC != 0)
|
#endif // (I2S_CHANS_DAC != 0)
|
||||||
|
|
||||||
@@ -417,8 +444,15 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
{
|
{
|
||||||
/* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */
|
/* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */
|
||||||
unsigned sample;
|
unsigned sample;
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index]));
|
||||||
sample = bitrev(sample);
|
sample = bitrev(sample);
|
||||||
|
if(XUA_I2S_N_BITS != 32)
|
||||||
|
{
|
||||||
|
set_port_shift_count(p_i2s_adc[index], XUA_I2S_N_BITS);
|
||||||
|
sample <<= (32 - XUA_I2S_N_BITS);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
|
||||||
int chanIndex = ((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i; // channels 1, 3, 5.. on each line.
|
int chanIndex = ((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i; // channels 1, 3, 5.. on each line.
|
||||||
#if (AUD_TO_USB_RATIO > 1 && !I2S_DOWNSAMPLE_MONO_IN)
|
#if (AUD_TO_USB_RATIO > 1 && !I2S_DOWNSAMPLE_MONO_IN)
|
||||||
if ((AUD_TO_USB_RATIO - 1) == audioToUsbRatioCounter)
|
if ((AUD_TO_USB_RATIO - 1) == audioToUsbRatioCounter)
|
||||||
@@ -450,7 +484,6 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
#pragma xta endpoint "i2s_output_r"
|
|
||||||
#if (I2S_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0)
|
||||||
/* Output "odd" channel to DAC (i.e. right) */
|
/* Output "odd" channel to DAC (i.e. right) */
|
||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
@@ -469,7 +502,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
src_ff3v_fir_coefs[2-audioToUsbRatioCounter]);
|
src_ff3v_fir_coefs[2-audioToUsbRatioCounter]);
|
||||||
}
|
}
|
||||||
#endif /* (AUD_TO_USB_RATIO > 1) */
|
#endif /* (AUD_TO_USB_RATIO > 1) */
|
||||||
p_i2s_dac[index++] <: bitrev(samplesOut[frameCount + i]);
|
if(XUA_I2S_N_BITS == 32)
|
||||||
|
p_i2s_dac[index++] <: bitrev(samplesOut[frameCount + i]);
|
||||||
|
else
|
||||||
|
partout(p_i2s_dac[index++], XUA_I2S_N_BITS, bitrev(samplesOut[frameCount + i]));
|
||||||
}
|
}
|
||||||
#endif // (I2S_CHANS_DAC != 0)
|
#endif // (I2S_CHANS_DAC != 0)
|
||||||
|
|
||||||
@@ -523,7 +559,6 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma xta endpoint "deliver_return"
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,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 _XUA_CLK_DIR port:32 ?p_bclk,
|
||||||
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
|
||||||
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
|
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)
|
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||||
, chanend c_spdif_out
|
, chanend c_spdif_out
|
||||||
#endif
|
#endif
|
||||||
@@ -628,6 +666,12 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
unsigned divide;
|
unsigned divide;
|
||||||
unsigned firstRun = 1;
|
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 */
|
/* Clock master clock-block from master-clock port */
|
||||||
/* Note, marked unsafe since other cores may be using this mclk port */
|
/* Note, marked unsafe since other cores may be using this mclk port */
|
||||||
configure_clock_src(clk_audio_mclk, p_mclk_in);
|
configure_clock_src(clk_audio_mclk, p_mclk_in);
|
||||||
@@ -653,6 +697,8 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Perform required CODEC/ADC/DAC initialisation */
|
/* Perform required CODEC/ADC/DAC initialisation */
|
||||||
AudioHwInit();
|
AudioHwInit();
|
||||||
|
|
||||||
@@ -681,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
|
/* Calculate master clock to bit clock (or DSD clock) divide for current sample freq
|
||||||
* e.g. 11.289600 / (176400 * 64) = 1 */
|
* e.g. 11.289600 / (176400 * 64) = 1 */
|
||||||
{
|
{
|
||||||
#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
unsigned numBits = XUA_I2S_N_BITS * I2S_CHANS_PER_FRAME;
|
||||||
/* I2S has 32 bits per sample. *8 as 8 channels */
|
|
||||||
unsigned numBits = 256;
|
|
||||||
#else
|
|
||||||
/* I2S has 32 bits per sample. *2 as 2 channels */
|
|
||||||
unsigned numBits = 64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (DSD_CHANS_DAC > 0)
|
#if (DSD_CHANS_DAC > 0)
|
||||||
if(dsdMode == DSD_MODE_DOP)
|
if(dsdMode == DSD_MODE_DOP)
|
||||||
@@ -701,17 +741,24 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
numBits = 32;
|
numBits = 32;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
divide = mClk / ( curSamFreq * numBits);
|
divide = mClk / (curSamFreq * numBits);
|
||||||
|
|
||||||
|
//Do some checks
|
||||||
|
xassert((divide > 0) && "Error: divider is 0, BCLK rate unachievable");
|
||||||
|
|
||||||
|
unsigned remainder = mClk % ( curSamFreq * numBits);
|
||||||
|
xassert((!remainder) && "Error: MCLK not divisible into BCLK by an integer number");
|
||||||
|
|
||||||
|
unsigned divider_is_odd = divide & 0x1;
|
||||||
|
xassert((!divider_is_odd) && "Error: divider is odd, clockblock cannot produce desired BCLK");
|
||||||
|
|
||||||
/* TODO; we should catch and handle the case when divide is 0. Currently design will lock up */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (DSD_CHANS_DAC > 0)
|
#if (DSD_CHANS_DAC > 0)
|
||||||
if(dsdMode)
|
if(dsdMode)
|
||||||
{
|
{
|
||||||
/* Configure audio ports */
|
/* Configure audio ports */
|
||||||
ConfigAudioPortsWrapper(
|
ConfigAudioPortsWrapper(
|
||||||
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
||||||
p_dsd_dac,
|
p_dsd_dac,
|
||||||
DSD_CHANS_DAC,
|
DSD_CHANS_DAC,
|
||||||
@@ -724,7 +771,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
null,
|
null,
|
||||||
p_dsd_clk,
|
p_dsd_clk,
|
||||||
#endif
|
#endif
|
||||||
p_mclk_in, clk_audio_bclk, divide, curSamFreq, dsdMode);
|
p_mclk_in, clk_audio_bclk, divide, curSamFreq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -747,9 +794,8 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
p_bclk,
|
p_bclk,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
p_mclk_in, clk_audio_bclk, divide, curSamFreq, dsdMode);
|
p_mclk_in, clk_audio_bclk, divide, curSamFreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned curFreq = curSamFreq;
|
unsigned curFreq = curSamFreq;
|
||||||
@@ -764,8 +810,19 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
curFreq *= 16;
|
curFreq *= 16;
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
AudioHwConfig(curFreq, mClk, dsdMode, curSamRes_DAC, curSamRes_ADC);
|
||||||
|
|
||||||
|
/* User should unmute audio hardware */
|
||||||
|
AudioHwConfig_UnMute();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!firstRun)
|
if(!firstRun)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
/*** BUFFER SIZES ***/
|
/*** BUFFER SIZES ***/
|
||||||
|
|
||||||
#define BUFFER_PACKET_COUNT 4 /* How many packets too allow for in buffer - minimum is 4 */
|
#define BUFFER_PACKET_COUNT (4) /* How many packets too allow for in buffer - minimum is 4 */
|
||||||
|
|
||||||
#define BUFF_SIZE_OUT_HS MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS * BUFFER_PACKET_COUNT
|
#define BUFF_SIZE_OUT_HS MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS * BUFFER_PACKET_COUNT
|
||||||
#define BUFF_SIZE_OUT_FS MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS * BUFFER_PACKET_COUNT
|
#define BUFF_SIZE_OUT_FS MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS * BUFFER_PACKET_COUNT
|
||||||
@@ -55,16 +55,22 @@
|
|||||||
#define BUFF_SIZE_IN MAX(BUFF_SIZE_IN_HS, BUFF_SIZE_IN_FS)
|
#define BUFF_SIZE_IN MAX(BUFF_SIZE_IN_HS, BUFF_SIZE_IN_FS)
|
||||||
|
|
||||||
#define OUT_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS))
|
#define OUT_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS))
|
||||||
#define IN_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_IN_HS, MAX_DEVICE_AUD_PACKET_SIZE_IN_FS)*2)
|
#define IN_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_IN_HS, MAX_DEVICE_AUD_PACKET_SIZE_IN_FS)*2)
|
||||||
|
|
||||||
/* Volume and mute tables */
|
/* Volume and mute tables */
|
||||||
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
|
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
|
||||||
unsigned int multOut[NUM_USB_CHAN_OUT + 1];
|
unsigned int multOut[NUM_USB_CHAN_OUT + 1];
|
||||||
static xc_ptr p_multOut;
|
unsafe
|
||||||
|
{
|
||||||
|
unsigned int volatile * unsafe multOutPtr = multOut;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
|
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
|
||||||
unsigned int multIn[NUM_USB_CHAN_IN + 1];
|
unsigned int multIn[NUM_USB_CHAN_IN + 1];
|
||||||
static xc_ptr p_multIn;
|
unsafe
|
||||||
|
{
|
||||||
|
unsigned int volatile * unsafe multInPtr = multIn;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */
|
/* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */
|
||||||
@@ -162,7 +168,10 @@ static inline void SendSamples4(chanend c_mix_out)
|
|||||||
g_aud_from_host_rdptr+=4;
|
g_aud_from_host_rdptr+=4;
|
||||||
|
|
||||||
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multOutPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
h <<= 3;
|
h <<= 3;
|
||||||
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
|
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
|
||||||
@@ -189,7 +198,10 @@ static inline void SendSamples4(chanend c_mix_out)
|
|||||||
g_aud_from_host_rdptr+=4;
|
g_aud_from_host_rdptr+=4;
|
||||||
|
|
||||||
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multOutPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
h <<= 3;
|
h <<= 3;
|
||||||
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
|
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
|
||||||
@@ -267,7 +279,10 @@ __builtin_unreachable();
|
|||||||
sample <<= 16;
|
sample <<= 16;
|
||||||
|
|
||||||
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multOutPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
/* Note, in 2 byte subslot mode - ignore lower result of macs */
|
/* Note, in 2 byte subslot mode - ignore lower result of macs */
|
||||||
h <<= 3;
|
h <<= 3;
|
||||||
@@ -326,18 +341,19 @@ __builtin_unreachable();
|
|||||||
unpackState++;
|
unpackState++;
|
||||||
|
|
||||||
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER)
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multOutPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
h <<= 3;
|
h <<= 3;
|
||||||
outuint(c_mix_out, h);
|
outuint(c_mix_out, h);
|
||||||
#else
|
#else
|
||||||
outuint(c_mix_out, sample);
|
outuint(c_mix_out, sample);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
break;
|
break;
|
||||||
@@ -376,7 +392,10 @@ __builtin_unreachable();
|
|||||||
int mult;
|
int mult;
|
||||||
int h;
|
int h;
|
||||||
unsigned l;
|
unsigned l;
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multInPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
sample = h << 3;
|
sample = h << 3;
|
||||||
|
|
||||||
@@ -406,7 +425,10 @@ __builtin_unreachable();
|
|||||||
int mult;
|
int mult;
|
||||||
int h;
|
int h;
|
||||||
unsigned l;
|
unsigned l;
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multInPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
sample = h << 3;
|
sample = h << 3;
|
||||||
#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1)
|
#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1)
|
||||||
@@ -437,7 +459,10 @@ __builtin_unreachable();
|
|||||||
int mult;
|
int mult;
|
||||||
int h;
|
int h;
|
||||||
unsigned l;
|
unsigned l;
|
||||||
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
|
unsafe
|
||||||
|
{
|
||||||
|
mult = multInPtr[i];
|
||||||
|
}
|
||||||
{h, l} = macs(mult, sample, 0, 0);
|
{h, l} = macs(mult, sample, 0, 0);
|
||||||
sample = h << 3;
|
sample = h << 3;
|
||||||
#endif
|
#endif
|
||||||
@@ -676,13 +701,6 @@ void XUA_Buffer_Decouple(chanend c_mix_out
|
|||||||
|
|
||||||
int t = array_to_xc_ptr(outAudioBuff);
|
int t = array_to_xc_ptr(outAudioBuff);
|
||||||
|
|
||||||
#if (!OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1)
|
|
||||||
p_multOut = array_to_xc_ptr(multOut);
|
|
||||||
#endif
|
|
||||||
#if (!IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1)
|
|
||||||
p_multIn = array_to_xc_ptr(multIn);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
aud_from_host_fifo_start = t;
|
aud_from_host_fifo_start = t;
|
||||||
aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT;
|
aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT;
|
||||||
g_aud_from_host_wrptr = aud_from_host_fifo_start;
|
g_aud_from_host_wrptr = aud_from_host_fifo_start;
|
||||||
@@ -708,15 +726,15 @@ void XUA_Buffer_Decouple(chanend c_mix_out
|
|||||||
/* Init vol mult tables */
|
/* Init vol mult tables */
|
||||||
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
|
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
|
||||||
for (int i = 0; i < NUM_USB_CHAN_OUT + 1; i++)
|
for (int i = 0; i < NUM_USB_CHAN_OUT + 1; i++)
|
||||||
{
|
unsafe{
|
||||||
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i));
|
multOutPtr[i] = MAX_VOLUME_MULT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
|
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
|
||||||
for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++)
|
for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++)
|
||||||
{
|
unsafe{
|
||||||
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multIn),"r"(i));
|
multInPtr[i] = MAX_VOLUME_MULT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2022 XMOS LIMITED.
|
// Copyright 2011-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
#if XUA_USB_EN
|
#if XUA_USB_EN
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "xud.h"
|
#include "xud.h"
|
||||||
#include "testct_byref.h"
|
#include "testct_byref.h"
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
#include "xua_hid_report.h"
|
#include "xua_hid_report.h"
|
||||||
#include "user_hid.h"
|
#include "user_hid.h"
|
||||||
#include "xua_hid.h"
|
#include "xua_hid.h"
|
||||||
@@ -105,7 +105,11 @@ void XUA_Buffer(
|
|||||||
#endif
|
#endif
|
||||||
, chanend c_aud
|
, chanend c_aud
|
||||||
#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
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -134,14 +138,18 @@ void XUA_Buffer(
|
|||||||
c_clk_int,
|
c_clk_int,
|
||||||
#endif
|
#endif
|
||||||
c_sof, c_aud_ctl, p_off_mclk
|
c_sof, c_aud_ctl, p_off_mclk
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
, c_hid
|
, c_hid
|
||||||
#endif
|
#endif
|
||||||
#ifdef CHAN_BUFF_CTRL
|
#ifdef CHAN_BUFF_CTRL
|
||||||
, c_buff_ctrl
|
, c_buff_ctrl
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
, i_pll_ref
|
#if(XUA_USE_APP_PLL)
|
||||||
|
, c_swpll_update
|
||||||
|
#else
|
||||||
|
, i_pll_ref
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -190,8 +198,12 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#ifdef CHAN_BUFF_CTRL
|
#ifdef CHAN_BUFF_CTRL
|
||||||
, chanend c_buff_ctrl
|
, chanend c_buff_ctrl
|
||||||
#endif
|
#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
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -224,7 +236,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
XUD_ep ep_int = XUD_InitEp(c_ep_int);
|
XUD_ep ep_int = XUD_InitEp(c_ep_int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
XUD_ep ep_hid = XUD_InitEp(c_hid);
|
XUD_ep ep_hid = XUD_InitEp(c_hid);
|
||||||
#endif
|
#endif
|
||||||
unsigned u_tmp;
|
unsigned u_tmp;
|
||||||
@@ -247,7 +259,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#if (NUM_USB_CHAN_IN > 0)
|
#if (NUM_USB_CHAN_IN > 0)
|
||||||
unsigned bufferIn = 1;
|
unsigned bufferIn = 1;
|
||||||
#endif
|
#endif
|
||||||
unsigned sofCount = 0;
|
int sofCount = 0;
|
||||||
|
int pllUpdate = 0;
|
||||||
|
|
||||||
unsigned mod_from_last_time = 0;
|
unsigned mod_from_last_time = 0;
|
||||||
#ifdef FB_TOLERANCE_TEST
|
#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_interface_alt_setting = 0;
|
||||||
unsigned iap_ea_native_control_to_send = 0;
|
unsigned iap_ea_native_control_to_send = 0;
|
||||||
unsigned iap_ea_native_incoming = 0;
|
unsigned iap_ea_native_incoming = 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -332,7 +344,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
|
|
||||||
while (!hidIsReportDescriptorPrepared())
|
while (!hidIsReportDescriptorPrepared())
|
||||||
;
|
;
|
||||||
@@ -357,12 +369,16 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#ifndef LOCAL_CLOCK_MARGIN
|
#ifndef LOCAL_CLOCK_MARGIN
|
||||||
#define LOCAL_CLOCK_MARGIN (1000)
|
#define LOCAL_CLOCK_MARGIN (1000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (!XUA_USE_APP_PLL)
|
||||||
timer t_sofCheck;
|
timer t_sofCheck;
|
||||||
unsigned timeLastEdge;
|
unsigned timeLastEdge;
|
||||||
unsigned timeNextEdge;
|
unsigned timeNextEdge;
|
||||||
t_sofCheck :> timeLastEdge;
|
t_sofCheck :> timeLastEdge;
|
||||||
timeNextEdge + LOCAL_CLOCK_INCREMENT;
|
timeNextEdge + LOCAL_CLOCK_INCREMENT;
|
||||||
i_pll_ref.toggle();
|
i_pll_ref.toggle();
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
@@ -427,7 +443,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
/* Reset FB */
|
/* Reset FB */
|
||||||
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
||||||
* to stabilise (i.e. sofCount == 128 to fire) */
|
* to stabilise (i.e. sofCount == 128 to fire) */
|
||||||
sofCount = 1;
|
sofCount = 0;
|
||||||
|
pllUpdate = 0;
|
||||||
clocks = 0;
|
clocks = 0;
|
||||||
clockcounter = 0;
|
clockcounter = 0;
|
||||||
mod_from_last_time = 0;
|
mod_from_last_time = 0;
|
||||||
@@ -502,13 +519,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Pass on sample freq change to decouple() via global flag (saves a chanend) */
|
/* 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_GLOBAL0(g_freqChange, cmd); /* Set command */
|
||||||
SET_SHARED_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */
|
SET_SHARED_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && (!XUA_USE_APP_PLL)
|
||||||
case t_sofCheck when timerafter(timeNextEdge) :> void:
|
case t_sofCheck when timerafter(timeNextEdge) :> void:
|
||||||
i_pll_ref.toggle();
|
i_pll_ref.toggle();
|
||||||
timeLastEdge = timeNextEdge;
|
timeLastEdge = timeNextEdge;
|
||||||
@@ -528,7 +545,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
unsigned usbSpeed;
|
unsigned usbSpeed;
|
||||||
int framesPerSec;
|
int framesPerSec;
|
||||||
GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed);
|
GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed);
|
||||||
static int sofCount = 0;
|
|
||||||
|
|
||||||
framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000;
|
framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000;
|
||||||
|
|
||||||
@@ -539,12 +555,27 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
sofCount += 1000;
|
sofCount += 1000;
|
||||||
if (sofCount == framesPerSec)
|
if (sofCount == framesPerSec)
|
||||||
{
|
{
|
||||||
|
sofCount = 0;
|
||||||
|
pllUpdate++;
|
||||||
|
#if (!XUA_USE_APP_PLL)
|
||||||
/* Port is accessed via interface to allow flexibilty with location */
|
/* Port is accessed via interface to allow flexibilty with location */
|
||||||
i_pll_ref.toggle();
|
i_pll_ref.toggle();
|
||||||
t_sofCheck :> timeLastEdge;
|
t_sofCheck :> timeLastEdge;
|
||||||
sofCount = 0;
|
|
||||||
timeNextEdge = timeLastEdge + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
|
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)
|
#elif (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
||||||
|
|
||||||
/* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to
|
/* 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;
|
clockcounter = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
||||||
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
|
* 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.
|
* 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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if (XUA_HID_ENABLED)
|
||||||
/* HID Report Data */
|
/* HID Report Data */
|
||||||
case XUD_SetData_Select(c_hid, ep_hid, result):
|
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||||
hid_ready_flag = 0U;
|
hid_ready_flag = 0U;
|
||||||
unsigned reportTime;
|
unsigned reportTime;
|
||||||
@@ -911,7 +941,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MIDI
|
#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):
|
case midi_get_ack_or_data(c_midi, is_ack, datum):
|
||||||
if (is_ack)
|
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
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015-2021 XMOS LIMITED.
|
// Copyright 2015-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
#ifndef __DESCRIPTOR_DEFS_H__
|
#ifndef __DESCRIPTOR_DEFS_H__
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#define ENDPOINT_ADDRESS_OUT_MIDI (ENDPOINT_NUMBER_OUT_MIDI)
|
#define ENDPOINT_ADDRESS_OUT_MIDI (ENDPOINT_NUMBER_OUT_MIDI)
|
||||||
#define ENDPOINT_ADDRESS_OUT_IAP (ENDPOINT_NUMBER_OUT_IAP)
|
#define ENDPOINT_ADDRESS_OUT_IAP (ENDPOINT_NUMBER_OUT_IAP)
|
||||||
#define ENDPOINT_ADDRESS_OUT_IAP_EA_NATIVE_TRANS (ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS)
|
#define ENDPOINT_ADDRESS_OUT_IAP_EA_NATIVE_TRANS (ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS)
|
||||||
|
#define ENDPOINT_ADDRESS_OUT_HID (ENDPOINT_NUMBER_OUT_HID)
|
||||||
|
|
||||||
/* Interface numbers enum */
|
/* Interface numbers enum */
|
||||||
enum USBInterfaceNumber
|
enum USBInterfaceNumber
|
||||||
@@ -60,7 +61,7 @@ enum USBInterfaceNumber
|
|||||||
INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS,
|
INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
INTERFACE_NUMBER_HID,
|
INTERFACE_NUMBER_HID,
|
||||||
#endif
|
#endif
|
||||||
INTERFACE_COUNT /* End marker */
|
INTERFACE_COUNT /* End marker */
|
||||||
@@ -70,4 +71,8 @@ enum USBInterfaceNumber
|
|||||||
#define ENDPOINT_INT_INTERVAL_IN_HID 0x08
|
#define ENDPOINT_INT_INTERVAL_IN_HID 0x08
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENDPOINT_INT_INTERVAL_OUT_HID
|
||||||
|
#define ENDPOINT_INT_INTERVAL_OUT_HID 0x08
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include "xc_ptr.h"
|
#include "xc_ptr.h"
|
||||||
#include "xua_ep0_uacreqs.h"
|
#include "xua_ep0_uacreqs.h"
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
#include "xua_hid.h"
|
#include "xua_hid.h"
|
||||||
#include "xua_hid_report.h"
|
#include "xua_hid_report.h"
|
||||||
@@ -275,15 +275,10 @@ void InitLocalMixerState()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Configure default connections */
|
/* Configure default connections */
|
||||||
// TODO this should be a loop using defines.
|
for (int i = 0; i < MAX_MIX_COUNT; i++)
|
||||||
mixer1Weights[0] = 0;
|
{
|
||||||
mixer1Weights[9] = 0;
|
mixer1Weights[(i * MAX_MIX_COUNT) + i] = 0;
|
||||||
mixer1Weights[18] = 0;
|
}
|
||||||
mixer1Weights[27] = 0;
|
|
||||||
mixer1Weights[36] = 0;
|
|
||||||
mixer1Weights[45] = 0;
|
|
||||||
mixer1Weights[54] = 0;
|
|
||||||
mixer1Weights[63] = 0;
|
|
||||||
|
|
||||||
#if NUM_USB_CHAN_OUT > 0
|
#if NUM_USB_CHAN_OUT > 0
|
||||||
/* Setup up audio output channel mapping */
|
/* Setup up audio output channel mapping */
|
||||||
@@ -447,6 +442,15 @@ void XUA_Endpoint0_setBcdDevice(unsigned short bcd) {
|
|||||||
#endif // AUDIO_CLASS == 1}
|
#endif // AUDIO_CLASS == 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__static_hid_report_h_exists__)
|
||||||
|
#define hidReportDescriptorLength (sizeof(hidReportDescriptorPtr))
|
||||||
|
static unsigned char hidReportDescriptorPtr[] = {
|
||||||
|
#include "static_hid_report.h"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(chanend, c_audioControl),
|
void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(chanend, c_audioControl),
|
||||||
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
|
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
|
||||||
{
|
{
|
||||||
@@ -518,11 +522,13 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
|
|||||||
|
|
||||||
#endif // XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES
|
#endif // XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
|
#if XUA_HID_ENABLED
|
||||||
hidReportInit();
|
hidReportInit();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
|
|
||||||
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
||||||
|
#endif
|
||||||
unsigned char hidReportDescriptorLengthLo = hidReportDescriptorLength & 0xFF;
|
unsigned char hidReportDescriptorLengthLo = hidReportDescriptorLength & 0xFF;
|
||||||
unsigned char hidReportDescriptorLengthHi = (hidReportDescriptorLength & 0xFF00) >> 8;
|
unsigned char hidReportDescriptorLengthHi = (hidReportDescriptorLength & 0xFF00) >> 8;
|
||||||
|
|
||||||
@@ -533,6 +539,7 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
|
|||||||
|
|
||||||
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ] = hidReportDescriptorLengthLo;
|
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ] = hidReportDescriptorLengthLo;
|
||||||
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET + 1] = hidReportDescriptorLengthHi;
|
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET + 1] = hidReportDescriptorLengthHi;
|
||||||
|
|
||||||
#endif // 0 < HID_CONTROLS
|
#endif // 0 < HID_CONTROLS
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -736,7 +743,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
|
|||||||
|
|
||||||
switch(sp.bRequest)
|
switch(sp.bRequest)
|
||||||
{
|
{
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
case USB_GET_DESCRIPTOR:
|
case USB_GET_DESCRIPTOR:
|
||||||
|
|
||||||
/* Check what inteface request is for */
|
/* Check what inteface request is for */
|
||||||
@@ -751,15 +758,17 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
|
|||||||
{
|
{
|
||||||
/* Return HID Descriptor */
|
/* Return HID Descriptor */
|
||||||
result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor,
|
result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor,
|
||||||
sizeof(hidDescriptor), sp.wLength);
|
hidDescriptor[0], sp.wLength);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HID_REPORT:
|
case HID_REPORT:
|
||||||
{
|
{
|
||||||
/* Return HID report descriptor */
|
/* Return HID report descriptor */
|
||||||
|
#if XUA_HID_ENABLED
|
||||||
unsigned char* hidReportDescriptorPtr;
|
unsigned char* hidReportDescriptorPtr;
|
||||||
hidReportDescriptorPtr = hidGetReportDescriptor();
|
hidReportDescriptorPtr = hidGetReportDescriptor();
|
||||||
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
||||||
|
#endif
|
||||||
result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptorPtr,
|
result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptorPtr,
|
||||||
hidReportDescriptorLength, sp.wLength);
|
hidReportDescriptorLength, sp.wLength);
|
||||||
}
|
}
|
||||||
@@ -863,7 +872,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
if (interfaceNum == INTERFACE_NUMBER_HID)
|
if (interfaceNum == INTERFACE_NUMBER_HID)
|
||||||
{
|
{
|
||||||
result = HidInterfaceClassRequests(ep0_out, ep0_in, &sp);
|
result = HidInterfaceClassRequests(ep0_out, ep0_in, &sp);
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ USB_Descriptor_Device_t devDesc_Audio2 =
|
|||||||
.iManufacturer = offsetof(StringDescTable_t, vendorStr)/sizeof(char *),
|
.iManufacturer = offsetof(StringDescTable_t, vendorStr)/sizeof(char *),
|
||||||
.iProduct = offsetof(StringDescTable_t, productStr_Audio2)/sizeof(char *),
|
.iProduct = offsetof(StringDescTable_t, productStr_Audio2)/sizeof(char *),
|
||||||
.iSerialNumber = offsetof(StringDescTable_t, serialStr)/sizeof(char *),
|
.iSerialNumber = offsetof(StringDescTable_t, serialStr)/sizeof(char *),
|
||||||
.bNumConfigurations = 0x02 /* Set to 2 such that windows does not load composite driver */
|
.bNumConfigurations = 0x01
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device Descriptor for Null Device */
|
/* Device Descriptor for Null Device */
|
||||||
@@ -787,10 +787,13 @@ typedef struct
|
|||||||
#endif
|
#endif
|
||||||
#endif // IAP
|
#endif // IAP
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
USB_Descriptor_Interface_t HID_Interface;
|
USB_Descriptor_Interface_t HID_Interface;
|
||||||
USB_HID_Descriptor_t HID_Descriptor;
|
USB_HID_Descriptor_t HID_Descriptor;
|
||||||
USB_Descriptor_Endpoint_t HID_In_Endpoint;
|
USB_Descriptor_Endpoint_t HID_In_Endpoint;
|
||||||
|
#if HID_OUT_REQUIRED
|
||||||
|
USB_Descriptor_Endpoint_t HID_Out_Endpoint;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}__attribute__((packed)) USB_Config_Descriptor_Audio2_t;
|
}__attribute__((packed)) USB_Config_Descriptor_Audio2_t;
|
||||||
@@ -2208,14 +2211,14 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
|||||||
#endif
|
#endif
|
||||||
#endif /* IAP */
|
#endif /* IAP */
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
#include "xua_hid_descriptors.h"
|
#include "xua_hid_descriptors.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif /* (AUDIO_CLASS == 2) */
|
#endif /* (AUDIO_CLASS == 2) */
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
#if (AUDIO_CLASS ==1 )
|
#if (AUDIO_CLASS ==1 )
|
||||||
unsigned char hidDescriptor[] =
|
unsigned char hidDescriptor[] =
|
||||||
{
|
{
|
||||||
@@ -2330,14 +2333,14 @@ const unsigned num_freqs_a1 = MAX(3, (0
|
|||||||
#define DFU_INTERFACES_A1 0
|
#define DFU_INTERFACES_A1 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
/*
|
/*
|
||||||
* The value of HID_INTERFACE_BYTES must match the length of the descriptors defined in
|
* The value of HID_INTERFACE_BYTES must match the length of the descriptors defined in
|
||||||
* - xua_hid_descriptor_contents.h
|
* - xua_hid_descriptor_contents.h
|
||||||
* - xua_hid_endpoint_descriptor_contents.h and
|
* - xua_hid_endpoint_descriptor_contents.h and
|
||||||
* - xua_hid_interface_descriptor_contents.h
|
* - xua_hid_interface_descriptor_contents.h
|
||||||
*/
|
*/
|
||||||
#define HID_INTERFACE_BYTES ( 9 + 9 + 7 )
|
#define HID_INTERFACE_BYTES ( 9 + 9 + (7 * (1 + HID_OUT_REQUIRED))) // always IN
|
||||||
#define HID_INTERFACES_A1 1
|
#define HID_INTERFACES_A1 1
|
||||||
#else
|
#else
|
||||||
#define HID_INTERFACE_BYTES 0
|
#define HID_INTERFACE_BYTES 0
|
||||||
@@ -2379,7 +2382,7 @@ const unsigned num_freqs_a1 = MAX(3, (0
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
#define USB_HID_DESCRIPTOR_OFFSET (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + INTERFACE_DESCRIPTOR_BYTES)
|
#define USB_HID_DESCRIPTOR_OFFSET (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + INTERFACE_DESCRIPTOR_BYTES)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2893,7 +2896,7 @@ unsigned char cfgDesc_Audio1[] =
|
|||||||
offsetof(StringDescTable_t, ctrlStr)/sizeof(char *), /* 8 iInterface */
|
offsetof(StringDescTable_t, ctrlStr)/sizeof(char *), /* 8 iInterface */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
#include "xua_hid_descriptors.h"
|
#include "xua_hid_descriptors.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -14,16 +14,20 @@
|
|||||||
#include "usbaudio10.h"
|
#include "usbaudio10.h"
|
||||||
#include "dbcalc.h"
|
#include "dbcalc.h"
|
||||||
#include "xua_commands.h"
|
#include "xua_commands.h"
|
||||||
#include "xc_ptr.h"
|
|
||||||
|
|
||||||
#define CS_XU_MIXSEL (0x06)
|
#define CS_XU_MIXSEL (0x06)
|
||||||
|
|
||||||
|
/* From decouple.xc */
|
||||||
|
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
|
||||||
extern unsigned int multOut[NUM_USB_CHAN_OUT + 1];
|
extern unsigned int multOut[NUM_USB_CHAN_OUT + 1];
|
||||||
|
#endif
|
||||||
|
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
|
||||||
extern unsigned int multIn[NUM_USB_CHAN_IN + 1];
|
extern unsigned int multIn[NUM_USB_CHAN_IN + 1];
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int interfaceAlt[];
|
extern int interfaceAlt[];
|
||||||
|
|
||||||
/* Global volume and mute tables */
|
/* Global volume and mute tables - from xua_endpoint0.c */
|
||||||
extern int volsOut[];
|
extern int volsOut[];
|
||||||
extern unsigned int mutesOut[];
|
extern unsigned int mutesOut[];
|
||||||
|
|
||||||
@@ -101,20 +105,6 @@ void FeedbackStabilityDelay()
|
|||||||
t when timerafter(time + delay):> void;
|
t when timerafter(time + delay):> void;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Original feedback implementation */
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
unsigned * unsafe curSamFreqMultiplier = &g_curSamFreqMultiplier;
|
|
||||||
|
|
||||||
static void setG_curSamFreqMultiplier(unsigned x)
|
|
||||||
{
|
|
||||||
// asm(" stw %0, dp[g_curSamFreqMultiplier]" :: "r"(x));
|
|
||||||
*curSamFreqMultiplier = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1)
|
#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1)
|
||||||
static unsigned longMul(unsigned a, unsigned b, int prec)
|
static unsigned longMul(unsigned a, unsigned b, int prec)
|
||||||
{
|
{
|
||||||
@@ -131,13 +121,6 @@ static unsigned longMul(unsigned a, unsigned b, int prec)
|
|||||||
/* Update master volume i.e. i.e update weights for all channels */
|
/* Update master volume i.e. i.e update weights for all channels */
|
||||||
static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
||||||
{
|
{
|
||||||
int x;
|
|
||||||
#if (OUT_VOLUME_IN_MIXER == 0)
|
|
||||||
xc_ptr p_multOut = array_to_xc_ptr(multOut);
|
|
||||||
#endif
|
|
||||||
#if (IN_VOLUME_IN_MIXER == 0)
|
|
||||||
xc_ptr p_multIn = array_to_xc_ptr(multIn);
|
|
||||||
#endif
|
|
||||||
switch(unitID)
|
switch(unitID)
|
||||||
{
|
{
|
||||||
case FU_USBOUT:
|
case FU_USBOUT:
|
||||||
@@ -150,7 +133,7 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
|||||||
/* 0x8000 is a special value representing -inf (i.e. mute) */
|
/* 0x8000 is a special value representing -inf (i.e. mute) */
|
||||||
unsigned vol = volsOut[i] == 0x8000 ? 0 : db_to_mult(volsOut[i], 8, 29);
|
unsigned vol = volsOut[i] == 0x8000 ? 0 : db_to_mult(volsOut[i], 8, 29);
|
||||||
|
|
||||||
x = longMul(master_vol, vol, 29) * !mutesOut[0] * !mutesOut[i];
|
int x = longMul(master_vol, vol, 29) * !mutesOut[0] * !mutesOut[i];
|
||||||
|
|
||||||
#if (OUT_VOLUME_IN_MIXER)
|
#if (OUT_VOLUME_IN_MIXER)
|
||||||
if (!isnull(c_mix_ctl))
|
if (!isnull(c_mix_ctl))
|
||||||
@@ -162,8 +145,12 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
|||||||
outuint(c_mix_ctl, x);
|
outuint(c_mix_ctl, x);
|
||||||
outct(c_mix_ctl, XS1_CT_END);
|
outct(c_mix_ctl, XS1_CT_END);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
asm("stw %0, %1[%2]"::"r"(x),"r"(p_multOut),"r"(i-1));
|
unsafe
|
||||||
|
{
|
||||||
|
unsigned int * unsafe multOutPtr = multOut;
|
||||||
|
multOutPtr[i-1] = x;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +165,7 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
|||||||
/* 0x8000 is a special value representing -inf (i.e. mute) */
|
/* 0x8000 is a special value representing -inf (i.e. mute) */
|
||||||
unsigned vol = volsIn[i] == 0x8000 ? 0 : db_to_mult(volsIn[i], 8, 29);
|
unsigned vol = volsIn[i] == 0x8000 ? 0 : db_to_mult(volsIn[i], 8, 29);
|
||||||
|
|
||||||
x = longMul(master_vol, vol, 29) * !mutesIn[0] * !mutesIn[i];
|
int x = longMul(master_vol, vol, 29) * !mutesIn[0] * !mutesIn[i];
|
||||||
|
|
||||||
#if (IN_VOLUME_IN_MIXER)
|
#if (IN_VOLUME_IN_MIXER)
|
||||||
if (!isnull(c_mix_ctl))
|
if (!isnull(c_mix_ctl))
|
||||||
@@ -191,7 +178,11 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
|||||||
outct(c_mix_ctl, XS1_CT_END);
|
outct(c_mix_ctl, XS1_CT_END);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
asm("stw %0, %1[%2]"::"r"(x),"r"(p_multIn),"r"(i-1));
|
unsafe
|
||||||
|
{
|
||||||
|
unsigned int * unsafe multInPtr = multIn;
|
||||||
|
multInPtr[i-1] = x;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,12 +196,6 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
|
|||||||
static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
|
static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
#if (OUT_VOLUME_IN_MIXER == 0)
|
|
||||||
xc_ptr p_multOut = array_to_xc_ptr(multOut);
|
|
||||||
#endif
|
|
||||||
#if (IN_VOLUME_IN_MIXER == 0)
|
|
||||||
xc_ptr p_multIn = array_to_xc_ptr(multIn);
|
|
||||||
#endif
|
|
||||||
/* Check for master volume update */
|
/* Check for master volume update */
|
||||||
if (channel == 0)
|
if (channel == 0)
|
||||||
{
|
{
|
||||||
@@ -240,7 +225,11 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
|
|||||||
outct(c_mix_ctl, XS1_CT_END);
|
outct(c_mix_ctl, XS1_CT_END);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
asm("stw %0, %1[%2]"::"r"(x),"r"(p_multOut),"r"(channel-1));
|
unsafe
|
||||||
|
{
|
||||||
|
unsigned int * unsafe multOutPtr = multOut;
|
||||||
|
multOutPtr[channel-1] = x;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -264,7 +253,11 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
|
|||||||
outct(c_mix_ctl, XS1_CT_END);
|
outct(c_mix_ctl, XS1_CT_END);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
asm("stw %0, %1[%2]"::"r"(x),"r"(p_multIn),"r"(channel-1));
|
unsafe
|
||||||
|
{
|
||||||
|
unsigned int * unsafe multInPtr = multIn;
|
||||||
|
multInPtr[channel-1] = x;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (XUA_SPDIF_RX_EN)
|
#if (XUA_SPDIF_RX_EN)
|
||||||
#include "SpdifReceive.h"
|
#include "spdif.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (XUA_ADAT_RX_EN)
|
#if (XUA_ADAT_RX_EN)
|
||||||
@@ -142,10 +142,10 @@ on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (XUA_SPDIF_RX_EN)
|
#if (XUA_SPDIF_RX_EN)
|
||||||
on tile[XUD_TILE] : buffered in port:4 p_spdif_rx = PORT_SPDIF_IN;
|
on tile[XUD_TILE] : in port p_spdif_rx = PORT_SPDIF_IN;
|
||||||
#endif
|
#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 */
|
/* Reference to external clock multiplier */
|
||||||
on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF;
|
on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF;
|
||||||
#endif
|
#endif
|
||||||
@@ -213,6 +213,9 @@ XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_EN
|
|||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
XUD_EPTYPE_BUL, /* MIDI */
|
XUD_EPTYPE_BUL, /* MIDI */
|
||||||
#endif
|
#endif
|
||||||
|
#if HID_OUT_REQUIRED
|
||||||
|
XUD_EPTYPE_INT,
|
||||||
|
#endif
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
XUD_EPTYPE_BUL, /* iAP */
|
XUD_EPTYPE_BUL, /* iAP */
|
||||||
#ifdef IAP_EA_NATIVE_TRANS
|
#ifdef IAP_EA_NATIVE_TRANS
|
||||||
@@ -228,12 +231,12 @@ XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENAB
|
|||||||
XUD_EPTYPE_ISO, /* Async feedback endpoint */
|
XUD_EPTYPE_ISO, /* Async feedback endpoint */
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
XUD_EPTYPE_BUL,
|
XUD_EPTYPE_INT,
|
||||||
#endif
|
#endif
|
||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
XUD_EPTYPE_BUL,
|
XUD_EPTYPE_BUL,
|
||||||
#endif
|
#endif
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_OR_STATIC_HID_ENABLED
|
||||||
XUD_EPTYPE_INT,
|
XUD_EPTYPE_INT,
|
||||||
#endif
|
#endif
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
@@ -267,115 +270,6 @@ void xscope_user_init()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XUA_USB_EN
|
|
||||||
/* Core USB Audio functions - must be called on the Tile connected to the USB Phy */
|
|
||||||
void usb_audio_core(chanend c_mix_out
|
|
||||||
#ifdef MIDI
|
|
||||||
, chanend c_midi
|
|
||||||
#endif
|
|
||||||
#if (MIXER)
|
|
||||||
, chanend c_mix_ctl
|
|
||||||
#endif
|
|
||||||
, chanend ?c_clk_int
|
|
||||||
, chanend ?c_clk_ctl
|
|
||||||
, client interface i_dfu ?dfuInterface
|
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
|
||||||
, client interface pll_ref_if i_pll_ref
|
|
||||||
#endif
|
|
||||||
VENDOR_REQUESTS_PARAMS_DEC_
|
|
||||||
)
|
|
||||||
{
|
|
||||||
chan c_sof;
|
|
||||||
chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */
|
|
||||||
chan c_xud_in[ENDPOINT_COUNT_IN];
|
|
||||||
chan c_aud_ctl;
|
|
||||||
|
|
||||||
#if (!MIXER)
|
|
||||||
#define c_mix_ctl null
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IAP_EA_NATIVE_TRANS
|
|
||||||
chan c_EANativeTransport_ctrl;
|
|
||||||
#else
|
|
||||||
#define c_EANativeTransport_ctrl null
|
|
||||||
#endif
|
|
||||||
|
|
||||||
par
|
|
||||||
{
|
|
||||||
{
|
|
||||||
#ifdef XUD_PRIORITY_HIGH
|
|
||||||
set_core_high_priority_on();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Run UAC2.0 at high-speed, UAC1.0 at full-speed */
|
|
||||||
unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS;
|
|
||||||
|
|
||||||
unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS;
|
|
||||||
|
|
||||||
/* USB interface core */
|
|
||||||
XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN,
|
|
||||||
c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
unsigned x;
|
|
||||||
thread_speed();
|
|
||||||
|
|
||||||
/* Attach mclk count port to mclk clock-block (for feedback) */
|
|
||||||
//set_port_clock(p_for_mclk_count, clk_audio_mclk);
|
|
||||||
#if(AUDIO_IO_TILE != XUD_TILE)
|
|
||||||
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb);
|
|
||||||
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb);
|
|
||||||
start_clock(clk_audio_mclk_usb);
|
|
||||||
#else
|
|
||||||
/* Clock port from same clock-block as I2S */
|
|
||||||
/* TODO remove asm() */
|
|
||||||
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
|
||||||
asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));
|
|
||||||
#endif
|
|
||||||
/* Endpoint & audio buffering cores */
|
|
||||||
XUA_Buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO],/* Audio Out*/
|
|
||||||
#if (NUM_USB_CHAN_IN > 0)
|
|
||||||
|
|
||||||
c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */
|
|
||||||
#endif
|
|
||||||
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
|
|
||||||
c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */
|
|
||||||
#endif
|
|
||||||
#ifdef MIDI
|
|
||||||
c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2
|
|
||||||
c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4
|
|
||||||
c_midi,
|
|
||||||
#endif
|
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
|
||||||
/* Audio Interrupt - only used for interrupts on external clock change */
|
|
||||||
c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT],
|
|
||||||
c_clk_int,
|
|
||||||
#endif
|
|
||||||
c_sof, c_aud_ctl, p_for_mclk_count
|
|
||||||
#if (HID_CONTROLS)
|
|
||||||
, c_xud_in[ENDPOINT_NUMBER_IN_HID]
|
|
||||||
#endif
|
|
||||||
, c_mix_out
|
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
|
||||||
, i_pll_ref
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
//:
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Endpoint 0 Core */
|
|
||||||
{
|
|
||||||
thread_speed();
|
|
||||||
XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* XUA_USB_EN */
|
|
||||||
|
|
||||||
|
|
||||||
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||||
void SpdifTxWrapper(chanend c_spdif_tx)
|
void SpdifTxWrapper(chanend c_spdif_tx)
|
||||||
{
|
{
|
||||||
@@ -420,6 +314,9 @@ void usb_audio_io(chanend ?c_aud_in,
|
|||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
, client interface pll_ref_if i_pll_ref
|
, client interface pll_ref_if i_pll_ref
|
||||||
#endif
|
#endif
|
||||||
|
#if (XUA_USE_APP_PLL)
|
||||||
|
, client interface SoftPll_if i_softPll
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if (MIXER)
|
#if (MIXER)
|
||||||
@@ -470,6 +367,9 @@ void usb_audio_io(chanend ?c_aud_in,
|
|||||||
#define AUDIO_CHANNEL c_aud_in
|
#define AUDIO_CHANNEL c_aud_in
|
||||||
#endif
|
#endif
|
||||||
XUA_AudioHub(AUDIO_CHANNEL, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc
|
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)
|
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||||
, c_spdif_tx
|
, c_spdif_tx
|
||||||
#endif
|
#endif
|
||||||
@@ -573,17 +473,36 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
#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;
|
interface pll_ref_if i_pll_ref;
|
||||||
#endif
|
#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];
|
||||||
|
chan c_aud_ctl;
|
||||||
|
|
||||||
|
#if (!MIXER)
|
||||||
|
#define c_mix_ctl null
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAP_EA_NATIVE_TRANS
|
||||||
|
chan c_EANativeTransport_ctrl;
|
||||||
|
#else
|
||||||
|
#define c_EANativeTransport_ctrl null
|
||||||
|
#endif
|
||||||
|
|
||||||
USER_MAIN_DECLARATIONS
|
USER_MAIN_DECLARATIONS
|
||||||
|
|
||||||
par
|
par
|
||||||
{
|
{
|
||||||
USER_MAIN_CORES
|
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);
|
on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref);
|
||||||
#endif
|
#endif
|
||||||
on tile[XUD_TILE]:
|
on tile[XUD_TILE]:
|
||||||
@@ -597,30 +516,91 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if XUA_USB_EN
|
#if XUA_USB_EN
|
||||||
/* Core USB audio task, buffering, USB etc */
|
|
||||||
usb_audio_core(c_mix_out
|
|
||||||
#ifdef MIDI
|
|
||||||
, c_midi
|
|
||||||
#endif
|
|
||||||
#ifdef IAP
|
|
||||||
, c_iap
|
|
||||||
#ifdef IAP_EA_NATIVE_TRANS
|
|
||||||
, c_ea_data
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if (MIXER)
|
|
||||||
, c_mix_ctl
|
|
||||||
#endif
|
|
||||||
, c_clk_int, c_clk_ctl, dfuInterface
|
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
|
||||||
, i_pll_ref
|
|
||||||
#endif
|
|
||||||
VENDOR_REQUESTS_PARAMS_
|
|
||||||
|
|
||||||
);
|
/* Core USB task, buffering, USB etc */
|
||||||
|
{
|
||||||
|
#ifdef XUD_PRIORITY_HIGH
|
||||||
|
set_core_high_priority_on();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Run UAC2.0 at high-speed, UAC1.0 at full-speed */
|
||||||
|
unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS;
|
||||||
|
|
||||||
|
unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS;
|
||||||
|
|
||||||
|
/* USB interface core */
|
||||||
|
XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN,
|
||||||
|
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;
|
||||||
|
thread_speed();
|
||||||
|
|
||||||
|
/* Attach mclk count port to mclk clock-block (for feedback) */
|
||||||
|
//set_port_clock(p_for_mclk_count, clk_audio_mclk);
|
||||||
|
#if(AUDIO_IO_TILE != XUD_TILE)
|
||||||
|
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb);
|
||||||
|
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb);
|
||||||
|
start_clock(clk_audio_mclk_usb);
|
||||||
|
#else
|
||||||
|
/* Clock port from same clock-block as I2S */
|
||||||
|
/* TODO remove asm() */
|
||||||
|
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
||||||
|
asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));
|
||||||
|
#endif
|
||||||
|
/* Endpoint & audio buffering cores */
|
||||||
|
XUA_Buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO],/* Audio Out*/
|
||||||
|
#if (NUM_USB_CHAN_IN > 0)
|
||||||
|
|
||||||
|
c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */
|
||||||
|
#endif
|
||||||
|
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
|
||||||
|
c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */
|
||||||
|
#endif
|
||||||
|
#ifdef MIDI
|
||||||
|
c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2
|
||||||
|
c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4
|
||||||
|
c_midi,
|
||||||
|
#endif
|
||||||
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
|
/* Audio Interrupt - only used for interrupts on external clock change */
|
||||||
|
c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT],
|
||||||
|
c_clk_int,
|
||||||
|
#endif
|
||||||
|
c_sof, c_aud_ctl, p_for_mclk_count
|
||||||
|
#if (XUA_HID_ENABLED)
|
||||||
|
, c_xud_in[ENDPOINT_NUMBER_IN_HID]
|
||||||
|
#endif
|
||||||
|
, c_mix_out
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
#if (!XUA_USE_APP_PLL)
|
||||||
|
, i_pll_ref
|
||||||
|
#else
|
||||||
|
, c_swpll_update
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
//:
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Endpoint 0 Core */
|
||||||
|
{
|
||||||
|
thread_speed();
|
||||||
|
XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* XUA_USB_EN */
|
#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]:
|
on tile[AUDIO_IO_TILE]:
|
||||||
{
|
{
|
||||||
/* Audio I/O task, includes mixing etc */
|
/* Audio I/O task, includes mixing etc */
|
||||||
@@ -643,6 +623,9 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
, i_pll_ref
|
, i_pll_ref
|
||||||
|
#endif
|
||||||
|
#if (XUA_USE_APP_PLL)
|
||||||
|
, i_softPll
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -685,7 +668,7 @@ int main()
|
|||||||
on tile[XUD_TILE]:
|
on tile[XUD_TILE]:
|
||||||
{
|
{
|
||||||
thread_speed();
|
thread_speed();
|
||||||
SpdifReceive(p_spdif_rx, c_spdif_rx, 1, clk_spd_rx);
|
spdif_rx(c_spdif_rx,p_spdif_rx,clk_spd_rx,192000);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
static unsigned int multOut_array[NUM_USB_CHAN_OUT + 1];
|
static unsigned int multOut_array[NUM_USB_CHAN_OUT + 1];
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
int volatile * unsafe multOut = multOut_array;
|
unsigned int volatile * unsafe multOut = multOut_array;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ unsafe
|
|||||||
static unsigned int multIn_array[NUM_USB_CHAN_IN + 1];
|
static unsigned int multIn_array[NUM_USB_CHAN_IN + 1];
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
int volatile * unsafe multIn = multIn_array;
|
unsigned int volatile * unsafe multIn = multIn_array;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -827,14 +827,14 @@ void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl)
|
|||||||
#if (OUT_VOLUME_IN_MIXER)
|
#if (OUT_VOLUME_IN_MIXER)
|
||||||
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
|
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
|
||||||
unsafe{
|
unsafe{
|
||||||
multOut[i] = MAX_VOL;
|
multOut[i] = MAX_VOLUME_MULT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (IN_VOLUME_IN_MIXER)
|
#if (IN_VOLUME_IN_MIXER)
|
||||||
for (int i=0; i<NUM_USB_CHAN_IN; i++)
|
for (int i=0; i<NUM_USB_CHAN_IN; i++)
|
||||||
unsafe{
|
unsafe{
|
||||||
multIn[i] = MAX_VOL;
|
multIn[i] = MAX_VOLUME_MULT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2013-2022 XMOS LIMITED.
|
// Copyright 2013-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
@@ -9,17 +9,17 @@
|
|||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
|
|
||||||
/* Note since DSD ports could be reused for I2S ports we do all the setup manually in C */
|
/* Note since DSD ports could be reused for I2S ports we do all the setup manually in C */
|
||||||
#if DSD_CHANS_DAC > 0
|
#if (DSD_CHANS_DAC > 0)
|
||||||
port p_dsd_dac[DSD_CHANS_DAC] = {
|
port p_dsd_dac[DSD_CHANS_DAC] = {
|
||||||
PORT_DSD_DAC0,
|
PORT_DSD_DAC0,
|
||||||
#endif
|
#endif
|
||||||
#if DSD_CHANS_DAC > 1
|
#if (DSD_CHANS_DAC > 1)
|
||||||
PORT_DSD_DAC1,
|
PORT_DSD_DAC1,
|
||||||
#endif
|
#endif
|
||||||
#if DSD_CHANS_DAC > 2
|
#if (DSD_CHANS_DAC > 2)
|
||||||
#error > 2 DSD chans currently not supported
|
#error > 2 DSD chans currently not supported
|
||||||
#endif
|
#endif
|
||||||
#if DSD_CHANS_DAC > 0
|
#if (DSD_CHANS_DAC > 0)
|
||||||
};
|
};
|
||||||
port p_dsd_clk = PORT_DSD_CLK;
|
port p_dsd_clk = PORT_DSD_CLK;
|
||||||
#endif
|
#endif
|
||||||
@@ -45,7 +45,7 @@ void ConfigAudioPortsWrapper(
|
|||||||
port p_lrclk,
|
port p_lrclk,
|
||||||
port p_bclk,
|
port p_bclk,
|
||||||
#endif
|
#endif
|
||||||
port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq, unsigned int dsdMode)
|
port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq)
|
||||||
{
|
{
|
||||||
ConfigAudioPorts(
|
ConfigAudioPorts(
|
||||||
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2022 XMOS LIMITED.
|
// Copyright 2011-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#ifndef _AUDIOPORTS_H_
|
#ifndef _AUDIOPORTS_H_
|
||||||
#define _AUDIOPORTS_H_
|
#define _AUDIOPORTS_H_
|
||||||
@@ -79,7 +79,7 @@ void ConfigAudioPortsWrapper(
|
|||||||
buffered in port:32 p_bclk,
|
buffered in port:32 p_bclk,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
in port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq, unsigned int dsdMode);
|
in port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void ConfigAudioPortsWrapper(
|
void ConfigAudioPortsWrapper(
|
||||||
@@ -95,7 +95,7 @@ void ConfigAudioPortsWrapper(
|
|||||||
port p_lrclk,
|
port p_lrclk,
|
||||||
port p_bclk,
|
port p_bclk,
|
||||||
#endif
|
#endif
|
||||||
port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq, unsigned int dsdMode);
|
port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __XC__*/
|
#endif /* __XC__*/
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2022 XMOS LIMITED.
|
// Copyright 2011-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
@@ -6,9 +6,7 @@
|
|||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
#include "audioports.h"
|
#include "audioports.h"
|
||||||
|
|
||||||
//extern in port p_mclk_in;
|
|
||||||
extern clock clk_audio_mclk;
|
extern clock clk_audio_mclk;
|
||||||
//extern clock clk_audio_bclk;
|
|
||||||
|
|
||||||
void ConfigAudioPorts(
|
void ConfigAudioPorts(
|
||||||
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
||||||
@@ -58,7 +56,7 @@ void ConfigAudioPorts(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (I2S_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0)|| (DSD_CHANS_DAC != 0)
|
||||||
for(int i = 0; i < numPortsDac; i++)
|
for(int i = 0; i < numPortsDac; i++)
|
||||||
{
|
{
|
||||||
clearbuf(p_i2s_dac[i]);
|
clearbuf(p_i2s_dac[i]);
|
||||||
@@ -82,7 +80,7 @@ void ConfigAudioPorts(
|
|||||||
/* Some adustments for timing. Sample ADC lines on negative edge and add some delay */
|
/* Some adustments for timing. Sample ADC lines on negative edge and add some delay */
|
||||||
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
for(int i = 0; i < numPortsAdc; i++)
|
||||||
{
|
{
|
||||||
set_port_sample_delay(p_i2s_adc[i]);
|
set_port_sample_delay(p_i2s_adc[i]);
|
||||||
set_pad_delay(p_i2s_adc[i], 4);
|
set_pad_delay(p_i2s_adc[i], 4);
|
||||||
@@ -91,7 +89,6 @@ void ConfigAudioPorts(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif (CODEC_MASTER)
|
#elif (CODEC_MASTER)
|
||||||
|
|
||||||
/* Stop bit and master clock blocks */
|
/* Stop bit and master clock blocks */
|
||||||
stop_clock(clk_audio_bclk);
|
stop_clock(clk_audio_bclk);
|
||||||
|
|
||||||
@@ -103,7 +100,7 @@ void ConfigAudioPorts(
|
|||||||
/* Do some clocking shifting to get data in the valid window */
|
/* Do some clocking shifting to get data in the valid window */
|
||||||
/* E.g. Only shift when running at 88.2+ kHz TDM slave */
|
/* E.g. Only shift when running at 88.2+ kHz TDM slave */
|
||||||
int bClkDelay_fall = 0;
|
int bClkDelay_fall = 0;
|
||||||
if(curSamFreq * I2S_CHANS_PER_FRAME * 32 >= 20000000)
|
if(curSamFreq * I2S_CHANS_PER_FRAME * XUA_I2S_N_BITS >= 20000000)
|
||||||
{
|
{
|
||||||
/* 18 * 2ns = 36ns. This results in a -4ns (36 - 40) shift at 96KHz and -8ns (36 - 44) at 88.4KHz */
|
/* 18 * 2ns = 36ns. This results in a -4ns (36 - 40) shift at 96KHz and -8ns (36 - 44) at 88.4KHz */
|
||||||
bClkDelay_fall = 18;
|
bClkDelay_fall = 18;
|
||||||
@@ -112,9 +109,9 @@ void ConfigAudioPorts(
|
|||||||
set_clock_fall_delay(clk_audio_bclk, bClkDelay_fall);
|
set_clock_fall_delay(clk_audio_bclk, bClkDelay_fall);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (I2S_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
|
||||||
/* Clock I2S output data ports from b-clock clock block */
|
/* Clock I2S/DSD output data ports from b-clock clock block */
|
||||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
for(int i = 0; i < numPortsDac; i++)
|
||||||
{
|
{
|
||||||
configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
|
configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
|
||||||
}
|
}
|
||||||
@@ -122,7 +119,7 @@ void ConfigAudioPorts(
|
|||||||
|
|
||||||
#if (I2S_CHANS_ADC != 0)
|
#if (I2S_CHANS_ADC != 0)
|
||||||
/* Clock I2S input data ports from clock block */
|
/* Clock I2S input data ports from clock block */
|
||||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
for(int i = 0; i < numPortsAdc; i++)
|
||||||
{
|
{
|
||||||
configure_in_port_no_ready(p_i2s_adc[i], clk_audio_bclk);
|
configure_in_port_no_ready(p_i2s_adc[i], clk_audio_bclk);
|
||||||
}
|
}
|
||||||
|
|||||||
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.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#ifndef _AUDIOSTREAM_H_
|
#ifndef _AUDIOSTREAM_H_
|
||||||
#define _AUDIOSTREAM_H_
|
#define _AUDIOSTREAM_H_
|
||||||
|
|
||||||
/* Functions that handle functions that must occur on stream start/stop e.g. DAC mute/un-mute
|
/* 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.
|
||||||
* THESE NEED IMPLEMENTING FOR 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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
void UserAudioOutputStreamStop(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
// Copyright 2013-2021 XMOS LIMITED.
|
// Copyright 2013-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Human Interface Device (HID) API
|
* @brief Human Interface Device (HID) API
|
||||||
*
|
*
|
||||||
* This file defines the Application Programming Interface (API) used to record HID
|
* 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.
|
* The using application has the responsibility to fulfill this API.
|
||||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __USER_HID_H__
|
#ifndef _USER_HID_H_
|
||||||
#define __USER_HID_H__
|
#define _USER_HID_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -34,22 +34,16 @@ typedef struct hidEvent_t {
|
|||||||
#define HID_MAX_DATA_BYTES ( 4 )
|
#define HID_MAX_DATA_BYTES ( 4 )
|
||||||
#define HID_EVENT_INVALID_ID ( 0x100 )
|
#define HID_EVENT_INVALID_ID ( 0x100 )
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the data for the next HID Report
|
* \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)
|
* \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
|
* 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
|
* \param[out] hidData The HID data
|
||||||
* If using Report IDs, this function places the Report ID in
|
* If using Report IDs, this function places the Report ID in
|
||||||
* the first element; otherwise the first element holds the
|
* the first element; otherwise the first element holds the
|
||||||
* first byte of HID event data.
|
* first byte of HID event data.
|
||||||
*
|
*
|
||||||
* \returns The length of the HID Report in the \a hidData argument
|
* \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
|
* \retval Zero means no new HID event data has been recorded for the given \a id
|
||||||
@@ -61,21 +55,4 @@ size_t UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BY
|
|||||||
*/
|
*/
|
||||||
void UserHIDInit( void );
|
void UserHIDInit( void );
|
||||||
|
|
||||||
/**
|
#endif /* _USER_HID_H_ */
|
||||||
* \brief Record that a HID event has occurred
|
|
||||||
*
|
|
||||||
* \param[in] hidEvent A list of events which have occurred.
|
|
||||||
* Each element specifies a HID Report ID, a bit and byte
|
|
||||||
* within the HID Report and the value for it.
|
|
||||||
* Set the Report ID to zero if not using Report IDs
|
|
||||||
* (see 5.6, 6.2.2.7, 8.1 and 8.2).
|
|
||||||
* \param[in] hidEventCnt The length of the \a hidEvent list.
|
|
||||||
*
|
|
||||||
* \returns The index of the first unrecorded event in \a hidEvent
|
|
||||||
* \retval Zero indicates no events were recorded
|
|
||||||
* \retval \a hidEventCnt indicates all events were recorded
|
|
||||||
*/
|
|
||||||
size_t UserHIDRecordEvent( const hidEvent_t hidEvent[], const size_t hidEventCnt );
|
|
||||||
|
|
||||||
#endif /* ( 0 < HID_CONTROLS ) */
|
|
||||||
#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.
|
// 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);
|
void UserHostActive(int active);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Copyright 2013-2021 XMOS LIMITED.
|
// Copyright 2013-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Warnings relating to configuration defines located in this XC source file rather than the devicedefines.h header file in order to avoid multiple warnings being issued when the devicedefines.h header file is included in multiple files.
|
Warnings relating to configuration defines located in this XC source file rather than the xua_conf.h header file in order to avoid multiple warnings being issued when the xua_conf.h header file is included in multiple files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xua_conf_full.h"
|
#include "xua_conf_full.h"
|
||||||
|
|||||||
@@ -1,10 +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.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#if XUA_USB_EN
|
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
|
#if XUA_USB_EN
|
||||||
#include "hostactive.h"
|
#include "hostactive.h"
|
||||||
#include "audiostream.h"
|
#include "audiostream.h"
|
||||||
|
|
||||||
|
/* Implementations over-riding empty versions in lib_xud/sec/core/XUD_User.c */
|
||||||
|
|
||||||
void XUD_UserSuspend(void) __attribute__ ((weak));
|
void XUD_UserSuspend(void) __attribute__ ((weak));
|
||||||
void XUD_UserSuspend(void)
|
void XUD_UserSuspend(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2019-2022 XMOS LIMITED.
|
// Copyright 2019-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#define DEBUG_PRINT_ENABLE_HID_XC 0
|
#define DEBUG_PRINT_ENABLE_HID_XC 0
|
||||||
#include "debug_print.h"
|
#include "debug_print.h"
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod );
|
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod );
|
||||||
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime );
|
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime );
|
||||||
static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, const unsigned timeWithinPeriod );
|
static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, const unsigned timeWithinPeriod );
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2021-2022 XMOS LIMITED.
|
// Copyright 2021-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include "xua_conf_full.h"
|
#include "xua_conf_full.h"
|
||||||
#if( 0 < HID_CONTROLS )
|
#if XUA_HID_ENABLED
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +31,19 @@
|
|||||||
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI, /* 5 wMaxPacketSize */
|
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI, /* 5 wMaxPacketSize */
|
||||||
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
|
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
|
||||||
|
|
||||||
|
#if (HID_OUT_REQUIRED)
|
||||||
|
|
||||||
|
/* HID Endpoint descriptor (OUT) */
|
||||||
|
HID_ENDPOINT_DESCRIPTOR_LENGTH, /* 0 bLength */
|
||||||
|
HID_ENDPOINT_DESCRIPTOR_TYPE, /* 1 bDescriptorType */
|
||||||
|
ENDPOINT_ADDRESS_OUT_HID, /* 2 bEndpointAddress */
|
||||||
|
HID_ENDPOINT_ATTRIBUTES, /* 3 bmAttributes (INTERRUPT) */
|
||||||
|
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO, /* 4 wMaxPacketSize */
|
||||||
|
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI, /* 5 wMaxPacketSize */
|
||||||
|
ENDPOINT_INT_INTERVAL_OUT_HID, /* 6 bInterval */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif (AUDIO_CLASS == 2)
|
#elif (AUDIO_CLASS == 2)
|
||||||
|
|
||||||
.HID_In_Endpoint =
|
.HID_In_Endpoint =
|
||||||
@@ -44,6 +57,21 @@
|
|||||||
.bInterval = ENDPOINT_INT_INTERVAL_IN_HID,
|
.bInterval = ENDPOINT_INT_INTERVAL_IN_HID,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#if (HID_OUT_REQUIRED)
|
||||||
|
|
||||||
|
.HID_Out_Endpoint =
|
||||||
|
{
|
||||||
|
/* Endpoint descriptor (OUT) */
|
||||||
|
.bLength = sizeof(USB_Descriptor_Endpoint_t),
|
||||||
|
.bDescriptorType = HID_ENDPOINT_DESCRIPTOR_TYPE,
|
||||||
|
.bEndpointAddress = ENDPOINT_ADDRESS_OUT_HID,
|
||||||
|
.bmAttributes = HID_ENDPOINT_ATTRIBUTES,
|
||||||
|
.wMaxPacketSize = HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO,
|
||||||
|
.bInterval = ENDPOINT_INT_INTERVAL_OUT_HID,
|
||||||
|
},
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Unknown Audio Class"
|
#error "Unknown Audio Class"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,7 +15,8 @@
|
|||||||
#define HID_INTERFACE_DESCRIPTOR_LENGTH ( 0x09 ) /* Size of descriptor in Bytes */
|
#define HID_INTERFACE_DESCRIPTOR_LENGTH ( 0x09 ) /* Size of descriptor in Bytes */
|
||||||
#define HID_INTERFACE_DESCRIPTOR_TYPE ( 0x04 ) /* Interface 0x04 */
|
#define HID_INTERFACE_DESCRIPTOR_TYPE ( 0x04 ) /* Interface 0x04 */
|
||||||
#define HID_INTERFACE_ALTERNATE_SETTING ( 0x00 ) /* Value used alternate interfaces using SetInterface Request */
|
#define HID_INTERFACE_ALTERNATE_SETTING ( 0x00 ) /* Value used alternate interfaces using SetInterface Request */
|
||||||
#define HID_INTERFACE_NUMBER_OF_ENDPOINTS ( 0x01 ) /* Number of endpoitns for this interface (excluding 0) */
|
#define HID_INTERFACE_NUMBER_OF_ENDPOINTS ( 0x01 + HID_OUT_REQUIRED )
|
||||||
|
/* Number of endpoints for this interface (excluding 0) */
|
||||||
#define HID_INTERFACE_CLASS ( 0x03 )
|
#define HID_INTERFACE_CLASS ( 0x03 )
|
||||||
#define HID_INTERFACE_SUBCLASS ( 0x00 ) /* No boot device */
|
#define HID_INTERFACE_SUBCLASS ( 0x00 ) /* No boot device */
|
||||||
#define HID_INTERFACE_PROTOCOL ( 0x00 )
|
#define HID_INTERFACE_PROTOCOL ( 0x00 )
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018-2022 XMOS LIMITED.
|
# Copyright 2018-2023 XMOS LIMITED.
|
||||||
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
import pytest
|
import pytest
|
||||||
import Pyxsim
|
import Pyxsim
|
||||||
@@ -11,16 +11,21 @@ import sys
|
|||||||
def test_file(request):
|
def test_file(request):
|
||||||
return str(request.node.fspath)
|
return str(request.node.fspath)
|
||||||
|
|
||||||
|
|
||||||
def do_test(
|
def do_test(
|
||||||
pcm_format, i2s_role, channel_count, sample_rate, test_file, options, capfd
|
pcm_format, i2s_role, channel_count, sample_rate, word_length, test_file, options, capfd
|
||||||
):
|
):
|
||||||
|
|
||||||
build_options = []
|
build_options = []
|
||||||
output = []
|
output = []
|
||||||
testname, _ = os.path.splitext(os.path.basename(test_file))
|
testname, _ = os.path.splitext(os.path.basename(test_file))
|
||||||
|
|
||||||
desc = f"simulation_{pcm_format}_{i2s_role}_{channel_count}in_{channel_count}out_{sample_rate}"
|
build_options += [f"pcm_format={pcm_format}"]
|
||||||
|
build_options += [f"i2s_role={i2s_role}"]
|
||||||
|
build_options += [f"channel_count={channel_count}"]
|
||||||
|
build_options += [f"sample_rate={sample_rate}"]
|
||||||
|
build_options += [f"word_length={word_length}"]
|
||||||
|
|
||||||
|
desc = f"simulation_{pcm_format}_{i2s_role}_{channel_count}in_{channel_count}out_{sample_rate}_{word_length}bit"
|
||||||
binary = f"{testname}/bin/{desc}/{testname}_{desc}.xe"
|
binary = f"{testname}/bin/{desc}/{testname}_{desc}.xe"
|
||||||
|
|
||||||
tester = testers.ComparisonTester(open("pass.expect"))
|
tester = testers.ComparisonTester(open("pass.expect"))
|
||||||
@@ -52,6 +57,7 @@ def do_test(
|
|||||||
|
|
||||||
result = Pyxsim.run_on_simulator(
|
result = Pyxsim.run_on_simulator(
|
||||||
binary,
|
binary,
|
||||||
|
build_options=build_options,
|
||||||
tester=tester,
|
tester=tester,
|
||||||
simargs=simargs,
|
simargs=simargs,
|
||||||
capfd=capfd,
|
capfd=capfd,
|
||||||
@@ -65,25 +71,26 @@ def do_test(
|
|||||||
@pytest.mark.parametrize("i2s_role", ["master", "slave"])
|
@pytest.mark.parametrize("i2s_role", ["master", "slave"])
|
||||||
@pytest.mark.parametrize("pcm_format", ["i2s", "tdm"])
|
@pytest.mark.parametrize("pcm_format", ["i2s", "tdm"])
|
||||||
@pytest.mark.parametrize("channel_count", [2, 8, 16])
|
@pytest.mark.parametrize("channel_count", [2, 8, 16])
|
||||||
@pytest.mark.parametrize("sample_rate", ["48khz", "96khz", "192khz"])
|
@pytest.mark.parametrize("word_length", [16, 32]) # I2S world length in bits
|
||||||
|
@pytest.mark.parametrize("sample_rate", [48000, 96000, 192000])
|
||||||
def test_i2s_loopback(
|
def test_i2s_loopback(
|
||||||
i2s_role, pcm_format, channel_count, sample_rate, test_file, options, capfd
|
i2s_role, pcm_format, channel_count, sample_rate, word_length, test_file, options, capfd
|
||||||
):
|
):
|
||||||
|
|
||||||
if pcm_format == "i2s" and channel_count == 16:
|
if pcm_format == "i2s" and channel_count == 16:
|
||||||
pytest.skip("Invalid parameter combination")
|
pytest.skip("Invalid parameter combination")
|
||||||
|
|
||||||
if pcm_format == "i2s" and sample_rate not in ["48khz", "192khz"]:
|
if pcm_format == "i2s" and sample_rate not in [48000, 192000]:
|
||||||
pytest.skip("Invalid parameter combination")
|
pytest.skip("Invalid parameter combination")
|
||||||
|
|
||||||
if pcm_format == "tdm" and channel_count == 2:
|
if pcm_format == "tdm" and channel_count == 2:
|
||||||
pytest.skip("Invalid parameter combination")
|
pytest.skip("Invalid parameter combination")
|
||||||
|
|
||||||
if pcm_format == "tdm" and sample_rate == "192khz":
|
if pcm_format == "tdm" and sample_rate == 192000:
|
||||||
pytest.skip("Invalid parameter combination")
|
pytest.skip("Invalid parameter combination")
|
||||||
|
|
||||||
result = do_test(
|
result = do_test(
|
||||||
pcm_format, i2s_role, channel_count, sample_rate, test_file, options, capfd
|
pcm_format, i2s_role, channel_count, sample_rate, word_length, test_file, options, capfd
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result
|
assert result
|
||||||
|
|||||||
@@ -1,126 +1,44 @@
|
|||||||
TARGET = xk-audio-216-mc.xn
|
TARGET = xk-audio-216-mc.xn
|
||||||
USED_MODULES = lib_xua lib_i2c lib_logging
|
USED_MODULES = lib_xua lib_i2c lib_logging
|
||||||
|
|
||||||
BUILD_FLAGS = -O0 -g -lflash -DXUD_CORE_CLOCK=600 -fxscope -save-temps -march=xs2a -DUSB_TILE=tile[1]
|
BUILD_FLAGS = -O3 -g -lflash -DXUD_CORE_CLOCK=600 -fxscope -save-temps -march=xs2a -DUSB_TILE=tile[1] \
|
||||||
|
-DXUA_ADAT_RX_EN=0 -DXUA_ADAT_TX_EN=0 -DXUA_SPDIF_RX_EN=0 -DXUA_SPDIF_TX_EN=0 -DMIDI=0 \
|
||||||
|
-DSIMULATION=1
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_master_2in_2out_48khz = $(BUILD_FLAGS) \
|
ifndef pcm_format
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
$(error pcm_format is not set)
|
||||||
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
|
endif
|
||||||
-D DEFAULT_FREQ=48000
|
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_slave_2in_2out_48khz = $(BUILD_FLAGS) \
|
ifndef i2s_role
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
$(error i2s_role is not set)
|
||||||
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
|
endif
|
||||||
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1
|
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_master_2in_2out_192khz = $(BUILD_FLAGS) \
|
ifndef channel_count
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
$(error channel_count is not set)
|
||||||
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -D I2S_CHANS_ADC=2 -D I2S_CHANS_DAC=2 \
|
endif
|
||||||
-D DEFAULT_FREQ=192000
|
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_slave_2in_2out_192khz = $(BUILD_FLAGS) \
|
ifndef sample_rate
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
$(error sample_rate is not set)
|
||||||
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
|
endif
|
||||||
-D DEFAULT_FREQ=192000 -DCODEC_MASTER=1
|
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_master_8in_8out_48khz = $(BUILD_FLAGS) \
|
ifndef word_length
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
$(error word_length is not set)
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
endif
|
||||||
-D DEFAULT_FREQ=48000
|
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_slave_8in_8out_48khz = $(BUILD_FLAGS) \
|
ifeq ($(pcm_format),tdm)
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
BUILD_FLAGS += -DXUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
endif
|
||||||
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1
|
ifeq ($(i2s_role),slave)
|
||||||
|
BUILD_FLAGS += -DCODEC_MASTER=1
|
||||||
|
endif
|
||||||
|
|
||||||
BUILD_FLAGS_i2s_master_8in_8out_192khz = $(BUILD_FLAGS) \
|
XCC_FLAGS_simulation_${pcm_format}_${i2s_role}_$(channel_count)in_$(channel_count)out_$(sample_rate)_$(word_length)bit = $(BUILD_FLAGS) \
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
-DNUM_USB_CHAN_IN=${channel_count} \
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
-DNUM_USB_CHAN_OUT=${channel_count} \
|
||||||
-D DEFAULT_FREQ=192000 \
|
-DI2S_CHANS_DAC=${channel_count} \
|
||||||
-O2 # optimisations to meet timing
|
-DI2S_CHANS_ADC=${channel_count} \
|
||||||
|
-DDEFAULT_FREQ=${sample_rate} \
|
||||||
BUILD_FLAGS_i2s_slave_8in_8out_192khz = $(BUILD_FLAGS) \
|
-DXUA_I2S_N_BITS=${word_length}
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
|
||||||
-D DEFAULT_FREQ=192000 -DCODEC_MASTER=1 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_master_8in_8out_48khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
|
||||||
-D DEFAULT_FREQ=48000 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_master_8in_8out_96khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
|
||||||
-D DEFAULT_FREQ=96000 \
|
|
||||||
-O3 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_slave_8in_8out_48khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
|
||||||
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_slave_8in_8out_96khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
|
|
||||||
-D DEFAULT_FREQ=96000 -DCODEC_MASTER=1 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_master_16in_16out_48khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=16 -D NUM_USB_CHAN_OUT=16 -D I2S_CHANS_ADC=16 -D I2S_CHANS_DAC=16 \
|
|
||||||
-D DEFAULT_FREQ=48000 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_master_16in_16out_96khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=16 -D NUM_USB_CHAN_OUT=16 -D I2S_CHANS_ADC=16 -D I2S_CHANS_DAC=16 \
|
|
||||||
-D DEFAULT_FREQ=96000 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_slave_16in_16out_48khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=16 -D NUM_USB_CHAN_OUT=16 -D I2S_CHANS_ADC=16 -D I2S_CHANS_DAC=16 \
|
|
||||||
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
BUILD_FLAGS_tdm_slave_16in_16out_96khz = $(BUILD_FLAGS) -D XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM \
|
|
||||||
-D XUA_ADAT_RX_EN=0 -D XUA_ADAT_TX_EN=0 -D XUA_SPDIF_RX_EN=0 -D XUA_SPDIF_TX_EN=0 -D MIDI=0 \
|
|
||||||
-D NUM_USB_CHAN_IN=16 -D NUM_USB_CHAN_OUT=16 -D I2S_CHANS_ADC=16 -D I2S_CHANS_DAC=16 \
|
|
||||||
-D DEFAULT_FREQ=96000 -DCODEC_MASTER=1 \
|
|
||||||
-O2 # optimisations to meet timing
|
|
||||||
|
|
||||||
|
|
||||||
#XCC_FLAGS_hardware_i2s_master_2in_2out_48khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_2in_2out_48khz)
|
|
||||||
#XCC_FLAGS_hardware_i2s_master_2in_2out_192khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_2in_2out_192khz)
|
|
||||||
#XCC_FLAGS_hardware_i2s_master_8in_8out_48khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_8in_8out_48khz)
|
|
||||||
#XCC_FLAGS_hardware_i2s_master_8in_8out_192khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_8in_8out_192khz)
|
|
||||||
#XCC_FLAGS_hardware_tdm_master_8in_8out_48khz = -D HARDWARE $(BUILD_FLAGS_tdm_master_8in_8out_48khz)
|
|
||||||
|
|
||||||
XCC_FLAGS_simulation_i2s_master_2in_2out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_2in_2out_48khz)
|
|
||||||
XCC_FLAGS_simulation_i2s_slave_2in_2out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_2in_2out_48khz)
|
|
||||||
|
|
||||||
XCC_FLAGS_simulation_i2s_master_2in_2out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_2in_2out_192khz)
|
|
||||||
XCC_FLAGS_simulation_i2s_slave_2in_2out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_2in_2out_192khz)
|
|
||||||
|
|
||||||
XCC_FLAGS_simulation_i2s_master_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_8in_8out_48khz)
|
|
||||||
XCC_FLAGS_simulation_i2s_slave_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_8in_8out_48khz)
|
|
||||||
|
|
||||||
XCC_FLAGS_simulation_i2s_master_8in_8out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_8in_8out_192khz)
|
|
||||||
XCC_FLAGS_simulation_i2s_slave_8in_8out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_8in_8out_192khz)
|
|
||||||
|
|
||||||
XCC_FLAGS_simulation_tdm_master_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_master_8in_8out_48khz)
|
|
||||||
XCC_FLAGS_simulation_tdm_master_8in_8out_96khz = -D SIMULATION $(BUILD_FLAGS_tdm_master_8in_8out_96khz)
|
|
||||||
XCC_FLAGS_simulation_tdm_slave_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_slave_8in_8out_48khz)
|
|
||||||
XCC_FLAGS_simulation_tdm_slave_8in_8out_96khz = -D SIMULATION $(BUILD_FLAGS_tdm_slave_8in_8out_96khz)
|
|
||||||
|
|
||||||
XCC_FLAGS_simulation_tdm_master_16in_16out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_master_16in_16out_48khz)
|
|
||||||
XCC_FLAGS_simulation_tdm_master_16in_16out_96khz = -D SIMULATION $(BUILD_FLAGS_tdm_master_16in_16out_96khz)
|
|
||||||
XCC_FLAGS_simulation_tdm_slave_16in_16out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_slave_16in_16out_48khz)
|
|
||||||
XCC_FLAGS_simulation_tdm_slave_16in_16out_96khz = -D SIMULATION $(BUILD_FLAGS_tdm_slave_16in_16out_96khz)
|
|
||||||
|
|
||||||
XMOS_MAKE_PATH ?= ../..
|
XMOS_MAKE_PATH ?= ../..
|
||||||
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common
|
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2016-2022 XMOS LIMITED.
|
// Copyright 2016-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
#define DEBUG_UNIT MAIN
|
#define DEBUG_UNIT MAIN
|
||||||
#include "debug_print.h"
|
#include "debug_print.h"
|
||||||
|
|
||||||
|
|
||||||
/* Port declarations. Note, the defines come from the xn file */
|
/* Port declarations. Note, the defines come from the xn file */
|
||||||
#if I2S_WIRES_DAC > 0
|
#if I2S_WIRES_DAC > 0
|
||||||
on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
|
on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
|
||||||
@@ -92,9 +91,10 @@ clock clk_audio_mclk = on tile[AUDIO_IO_TILE]: XS1_CLKBLK_2; /*
|
|||||||
#define TOTAL_TEST_FRAMES (5 * DEFAULT_FREQ)
|
#define TOTAL_TEST_FRAMES (5 * DEFAULT_FREQ)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SAMPLE(frame_count, channel_num) (((frame_count) << 8) | ((channel_num) & 0xFF))
|
#define SHIFT (16) /* Note, we shift samples up such that we can test down to 16bit I2S */
|
||||||
#define SAMPLE_FRAME_NUM(test_word) ((test_word) >> 8)
|
#define SAMPLE(frame_count, channel_num) ((((frame_count) << 8) | ((channel_num) & 0xFF))<<SHIFT)
|
||||||
#define SAMPLE_CHANNEL_NUM(test_word) ((test_word) & 0xFF)
|
#define SAMPLE_FRAME_NUM(test_word) ((test_word>>SHIFT) >> 8)
|
||||||
|
#define SAMPLE_CHANNEL_NUM(test_word) ((test_word>>SHIFT) & 0xFF)
|
||||||
|
|
||||||
void generator(chanend c_checker, chanend c_out)
|
void generator(chanend c_checker, chanend c_out)
|
||||||
{
|
{
|
||||||
@@ -105,7 +105,6 @@ void generator(chanend c_checker, chanend c_out)
|
|||||||
|
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
underflow_word = inuint(c_out);
|
underflow_word = inuint(c_out);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2016-2022 XMOS LIMITED.
|
// Copyright 2016-2023 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#ifdef SIMULATION
|
#ifdef SIMULATION
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ extern out port p_lrclk_gen;
|
|||||||
extern clock clk_audio_lrclk_gen;
|
extern clock clk_audio_lrclk_gen;
|
||||||
|
|
||||||
void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame){
|
void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame){
|
||||||
const unsigned data_bits = 32;
|
const unsigned data_bits = XUA_I2S_N_BITS;
|
||||||
const unsigned mclk_freq = 24576000;
|
const unsigned mclk_freq = 24576000;
|
||||||
|
|
||||||
const unsigned mclk_bclk_ratio = mclk_freq / (chans_per_frame * samFreq * data_bits);
|
const unsigned mclk_bclk_ratio = mclk_freq / (chans_per_frame * samFreq * data_bits);
|
||||||
@@ -61,5 +61,4 @@ void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame
|
|||||||
master_mode_clk_setup();
|
master_mode_clk_setup();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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 \
|
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 \
|
-DBUS_SPEED=2 \
|
||||||
|
-DXUA_USE_APP_PLL=0 \
|
||||||
$(TEST_FLAGS)
|
$(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 \
|
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 \
|
-DBUS_SPEED=1 \
|
||||||
|
-DXUA_USE_APP_PLL=0 \
|
||||||
$(TEST_FLAGS)
|
$(TEST_FLAGS)
|
||||||
|
|
||||||
TARGET = test_xs3_600.xn
|
TARGET = test_xs3_600.xn
|
||||||
|
|||||||
Reference in New Issue
Block a user