62 Commits

Author SHA1 Message Date
Ross Owen
3a2926d1d8 Set default XUA_I2S_DUMMY_SAMPS value to 0 2023-06-12 18:07:10 +01:00
Ross Owen
85fd297336 Merge remote-tracking branch 'upstream' into feat/dummy_samps 2023-06-12 16:22:57 +01:00
Ross Owen
c92a640439 Added support for I2S/TDM “dummy samples” via XUA_I2S_DUMMY_SAMPS 2023-06-12 16:22:35 +01:00
Ross Owen
1ef5129fde Variable i2s bit width (#331)
- Add support for variable width I2S (via XUA_I2S_N_BITS)
- Add support for variable width TDM (again via XUD_I2S_N_BITS when XUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM)
- Includes support for xcore as I2S/TDM master and slave
- Add testing of the the above to test_i2s_loopback
- Rationalised test config building in test_i2s_loopback
- Documentation updated
2023-06-08 15:31:12 +01:00
Ross Owen
355df6d6b8 Fixed doc build 2023-06-07 15:24:29 +01:00
Ross Owen
0bff3dc5a8 Removed documentation for XUA_I2S_N_BITS=24 2023-06-07 12:32:07 +01:00
Ross Owen
9abd3b33f3 Bump lib_spdif dependency requirement 2023-06-07 12:17:40 +01:00
Ross Owen
0932ca0ccc Documentation updates relating to TDM/I2S 2023-06-07 11:53:42 +01:00
Ross Owen
f1df805b17 Added checks on XUA_I2S_N_BITS value 2023-06-07 10:24:40 +01:00
Ross Owen
867fb3f228 Use XUA_I2S_N_BITS when deciding whether or not to delay falling edge of bit clock when CODEC_MASTER=1 2023-06-06 20:20:15 +01:00
Ross Owen
9cbdf6374e Copyright date update 2023-06-06 19:34:36 +01:00
Ross Owen
a5922ce3ea Fixed issue with when XUA_I2S_N_BITS !=32 and CODEC_MASTER == 1 2023-06-06 19:13:25 +01:00
Ross Owen
e24bbe42eb test_i2s_loopback: add testing support for 16bit 2023-06-06 18:31:52 +01:00
Ross Owen
1488ace820 Fixed issue with I2S input when XUA_I2S_N_BITS != 32 2023-06-06 18:10:42 +01:00
Ross Owen
06bd547c69 Set XUA_I2S_N_BITS in test_i2s_loopback 2023-06-06 15:27:00 +01:00
Ross Owen
c2e1a8f17a Fixed issue where sample rate not set in test_i2s_loopback 2023-06-06 15:22:34 +01:00
Ross Owen
58bb074f0d Rationalisation of test_i2s_loopback config building 2023-06-06 14:52:03 +01:00
Ross Owen
c794ee77d5 Update copyright comment 2023-06-06 12:01:46 +01:00
Ross Owen
1cd24963d5 Fixed build issues when CODEC_MASTER set 2023-06-05 14:37:01 +01:00
Ross Owen
b27514fd9a Added XUA_I2S_N_BITS (was N_BITS_I2S) and tidied up usage of define 2023-06-05 14:24:59 +01:00
Ross Owen
5d886487fa Fixed operation when N_BITS_I2S define and small tidies 2023-06-02 16:37:43 +01:00
Ross Owen
1b50abb7a2 Resolve build issues post merge 2023-06-02 14:35:15 +01:00
Ross Owen
d3f0f11d9e Removed example 2023-06-02 14:20:44 +01:00
Ross Owen
897328f9c1 Resolved conflicts merging with develop 2023-06-02 14:18:44 +01:00
Ross Owen
b1fe49aff3 Conflicted merge 2023-06-02 14:06:13 +01:00
Brennan Magee
d3ad29e8a6 Merge pull request #330 from BrennanGit/fix/jenkins_windows_bat_sh
Use bat not sh for windows builds on Jenkins
2023-05-31 09:38:31 +01:00
Brennan Magee
17944ad908 Use bat not sh for windows builds on Jenkins
This was causing an issue where the windows workspaces could not be cleared.
2023-05-30 17:08:32 +01:00
danielpieczko
131dd252c0 Merge pull request #329 from danielpieczko/jenkins_windows_build_fix
Use withVS instead of runVS to use the latest Jenkins Windows agents
2023-05-19 09:20:11 +01:00
Daniel Pieczko
23d043630f Use withVS instead of runVS to use the latest Jenkins Windows agents 2023-05-19 09:03:33 +01:00
Ross Owen
761a33f5e4 Update CHANGELOG.rst 2023-05-18 10:07:25 +01:00
Ross Owen
12ec1d7536 module_build_info: lib_xud 2.2.2 -> 2.2.3 2023-05-18 10:05:30 +01:00
Ross Owen
2dba6dce36 Update CHANGELOG.rst 2023-05-18 10:04:36 +01:00
Ross Owen
9cf931898e Move check for XUA_USB_EN after include of xua.h (#325) 2023-05-17 14:55:37 +01:00
Ross Owen
9b104af8cf Merge branch 'develop' into develop 2023-05-17 14:00:38 +01:00
Ross Owen
c469dd6cde Changelog update 2023-05-17 13:58:56 +01:00
Ross Owen
b238196f74 Copyright comment only 2023-05-17 13:55:41 +01:00
Ross Owen
e9586b59d3 Move check for XUA_USB_EN after include of xua.h 2023-05-17 13:48:36 +01:00
Ross Owen
6d168b3209 Merge pull request #321 from TDW89/fix/SPDIF-api
SPDIF api fix
2023-05-17 11:05:57 +01:00
Ross Owen
d301fef6d7 Merge pull request #324 from xross/fix/sw_usb_audio_156
Fix for exception when entering DSD mode (also some tidies)
2023-05-15 10:24:47 +01:00
Ross Owen
1f4e9a99b8 Changelog update 2023-05-12 17:36:04 +01:00
Ross Owen
981ea78be7 Fix for exception when entering DSD mode (also some tidies) 2023-05-12 17:22:47 +01:00
Ross Owen
6cee90d876 Fix audio interrupt endpoint type
Note, this has no functional change
2023-04-17 12:23:27 +01:00
Tom Williams
79d14f8b59 changed to use spdif_rx from SpdifReceive 2023-04-05 17:34:33 +01:00
danielpieczko
05dcb8f3ab Merge pull request #323 from danielpieczko/fix/mixer_init
Fix memory corruption during initialisation of mixer weights
2023-04-04 14:54:57 +01:00
Daniel Pieczko
4e7ddb4036 Fix memory corruption during initialisation of mixer weights 2023-04-04 14:31:35 +01:00
Ross Owen
e8fcc80415 Merge pull request #322 from xross/fix/sw_usb_audio_152
Tidy up of volume control. Removal of xc_ptr.h in favour of built in xc pointers
2023-04-04 14:15:07 +01:00
Ross Owen
71a657dc9a Tidy up of volume control. Removal of xc_ptr.h in favour of built in xc pointers. 2023-04-04 12:37:59 +01:00
Tom Williams
ccfca90451 removed referance to outdated header file, changed for the api file 2023-03-22 15:56:28 +00:00
Ed
f7b05be05b Merge commit 'a44d5466b5ff4d1d766236d7036daceedef9f2c2' into variable_i2s_bit_width 2021-05-19 10:08:20 +01:00
Ed
fbda8fe92a Merge branch 'develop' of github.com:xmos/lib_xua into variable_i2s_bit_width 2021-05-19 10:02:22 +01:00
Ed
be69d3468e Initial guarding of variable bit I2S modifications 2019-08-23 16:15:47 +01:00
Ed
7cae9c385c Merge remote-tracking branch 'xmos/develop' into variable_i2s_bit_width 2019-08-23 15:34:06 +01:00
Ed Clarke
d9de1f0322 Add clock divider checks and remove debug prints 2019-05-01 10:58:15 +01:00
Ed Clarke
dd21ed0a84 Fix LRCLK alignment when N_BITS < 32 2019-05-01 10:25:22 +01:00
Ed Clarke
d50c9510c6 Fix app so that it loops (working 32b I2S master) 2019-05-01 09:49:36 +01:00
Ed Clarke
b032310302 Initial modifications to extend support to variable bit width master 2019-04-30 18:09:23 +01:00
Ed Clarke
8f9828ea2c Add simple test app for I2S loopback (no USB) 2019-04-30 18:07:15 +01:00
Ed Clarke
50097db00d Merge commit 'c59f9a7c0c628bffc9f9de5a6a4ee55e660d32fe' into variable_i2s_bit_width 2019-04-30 16:01:25 +01:00
Ed Clarke
c59f9a7c0c Make lrcheck mask track the data size 2018-10-15 08:56:57 +01:00
Ed Clarke
7ae04ca313 Enable error checking (helps recover from noise) 2018-10-12 14:26:02 +01:00
Ed Clarke
2562f0eb31 Fix I2S alignment 2018-10-12 14:25:47 +01:00
Ed Clarke
baaef3b749 Initial modifications for 24b I2S slave (without sync error check) 2018-10-10 11:21:44 +01:00
27 changed files with 411 additions and 313 deletions

View File

@@ -1,6 +1,14 @@
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
-----

14
Jenkinsfile vendored
View File

@@ -1,4 +1,4 @@
@Library('xmos_jenkins_shared_library@v0.21.0') _
@Library('xmos_jenkins_shared_library@v0.24.0') _
getApproval()
@@ -145,12 +145,16 @@ pipeline {
dir("${REPO}") {
checkout scm
dir("${REPO}/host/xmosdfu") {
runVS('nmake /f Makefile.Win32')
withVS("vcvars32.bat") {
bat "nmake /f Makefile.Win32"
}
}
dir("host_usb_mixer_control") {
runVS('msbuild host_usb_mixer_control.vcxproj /property:Configuration=Release /property:Platform=x64')
sh 'mkdir Win/x64'
sh 'mv bin/Release/x64/host_usb_mixer_control.exe Win/x64/xmos_mixer.exe'
withVS() {
bat 'msbuild host_usb_mixer_control.vcxproj /property:Configuration=Release /property:Platform=x64'
}
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
}
}

View File

@@ -93,7 +93,11 @@
#define XUA_PCM_FORMAT_I2S (0)
#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
#if (XUA_PCM_FORMAT != XUA_PCM_FORMAT_I2S) && (XUA_PCM_FORMAT != XUA_PCM_FORMAT_TDM)
#error Bad value for XUA_PCM_FORMAT
@@ -193,6 +197,36 @@
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
#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
*/
@@ -1194,7 +1228,8 @@ enum USBEndpointNumber_Out
#define AUDIO_START_FROM_DFU (0x87654321)
#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)
#define LEVEL_UPDATE_RATE (400000)

View File

@@ -50,6 +50,15 @@ Audio Class
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
^^^^

View File

@@ -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::
SpdifReceive(p_spdif_rx, c_spdif_rx, 1, clk_spd_rx);
spdif_rx(c_spdif_rx,p_spdif_rx,clk_spd_rx,192000);
.. 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
master clock must be able to synchronise to this external digital stream. Additionally, the host can be

View File

@@ -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)
- N/A (Must be defined)
* - ``XUA_PCM_FORMAT``
- Enabled either TDM or I2S mode
- Enables either TDM or I2S mode
- ``XUA_PCM_FORMAT_I2S``
* - ``CODEC_MASTER``
- Sets is xCORE is I2S master or slave
- Sets if xCORE is I2S master or slave
- ``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``.
For example::
@@ -42,8 +45,16 @@ For example::
<Port Location="XS1_PORT_1G" Name="PORT_I2S_ADC1"/>
</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::
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.

View File

@@ -21,7 +21,7 @@ full listing of these ``TILE`` defines.
- Description
- Default
* - ``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``
* - ``XUD_TILE``
- Tile on which USB resides, including buffering for all USB interfaces/endppoints

View File

@@ -25,7 +25,7 @@ Overview
| +---------------------------------------------------------------------------------------------+
| | `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 |
| +---------------------------------------------------------------------------------------------+

View File

@@ -5,7 +5,7 @@ I2S/TDM
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 */
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.
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 clk_audio_bclk = on tile[0]: XS1_CLKBLK_4; /* Bit clock */

View File

@@ -11,9 +11,9 @@ endif
DEPENDENT_MODULES = lib_locks(>=2.1.0) \
lib_logging(>=3.1.1) \
lib_mic_array(>=4.5.0) \
lib_spdif(>=4.2.1) \
lib_spdif(>=5.0.0) \
lib_xassert(>=4.1.0) \
lib_xud(>=2.2.2) \
lib_xud(>=2.2.3) \
lib_adat(>=1.0.0)
MODULE_XCC_FLAGS = $(XCC_FLAGS) \

View File

@@ -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.
#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.
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
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)
{
/* Check for DSD - note we only move into DoP mode if valid DoP Freq */

View File

@@ -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.
#include "xua.h"
#include "dsd_support.h"
#if (DSD_CHANS_DAC != 0)
@@ -12,7 +11,7 @@ extern buffered out port:32 p_dsd_clk;
extern unsigned dsdMode;
#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(dsdMode == DSD_MODE_OFF)
@@ -39,7 +38,12 @@ void InitPorts_master(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, bu
#endif
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;
/* 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
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
unsigned lrClkVal = 0x7FFFFFFF;
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
p_lrclk @ tmp <: 0x7FFFFFFF;
partout_timed(p_lrclk, XUA_I2S_N_BITS, lrClkVal, tmp);
#if (I2S_CHANS_ADC != 0)
for(int i = 0; i < I2S_WIRES_ADC; i++)
{
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 /* (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
}
#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)
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;
#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. 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
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
@@ -108,11 +126,15 @@ void InitPorts_slave(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buf
#pragma loop unroll
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
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

View File

@@ -15,6 +15,8 @@
#include <xclib.h>
#include <xs1_su.h>
#include <string.h>
#include <xassert.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)];
#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)
extern buffered out port:32 p_adat_tx;
#endif
@@ -76,7 +65,7 @@ void InitPorts_slave
#else
void InitPorts_master
#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]);
@@ -91,12 +80,30 @@ unsigned dsdMode = DSD_MODE_OFF;
#endif
#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)
{
#if CODEC_MASTER
unsigned syncError = 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)
{
@@ -114,30 +121,46 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
}
else
{
if(frameCount == 0)
syncError += (lrval != 0x80000000);
if(XUA_I2S_N_BITS == 32)
{
if(frameCount == 0)
syncError = (lrval != 0x80000000);
else
syncError = (lrval != 0x7FFFFFFF);
}
else
syncError += (lrval != 0x7FFFFFFF);
{
if(frameCount == 0)
syncError = ((lrval & lrval_mask) != 0x80000000);
else
syncError = ((lrval | (~lrval_mask)) != 0x7FFFFFFF);
}
}
return syncError;
#else
unsigned clkVal;
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
{
if(frameCount == (I2S_CHANS_PER_FRAME-1))
p_lrclk <: 0x80000000;
clkVal = 0x80000000;
else
p_lrclk <: 0x00000000;
clkVal = 0x00000000;
}
else
{
if(frameCount == 0)
p_lrclk <: 0x80000000;
clkVal = 0x80000000;
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;
#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 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
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
}
@@ -271,6 +294,19 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
else
#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 (AUD_TO_USB_RATIO > 1)
if (0 == audioToUsbRatioCounter)
@@ -290,9 +326,17 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
// p_i2s_adc[index++] :> sample;
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
unsigned sample;
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index]));
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) == audioToUsbRatioCounter)
@@ -344,7 +388,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
src_ff3v_fir_coefs[2-audioToUsbRatioCounter]);
}
#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)
@@ -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) */
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);
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.
#if (AUD_TO_USB_RATIO > 1 && !I2S_DOWNSAMPLE_MONO_IN)
if ((AUD_TO_USB_RATIO - 1) == audioToUsbRatioCounter)
@@ -445,12 +499,30 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
}
#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)
syncError += HandleSampleClock(frameCount, p_lrclk);
#endif
index = 0;
#pragma xta endpoint "i2s_output_r"
#if (I2S_CHANS_DAC != 0)
/* Output "odd" channel to DAC (i.e. right) */
#pragma loop unroll
@@ -469,7 +541,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
src_ff3v_fir_coefs[2-audioToUsbRatioCounter]);
}
#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)
@@ -523,7 +598,6 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
}
}
}
#pragma xta endpoint "deliver_return"
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
* e.g. 11.289600 / (176400 * 64) = 1 */
{
#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
/* 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
unsigned numBits = XUA_I2S_N_BITS * 2;
if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
{
/* TDM has 8 channels */
numBits *= 4;
}
#if (DSD_CHANS_DAC > 0)
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;
}
#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(dsdMode)
{
/* Configure audio ports */
ConfigAudioPortsWrapper(
/* Configure audio ports */
ConfigAudioPortsWrapper(
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
p_dsd_dac,
DSD_CHANS_DAC,
@@ -724,7 +805,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
null,
p_dsd_clk,
#endif
p_mclk_in, clk_audio_bclk, divide, curSamFreq, dsdMode);
p_mclk_in, clk_audio_bclk, divide, curSamFreq);
}
else
#endif
@@ -747,9 +828,8 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
p_bclk,
#endif
#endif
p_mclk_in, clk_audio_bclk, divide, curSamFreq, dsdMode);
}
p_mclk_in, clk_audio_bclk, divide, curSamFreq);
}
{
unsigned curFreq = curSamFreq;

View File

@@ -43,7 +43,7 @@
/*** 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_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 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 */
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
unsigned int multOut[NUM_USB_CHAN_OUT + 1];
static xc_ptr p_multOut;
unsafe
{
unsigned int volatile * unsafe multOutPtr = multOut;
}
#endif
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
unsigned int multIn[NUM_USB_CHAN_IN + 1];
static xc_ptr p_multIn;
unsafe
{
unsigned int volatile * unsafe multInPtr = multIn;
}
#endif
/* 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;
#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 <<= 3;
#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;
#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 <<= 3;
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
@@ -267,7 +279,10 @@ __builtin_unreachable();
sample <<= 16;
#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);
/* Note, in 2 byte subslot mode - ignore lower result of macs */
h <<= 3;
@@ -326,18 +341,19 @@ __builtin_unreachable();
unpackState++;
#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 <<= 3;
outuint(c_mix_out, h);
#else
outuint(c_mix_out, sample);
#endif
}
break;
default:
__builtin_unreachable();
break;
@@ -376,7 +392,10 @@ __builtin_unreachable();
int mult;
int h;
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);
sample = h << 3;
@@ -406,7 +425,10 @@ __builtin_unreachable();
int mult;
int h;
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);
sample = h << 3;
#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1)
@@ -437,7 +459,10 @@ __builtin_unreachable();
int mult;
int h;
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);
sample = h << 3;
#endif
@@ -676,13 +701,6 @@ void XUA_Buffer_Decouple(chanend c_mix_out
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_end = aud_from_host_fifo_start + BUFF_SIZE_OUT;
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 */
#if (OUT_VOLUME_IN_MIXER == 0) && (OUTPUT_VOLUME_CONTROL == 1)
for (int i = 0; i < NUM_USB_CHAN_OUT + 1; i++)
{
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i));
unsafe{
multOutPtr[i] = MAX_VOLUME_MULT;
}
#endif
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++)
{
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multIn),"r"(i));
unsafe{
multInPtr[i] = MAX_VOLUME_MULT;
}
#endif

View File

@@ -275,15 +275,10 @@ void InitLocalMixerState()
}
/* Configure default connections */
// TODO this should be a loop using defines.
mixer1Weights[0] = 0;
mixer1Weights[9] = 0;
mixer1Weights[18] = 0;
mixer1Weights[27] = 0;
mixer1Weights[36] = 0;
mixer1Weights[45] = 0;
mixer1Weights[54] = 0;
mixer1Weights[63] = 0;
for (int i = 0; i < MAX_MIX_COUNT; i++)
{
mixer1Weights[(i * MAX_MIX_COUNT) + i] = 0;
}
#if NUM_USB_CHAN_OUT > 0
/* Setup up audio output channel mapping */

View File

@@ -14,16 +14,20 @@
#include "usbaudio10.h"
#include "dbcalc.h"
#include "xua_commands.h"
#include "xc_ptr.h"
#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];
#endif
#if (IN_VOLUME_IN_MIXER == 0) && (INPUT_VOLUME_CONTROL == 1)
extern unsigned int multIn[NUM_USB_CHAN_IN + 1];
#endif
extern int interfaceAlt[];
/* Global volume and mute tables */
/* Global volume and mute tables - from xua_endpoint0.c */
extern int volsOut[];
extern unsigned int mutesOut[];
@@ -101,20 +105,6 @@ void FeedbackStabilityDelay()
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)
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 */
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)
{
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) */
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 (!isnull(c_mix_ctl))
@@ -162,8 +145,12 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
outuint(c_mix_ctl, x);
outct(c_mix_ctl, XS1_CT_END);
}
#else
asm("stw %0, %1[%2]"::"r"(x),"r"(p_multOut),"r"(i-1));
#else
unsafe
{
unsigned int * unsafe multOutPtr = multOut;
multOutPtr[i-1] = x;
}
#endif
}
}
@@ -178,7 +165,7 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
/* 0x8000 is a special value representing -inf (i.e. mute) */
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 (!isnull(c_mix_ctl))
@@ -191,7 +178,11 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
outct(c_mix_ctl, XS1_CT_END);
}
#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
}
}
@@ -205,12 +196,6 @@ static void updateMasterVol(int unitID, chanend ?c_mix_ctl)
static void updateVol(int unitID, int channel, 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
/* Check for master volume update */
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);
}
#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
break;
}
@@ -264,7 +253,11 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
outct(c_mix_ctl, XS1_CT_END);
}
#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
break;
}

View File

@@ -31,7 +31,7 @@
#endif
#if (XUA_SPDIF_RX_EN)
#include "SpdifReceive.h"
#include "spdif.h"
#endif
#if (XUA_ADAT_RX_EN)
@@ -142,7 +142,7 @@ on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN;
#endif
#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
#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 */
#endif
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
XUD_EPTYPE_BUL,
XUD_EPTYPE_INT,
#endif
#ifdef MIDI
XUD_EPTYPE_BUL,
@@ -685,7 +685,7 @@ int main()
on tile[XUD_TILE]:
{
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

View File

@@ -23,7 +23,7 @@
static unsigned int multOut_array[NUM_USB_CHAN_OUT + 1];
unsafe
{
int volatile * unsafe multOut = multOut_array;
unsigned int volatile * unsafe multOut = multOut_array;
}
#endif
@@ -31,7 +31,7 @@ unsafe
static unsigned int multIn_array[NUM_USB_CHAN_IN + 1];
unsafe
{
int volatile * unsafe multIn = multIn_array;
unsigned int volatile * unsafe multIn = multIn_array;
}
#endif
@@ -827,14 +827,14 @@ void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl)
#if (OUT_VOLUME_IN_MIXER)
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
unsafe{
multOut[i] = MAX_VOL;
multOut[i] = MAX_VOLUME_MULT;
}
#endif
#if (IN_VOLUME_IN_MIXER)
for (int i=0; i<NUM_USB_CHAN_IN; i++)
unsafe{
multIn[i] = MAX_VOL;
multIn[i] = MAX_VOLUME_MULT;
}
#endif

View File

@@ -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.
#include <xs1.h>
@@ -9,17 +9,17 @@
#include "xua.h"
/* 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_DSD_DAC0,
#endif
#if DSD_CHANS_DAC > 1
#if (DSD_CHANS_DAC > 1)
PORT_DSD_DAC1,
#endif
#if DSD_CHANS_DAC > 2
#if (DSD_CHANS_DAC > 2)
#error > 2 DSD chans currently not supported
#endif
#if DSD_CHANS_DAC > 0
#if (DSD_CHANS_DAC > 0)
};
port p_dsd_clk = PORT_DSD_CLK;
#endif
@@ -45,7 +45,7 @@ void ConfigAudioPortsWrapper(
port p_lrclk,
port p_bclk,
#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(
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)

View File

@@ -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.
#ifndef _AUDIOPORTS_H_
#define _AUDIOPORTS_H_
@@ -79,7 +79,7 @@ void ConfigAudioPortsWrapper(
buffered in port:32 p_bclk,
#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
void ConfigAudioPortsWrapper(
@@ -95,7 +95,7 @@ void ConfigAudioPortsWrapper(
port p_lrclk,
port p_bclk,
#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__*/

View File

@@ -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.
#include <xs1.h>
#include <platform.h>
@@ -6,9 +6,7 @@
#include "xua.h"
#include "audioports.h"
//extern in port p_mclk_in;
extern clock clk_audio_mclk;
//extern clock clk_audio_bclk;
void ConfigAudioPorts(
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
@@ -58,7 +56,7 @@ void ConfigAudioPorts(
}
#endif
#if (I2S_CHANS_DAC != 0)
#if (I2S_CHANS_DAC != 0)|| (DSD_CHANS_DAC != 0)
for(int i = 0; i < numPortsDac; 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 */
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_pad_delay(p_i2s_adc[i], 4);
@@ -91,7 +89,6 @@ void ConfigAudioPorts(
#endif
#elif (CODEC_MASTER)
/* Stop bit and master clock blocks */
stop_clock(clk_audio_bclk);
@@ -103,7 +100,7 @@ void ConfigAudioPorts(
/* Do some clocking shifting to get data in the valid window */
/* E.g. Only shift when running at 88.2+ kHz TDM slave */
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 */
bClkDelay_fall = 18;
@@ -112,9 +109,9 @@ void ConfigAudioPorts(
set_clock_fall_delay(clk_audio_bclk, bClkDelay_fall);
#endif
#if (I2S_CHANS_DAC != 0)
/* Clock I2S output data ports from b-clock clock block */
for(int i = 0; i < I2S_WIRES_DAC; i++)
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
/* Clock I2S/DSD output data ports from b-clock clock block */
for(int i = 0; i < numPortsDac; i++)
{
configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
}
@@ -122,7 +119,7 @@ void ConfigAudioPorts(
#if (I2S_CHANS_ADC != 0)
/* 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);
}

View File

@@ -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.
/*
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"

View File

@@ -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.
#if XUA_USB_EN
#include "xua.h"
#if XUA_USB_EN
#include "hostactive.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)
{

View File

@@ -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.
import pytest
import Pyxsim
@@ -11,16 +11,21 @@ import sys
def test_file(request):
return str(request.node.fspath)
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 = []
output = []
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"
tester = testers.ComparisonTester(open("pass.expect"))
@@ -52,6 +57,7 @@ def do_test(
result = Pyxsim.run_on_simulator(
binary,
build_options=build_options,
tester=tester,
simargs=simargs,
capfd=capfd,
@@ -65,25 +71,26 @@ def do_test(
@pytest.mark.parametrize("i2s_role", ["master", "slave"])
@pytest.mark.parametrize("pcm_format", ["i2s", "tdm"])
@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(
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:
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")
if pcm_format == "tdm" and channel_count == 2:
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")
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

View File

@@ -1,126 +1,44 @@
TARGET = xk-audio-216-mc.xn
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) \
-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=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=48000
ifndef pcm_format
$(error pcm_format is not set)
endif
BUILD_FLAGS_i2s_slave_2in_2out_48khz = $(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 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1
ifndef i2s_role
$(error i2s_role is not set)
endif
BUILD_FLAGS_i2s_master_2in_2out_192khz = $(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 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -D I2S_CHANS_ADC=2 -D I2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=192000
ifndef channel_count
$(error channel_count is not set)
endif
BUILD_FLAGS_i2s_slave_2in_2out_192khz = $(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 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=192000 -DCODEC_MASTER=1
ifndef sample_rate
$(error sample_rate is not set)
endif
BUILD_FLAGS_i2s_master_8in_8out_48khz = $(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 \
-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
ifndef word_length
$(error word_length is not set)
endif
BUILD_FLAGS_i2s_slave_8in_8out_48khz = $(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 \
-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
ifeq ($(pcm_format),tdm)
BUILD_FLAGS += -DXUA_PCM_FORMAT=XUA_PCM_FORMAT_TDM
endif
ifeq ($(i2s_role),slave)
BUILD_FLAGS += -DCODEC_MASTER=1
endif
BUILD_FLAGS_i2s_master_8in_8out_192khz = $(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 \
-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 \
-O2 # optimisations to meet timing
BUILD_FLAGS_i2s_slave_8in_8out_192khz = $(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 \
-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)
XCC_FLAGS_simulation_${pcm_format}_${i2s_role}_$(channel_count)in_$(channel_count)out_$(sample_rate)_$(word_length)bit = $(BUILD_FLAGS) \
-DNUM_USB_CHAN_IN=${channel_count} \
-DNUM_USB_CHAN_OUT=${channel_count} \
-DI2S_CHANS_DAC=${channel_count} \
-DI2S_CHANS_ADC=${channel_count} \
-DDEFAULT_FREQ=${sample_rate} \
-DXUA_I2S_N_BITS=${word_length}
XMOS_MAKE_PATH ?= ../..
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -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.
#include <platform.h>
#include <stdlib.h>
@@ -9,7 +9,6 @@
#define DEBUG_UNIT MAIN
#include "debug_print.h"
/* Port declarations. Note, the defines come from the xn file */
#if I2S_WIRES_DAC > 0
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)
#endif
#define SAMPLE(frame_count, channel_num) (((frame_count) << 8) | ((channel_num) & 0xFF))
#define SAMPLE_FRAME_NUM(test_word) ((test_word) >> 8)
#define SAMPLE_CHANNEL_NUM(test_word) ((test_word) & 0xFF)
#define SHIFT (16) /* Note, we shift samples up such that we can test down to 16bit I2S */
#define SAMPLE(frame_count, channel_num) ((((frame_count) << 8) | ((channel_num) & 0xFF))<<SHIFT)
#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)
{
@@ -105,7 +105,6 @@ void generator(chanend c_checker, chanend c_out)
frame_count = 0;
while (1) {
underflow_word = inuint(c_out);

View File

@@ -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.
#ifdef SIMULATION
#include "xua.h"
#include <platform.h>
#include <print.h>
@@ -41,11 +42,11 @@ extern out port p_lrclk_gen;
extern clock clk_audio_lrclk_gen;
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_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
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();
}
#endif
#endif