forked from PAWPAW-Mirror/lib_xua
Compare commits
62 Commits
v3.4.0
...
feat/dummy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a2926d1d8 | ||
|
|
85fd297336 | ||
|
|
c92a640439 | ||
|
|
1ef5129fde | ||
|
|
355df6d6b8 | ||
|
|
0bff3dc5a8 | ||
|
|
9abd3b33f3 | ||
|
|
0932ca0ccc | ||
|
|
f1df805b17 | ||
|
|
867fb3f228 | ||
|
|
9cbdf6374e | ||
|
|
a5922ce3ea | ||
|
|
e24bbe42eb | ||
|
|
1488ace820 | ||
|
|
06bd547c69 | ||
|
|
c2e1a8f17a | ||
|
|
58bb074f0d | ||
|
|
c794ee77d5 | ||
|
|
1cd24963d5 | ||
|
|
b27514fd9a | ||
|
|
5d886487fa | ||
|
|
1b50abb7a2 | ||
|
|
d3f0f11d9e | ||
|
|
897328f9c1 | ||
|
|
b1fe49aff3 | ||
|
|
d3ad29e8a6 | ||
|
|
17944ad908 | ||
|
|
131dd252c0 | ||
|
|
23d043630f | ||
|
|
761a33f5e4 | ||
|
|
12ec1d7536 | ||
|
|
2dba6dce36 | ||
|
|
9cf931898e | ||
|
|
9b104af8cf | ||
|
|
c469dd6cde | ||
|
|
b238196f74 | ||
|
|
e9586b59d3 | ||
|
|
6d168b3209 | ||
|
|
d301fef6d7 | ||
|
|
1f4e9a99b8 | ||
|
|
981ea78be7 | ||
|
|
6cee90d876 | ||
|
|
79d14f8b59 | ||
|
|
05dcb8f3ab | ||
|
|
4e7ddb4036 | ||
|
|
e8fcc80415 | ||
|
|
71a657dc9a | ||
|
|
ccfca90451 | ||
|
|
f7b05be05b | ||
|
|
fbda8fe92a | ||
|
|
be69d3468e | ||
|
|
7cae9c385c | ||
|
|
d9de1f0322 | ||
|
|
dd21ed0a84 | ||
|
|
d50c9510c6 | ||
|
|
b032310302 | ||
|
|
8f9828ea2c | ||
|
|
50097db00d | ||
|
|
c59f9a7c0c | ||
|
|
7ae04ca313 | ||
|
|
2562f0eb31 | ||
|
|
baaef3b749 |
@@ -1,6 +1,14 @@
|
|||||||
lib_xua Change Log
|
lib_xua Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
UNRELEASED
|
||||||
|
----------
|
||||||
|
|
||||||
|
* ADDED: Configurable word-length for I2S/TDM via XUA_I2S_N_BITS
|
||||||
|
* 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)
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,11 @@
|
|||||||
|
|
||||||
#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
|
||||||
@@ -193,6 +197,36 @@
|
|||||||
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef XUA_I2S_DUMMY_SAMPS
|
||||||
|
#define XUA_I2S_DUMMY_SAMPS (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
||||||
|
*
|
||||||
|
* Default: 32 bits
|
||||||
|
*/
|
||||||
|
#ifndef XUA_I2S_N_BITS
|
||||||
|
#define XUA_I2S_N_BITS (32)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (XUA_I2S_N_BITS != 16) && (XUA_I2S_N_BITS != 32)
|
||||||
|
#error Unsupported value for XUA_I2S_N_BITS (only values 16/32 supported)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
||||||
|
*
|
||||||
|
* Default: 32 bits
|
||||||
|
*/
|
||||||
|
#ifndef XUA_I2S_N_BITS
|
||||||
|
#define XUA_I2S_N_BITS (32)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (XUA_I2S_N_BITS != 16) && (XUA_I2S_N_BITS != 32)
|
||||||
|
#error Unsupported value for XUA_I2S_N_BITS (only values 16/32 supported)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Max supported sample frequency for device (Hz). Default: 192000
|
* @brief Max supported sample frequency for device (Hz). Default: 192000
|
||||||
*/
|
*/
|
||||||
@@ -1194,7 +1228,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)
|
||||||
|
|||||||
@@ -50,6 +50,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
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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) \
|
||||||
|
|||||||
@@ -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,6 +15,8 @@
|
|||||||
#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"
|
||||||
|
|
||||||
@@ -50,19 +52,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 +65,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]);
|
||||||
|
|
||||||
|
|
||||||
@@ -91,12 +80,30 @@ unsigned dsdMode = DSD_MODE_OFF;
|
|||||||
#endif
|
#endif
|
||||||
#include "xua_audiohub_st.h"
|
#include "xua_audiohub_st.h"
|
||||||
|
|
||||||
|
static inline void PortOutput(buffered out port:32 p, int bits, int value)
|
||||||
|
{
|
||||||
|
if(bits == 32)
|
||||||
|
p <: value;
|
||||||
|
else
|
||||||
|
partout(p, bits, value);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:32 p_lrclk)
|
static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:32 p_lrclk)
|
||||||
{
|
{
|
||||||
#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 +121,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 +277,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +294,19 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if XUA_I2S_DUMMY_SAMPS
|
||||||
|
if(frameCount == 0)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < XUA_I2S_DUMMY_SAMPS; j++)
|
||||||
|
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||||
|
{
|
||||||
|
PortOutput(p_i2s_dac[i], XUA_I2S_N_BITS, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (I2S_CHANS_ADC != 0)
|
#if (I2S_CHANS_ADC != 0)
|
||||||
#if (AUD_TO_USB_RATIO > 1)
|
#if (AUD_TO_USB_RATIO > 1)
|
||||||
if (0 == audioToUsbRatioCounter)
|
if (0 == audioToUsbRatioCounter)
|
||||||
@@ -290,9 +326,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 +388,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 +464,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)
|
||||||
@@ -445,12 +499,30 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if XUA_I2S_DUMMY_SAMPS
|
||||||
|
if(frameCount == 1)
|
||||||
|
{
|
||||||
|
int dummyBits;
|
||||||
|
for(int j = 0; j < XUA_I2S_DUMMY_SAMPS; j++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||||
|
{
|
||||||
|
asm volatile("in %0, res[%1]" : "=r"(dummyBits) : "r"(p_i2s_adc[i]));
|
||||||
|
if(XUA_I2S_N_BITS)
|
||||||
|
set_port_shift_count(p_i2s_adc[i], XUA_I2S_N_BITS);
|
||||||
|
}
|
||||||
|
asm volatile("in %0, res[%1]" : "=r"(dummyBits) : "r"(p_lrclk));
|
||||||
|
if(XUA_I2S_N_BITS)
|
||||||
|
set_port_shift_count(p_lrclk, XUA_I2S_N_BITS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||||
syncError += HandleSampleClock(frameCount, p_lrclk);
|
syncError += HandleSampleClock(frameCount, p_lrclk);
|
||||||
#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 +541,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 +598,6 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma xta endpoint "deliver_return"
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,13 +755,13 @@ 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 * 2;
|
||||||
/* I2S has 32 bits per sample. *8 as 8 channels */
|
|
||||||
unsigned numBits = 256;
|
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||||
#else
|
{
|
||||||
/* I2S has 32 bits per sample. *2 as 2 channels */
|
/* TDM has 8 channels */
|
||||||
unsigned numBits = 64;
|
numBits *= 4;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#if (DSD_CHANS_DAC > 0)
|
#if (DSD_CHANS_DAC > 0)
|
||||||
if(dsdMode == DSD_MODE_DOP)
|
if(dsdMode == DSD_MODE_DOP)
|
||||||
@@ -701,17 +775,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 +805,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 +828,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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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,7 +142,7 @@ 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)
|
||||||
@@ -228,7 +228,7 @@ 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,
|
||||||
@@ -685,7 +685,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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 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,6 +1,7 @@
|
|||||||
// 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
|
||||||
|
#include "xua.h"
|
||||||
|
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
@@ -41,11 +42,11 @@ 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);
|
||||||
const unsigned bclk_lrclk_ratio = (chans_per_frame * data_bits); // 48.828Hz LRCLK
|
const unsigned bclk_lrclk_ratio = (chans_per_frame * data_bits + (data_bits * XUA_I2S_DUMMY_SAMPS)); // 48.828Hz LRCLK
|
||||||
|
|
||||||
//bclk
|
//bclk
|
||||||
configure_clock_src_divide(clk_audio_bclk_gen, p_mclk_gen, mclk_bclk_ratio/2);
|
configure_clock_src_divide(clk_audio_bclk_gen, p_mclk_gen, mclk_bclk_ratio/2);
|
||||||
@@ -61,5 +62,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
|
||||||
|
|||||||
Reference in New Issue
Block a user