Merge remote-tracking branch 'upstream/develop' into release_prep
This commit is contained in:
@@ -4,9 +4,10 @@ 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
|
||||
* FIXED: Exception when entering DSD mode (#327)
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
@@ -153,8 +153,8 @@ pipeline {
|
||||
withVS() {
|
||||
bat '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'
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,19 @@
|
||||
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
||||
*
|
||||
* Default: 32 bits
|
||||
*/
|
||||
#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
|
||||
*/
|
||||
@@ -431,6 +448,40 @@
|
||||
#define HID_CONTROLS (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* HID may be required in two forms: the built-in XUA-HID reports, or a
|
||||
* user-provided static HID. Some sections of code are always needed, they
|
||||
* are enclosed in XUA_OR_STATIC_HID_ENABLED; code specific to XUA-HID
|
||||
* reports are enclosed in XUA_HID_ENABLED.
|
||||
*
|
||||
* HID_CONTROLS implies that the XUA_HID is used, and hence defines both.
|
||||
* In order to roll your own, do not enable HID_CONTROLS, but instead
|
||||
* create a file static_hid_report.h that contains the static descriptor.
|
||||
*
|
||||
* You must also supply your own function to deal with the HID endpoint(s)
|
||||
* in this case.
|
||||
*/
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#define XUA_HID_ENABLED (1)
|
||||
#define XUA_OR_STATIC_HID_ENABLED (1)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__static_hid_report_h_exists__)
|
||||
#define XUA_OR_STATIC_HID_ENABLED (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable a HID OUT endpoint. Only use this if you supply your own HID control.
|
||||
*
|
||||
* 1 for enabled, 0 for disabled.
|
||||
*
|
||||
* Default 0 (Disabled)
|
||||
*/
|
||||
#ifndef HID_OUT_REQUIRED
|
||||
#define HID_OUT_REQUIRED (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
||||
*
|
||||
@@ -1146,7 +1197,7 @@ enum USBEndpointNumber_In
|
||||
#ifdef MIDI
|
||||
ENDPOINT_NUMBER_IN_MIDI,
|
||||
#endif
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
ENDPOINT_NUMBER_IN_HID,
|
||||
#endif
|
||||
#ifdef IAP
|
||||
@@ -1173,6 +1224,9 @@ enum USBEndpointNumber_Out
|
||||
#ifdef IAP_EA_NATIVE_TRANS
|
||||
ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS,
|
||||
#endif
|
||||
#endif
|
||||
#if XUA_OR_STATIC_HID_ENABLED && HID_OUT_REQUIRED
|
||||
ENDPOINT_NUMBER_OUT_HID,
|
||||
#endif
|
||||
XUA_ENDPOINT_COUNT_OUT /* End marker */
|
||||
};
|
||||
|
||||
@@ -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
|
||||
^^^^
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
| +---------------------------------------------------------------------------------------------+
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -11,7 +11,7 @@ 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.3) \
|
||||
lib_adat(>=1.0.0)
|
||||
@@ -35,7 +35,7 @@ XCC_FLAGS_dfu.xc = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
||||
XCC_FLAGS_flash_interface.c = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
||||
XCC_FLAGS_flashlib_user.c = $(MODULE_XCC_FLAGS) -Os -mno-dual-issue
|
||||
|
||||
OPTIONAL_HEADERS += xua_conf.h
|
||||
OPTIONAL_HEADERS += xua_conf.h static_hid_report.h
|
||||
|
||||
EXPORT_INCLUDE_DIRS = api \
|
||||
src/core \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -96,7 +85,17 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
|
||||
#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 +113,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 +269,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
|
||||
}
|
||||
|
||||
@@ -290,9 +305,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 +367,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 +443,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)
|
||||
@@ -450,7 +483,6 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
||||
#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 +501,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 +558,6 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma xta endpoint "deliver_return"
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -681,13 +715,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)
|
||||
@@ -703,7 +737,15 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
#endif
|
||||
divide = mClk / (curSamFreq * numBits);
|
||||
|
||||
/* TODO; we should catch and handle the case when divide is 0. Currently design will lock up */
|
||||
//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");
|
||||
|
||||
}
|
||||
|
||||
#if (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.
|
||||
#include "xua.h"
|
||||
#if XUA_USB_EN
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "xud.h"
|
||||
#include "testct_byref.h"
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
#include "xua_hid_report.h"
|
||||
#include "user_hid.h"
|
||||
#include "xua_hid.h"
|
||||
@@ -134,7 +134,7 @@ void XUA_Buffer(
|
||||
c_clk_int,
|
||||
#endif
|
||||
c_sof, c_aud_ctl, p_off_mclk
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
, c_hid
|
||||
#endif
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
@@ -224,7 +224,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
XUD_ep ep_int = XUD_InitEp(c_ep_int);
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
XUD_ep ep_hid = XUD_InitEp(c_hid);
|
||||
#endif
|
||||
unsigned u_tmp;
|
||||
@@ -332,7 +332,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
|
||||
while (!hidIsReportDescriptorPrepared())
|
||||
;
|
||||
@@ -897,7 +897,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
/* HID Report Data */
|
||||
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||
hid_ready_flag = 0U;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2015-2021 XMOS LIMITED.
|
||||
// Copyright 2015-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#ifndef __DESCRIPTOR_DEFS_H__
|
||||
@@ -33,6 +33,7 @@
|
||||
#define ENDPOINT_ADDRESS_OUT_MIDI (ENDPOINT_NUMBER_OUT_MIDI)
|
||||
#define ENDPOINT_ADDRESS_OUT_IAP (ENDPOINT_NUMBER_OUT_IAP)
|
||||
#define ENDPOINT_ADDRESS_OUT_IAP_EA_NATIVE_TRANS (ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS)
|
||||
#define ENDPOINT_ADDRESS_OUT_HID (ENDPOINT_NUMBER_OUT_HID)
|
||||
|
||||
/* Interface numbers enum */
|
||||
enum USBInterfaceNumber
|
||||
@@ -60,7 +61,7 @@ enum USBInterfaceNumber
|
||||
INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS,
|
||||
#endif
|
||||
#endif
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
INTERFACE_NUMBER_HID,
|
||||
#endif
|
||||
INTERFACE_COUNT /* End marker */
|
||||
@@ -70,4 +71,8 @@ enum USBInterfaceNumber
|
||||
#define ENDPOINT_INT_INTERVAL_IN_HID 0x08
|
||||
#endif
|
||||
|
||||
#ifndef ENDPOINT_INT_INTERVAL_OUT_HID
|
||||
#define ENDPOINT_INT_INTERVAL_OUT_HID 0x08
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "xc_ptr.h"
|
||||
#include "xua_ep0_uacreqs.h"
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
#include "hid.h"
|
||||
#include "xua_hid.h"
|
||||
#include "xua_hid_report.h"
|
||||
@@ -442,6 +442,15 @@ void XUA_Endpoint0_setBcdDevice(unsigned short bcd) {
|
||||
#endif // AUDIO_CLASS == 1}
|
||||
}
|
||||
|
||||
#if defined(__static_hid_report_h_exists__)
|
||||
#define hidReportDescriptorLength (sizeof(hidReportDescriptorPtr))
|
||||
static unsigned char hidReportDescriptorPtr[] = {
|
||||
#include "static_hid_report.h"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(chanend, c_audioControl),
|
||||
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
|
||||
{
|
||||
@@ -513,11 +522,13 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
|
||||
|
||||
#endif // XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
#if XUA_HID_ENABLED
|
||||
hidReportInit();
|
||||
hidPrepareReportDescriptor();
|
||||
|
||||
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
||||
#endif
|
||||
unsigned char hidReportDescriptorLengthLo = hidReportDescriptorLength & 0xFF;
|
||||
unsigned char hidReportDescriptorLengthHi = (hidReportDescriptorLength & 0xFF00) >> 8;
|
||||
|
||||
@@ -528,6 +539,7 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
|
||||
|
||||
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ] = hidReportDescriptorLengthLo;
|
||||
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET + 1] = hidReportDescriptorLengthHi;
|
||||
|
||||
#endif // 0 < HID_CONTROLS
|
||||
|
||||
}
|
||||
@@ -731,7 +743,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
|
||||
|
||||
switch(sp.bRequest)
|
||||
{
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
case USB_GET_DESCRIPTOR:
|
||||
|
||||
/* Check what inteface request is for */
|
||||
@@ -746,15 +758,17 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
|
||||
{
|
||||
/* Return HID Descriptor */
|
||||
result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor,
|
||||
sizeof(hidDescriptor), sp.wLength);
|
||||
hidDescriptor[0], sp.wLength);
|
||||
}
|
||||
break;
|
||||
case HID_REPORT:
|
||||
{
|
||||
/* Return HID report descriptor */
|
||||
#if XUA_HID_ENABLED
|
||||
unsigned char* hidReportDescriptorPtr;
|
||||
hidReportDescriptorPtr = hidGetReportDescriptor();
|
||||
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
||||
#endif
|
||||
result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptorPtr,
|
||||
hidReportDescriptorLength, sp.wLength);
|
||||
}
|
||||
@@ -858,7 +872,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
if (interfaceNum == INTERFACE_NUMBER_HID)
|
||||
{
|
||||
result = HidInterfaceClassRequests(ep0_out, ep0_in, &sp);
|
||||
|
||||
@@ -787,10 +787,13 @@ typedef struct
|
||||
#endif
|
||||
#endif // IAP
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_Descriptor;
|
||||
USB_Descriptor_Endpoint_t HID_In_Endpoint;
|
||||
#if HID_OUT_REQUIRED
|
||||
USB_Descriptor_Endpoint_t HID_Out_Endpoint;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}__attribute__((packed)) USB_Config_Descriptor_Audio2_t;
|
||||
@@ -2208,14 +2211,14 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
#endif
|
||||
#endif /* IAP */
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
#include "xua_hid_descriptors.h"
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif /* (AUDIO_CLASS == 2) */
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
#if (AUDIO_CLASS ==1 )
|
||||
unsigned char hidDescriptor[] =
|
||||
{
|
||||
@@ -2330,14 +2333,14 @@ const unsigned num_freqs_a1 = MAX(3, (0
|
||||
#define DFU_INTERFACES_A1 0
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
/*
|
||||
* The value of HID_INTERFACE_BYTES must match the length of the descriptors defined in
|
||||
* - xua_hid_descriptor_contents.h
|
||||
* - xua_hid_endpoint_descriptor_contents.h and
|
||||
* - xua_hid_interface_descriptor_contents.h
|
||||
*/
|
||||
#define HID_INTERFACE_BYTES ( 9 + 9 + 7 )
|
||||
#define HID_INTERFACE_BYTES ( 9 + 9 + (7 * (1 + HID_OUT_REQUIRED))) // always IN
|
||||
#define HID_INTERFACES_A1 1
|
||||
#else
|
||||
#define HID_INTERFACE_BYTES 0
|
||||
@@ -2379,7 +2382,7 @@ const unsigned num_freqs_a1 = MAX(3, (0
|
||||
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
#define USB_HID_DESCRIPTOR_OFFSET (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + INTERFACE_DESCRIPTOR_BYTES)
|
||||
#endif
|
||||
|
||||
@@ -2893,7 +2896,7 @@ unsigned char cfgDesc_Audio1[] =
|
||||
offsetof(StringDescTable_t, ctrlStr)/sizeof(char *), /* 8 iInterface */
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
#include "xua_hid_descriptors.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -213,6 +213,9 @@ XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_EN
|
||||
#ifdef MIDI
|
||||
XUD_EPTYPE_BUL, /* MIDI */
|
||||
#endif
|
||||
#if HID_OUT_REQUIRED
|
||||
XUD_EPTYPE_INT,
|
||||
#endif
|
||||
#ifdef IAP
|
||||
XUD_EPTYPE_BUL, /* iAP */
|
||||
#ifdef IAP_EA_NATIVE_TRANS
|
||||
@@ -233,7 +236,7 @@ XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENAB
|
||||
#ifdef MIDI
|
||||
XUD_EPTYPE_BUL,
|
||||
#endif
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_OR_STATIC_HID_ENABLED
|
||||
XUD_EPTYPE_INT,
|
||||
#endif
|
||||
#ifdef IAP
|
||||
@@ -267,115 +270,6 @@ void xscope_user_init()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XUA_USB_EN
|
||||
/* Core USB Audio functions - must be called on the Tile connected to the USB Phy */
|
||||
void usb_audio_core(chanend c_mix_out
|
||||
#ifdef MIDI
|
||||
, chanend c_midi
|
||||
#endif
|
||||
#if (MIXER)
|
||||
, chanend c_mix_ctl
|
||||
#endif
|
||||
, chanend ?c_clk_int
|
||||
, chanend ?c_clk_ctl
|
||||
, client interface i_dfu ?dfuInterface
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
, client interface pll_ref_if i_pll_ref
|
||||
#endif
|
||||
VENDOR_REQUESTS_PARAMS_DEC_
|
||||
)
|
||||
{
|
||||
chan c_sof;
|
||||
chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */
|
||||
chan c_xud_in[ENDPOINT_COUNT_IN];
|
||||
chan c_aud_ctl;
|
||||
|
||||
#if (!MIXER)
|
||||
#define c_mix_ctl null
|
||||
#endif
|
||||
|
||||
#ifdef IAP_EA_NATIVE_TRANS
|
||||
chan c_EANativeTransport_ctrl;
|
||||
#else
|
||||
#define c_EANativeTransport_ctrl null
|
||||
#endif
|
||||
|
||||
par
|
||||
{
|
||||
{
|
||||
#ifdef XUD_PRIORITY_HIGH
|
||||
set_core_high_priority_on();
|
||||
#endif
|
||||
|
||||
/* Run UAC2.0 at high-speed, UAC1.0 at full-speed */
|
||||
unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS;
|
||||
|
||||
unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS;
|
||||
|
||||
/* USB interface core */
|
||||
XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN,
|
||||
c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned x;
|
||||
thread_speed();
|
||||
|
||||
/* Attach mclk count port to mclk clock-block (for feedback) */
|
||||
//set_port_clock(p_for_mclk_count, clk_audio_mclk);
|
||||
#if(AUDIO_IO_TILE != XUD_TILE)
|
||||
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb);
|
||||
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb);
|
||||
start_clock(clk_audio_mclk_usb);
|
||||
#else
|
||||
/* Clock port from same clock-block as I2S */
|
||||
/* TODO remove asm() */
|
||||
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
||||
asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));
|
||||
#endif
|
||||
/* Endpoint & audio buffering cores */
|
||||
XUA_Buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO],/* Audio Out*/
|
||||
#if (NUM_USB_CHAN_IN > 0)
|
||||
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */
|
||||
#endif
|
||||
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */
|
||||
#endif
|
||||
#ifdef MIDI
|
||||
c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4
|
||||
c_midi,
|
||||
#endif
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
/* Audio Interrupt - only used for interrupts on external clock change */
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT],
|
||||
c_clk_int,
|
||||
#endif
|
||||
c_sof, c_aud_ctl, p_for_mclk_count
|
||||
#if (HID_CONTROLS)
|
||||
, c_xud_in[ENDPOINT_NUMBER_IN_HID]
|
||||
#endif
|
||||
, c_mix_out
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
, i_pll_ref
|
||||
#endif
|
||||
);
|
||||
//:
|
||||
}
|
||||
|
||||
/* Endpoint 0 Core */
|
||||
{
|
||||
thread_speed();
|
||||
XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_);
|
||||
}
|
||||
|
||||
//:
|
||||
}
|
||||
}
|
||||
#endif /* XUA_USB_EN */
|
||||
|
||||
|
||||
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
void SpdifTxWrapper(chanend c_spdif_tx)
|
||||
{
|
||||
@@ -575,6 +469,20 @@ int main()
|
||||
|
||||
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
interface pll_ref_if i_pll_ref;
|
||||
#endif
|
||||
chan c_sof;
|
||||
chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */
|
||||
chan c_xud_in[ENDPOINT_COUNT_IN];
|
||||
chan c_aud_ctl;
|
||||
|
||||
#if (!MIXER)
|
||||
#define c_mix_ctl null
|
||||
#endif
|
||||
|
||||
#ifdef IAP_EA_NATIVE_TRANS
|
||||
chan c_EANativeTransport_ctrl;
|
||||
#else
|
||||
#define c_EANativeTransport_ctrl null
|
||||
#endif
|
||||
|
||||
USER_MAIN_DECLARATIONS
|
||||
@@ -597,27 +505,77 @@ int main()
|
||||
#endif
|
||||
#endif
|
||||
#if XUA_USB_EN
|
||||
/* Core USB audio task, buffering, USB etc */
|
||||
usb_audio_core(c_mix_out
|
||||
#ifdef MIDI
|
||||
, c_midi
|
||||
#endif
|
||||
#ifdef IAP
|
||||
, c_iap
|
||||
#ifdef IAP_EA_NATIVE_TRANS
|
||||
, c_ea_data
|
||||
#endif
|
||||
#endif
|
||||
#if (MIXER)
|
||||
, c_mix_ctl
|
||||
#endif
|
||||
, c_clk_int, c_clk_ctl, dfuInterface
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
, i_pll_ref
|
||||
#endif
|
||||
VENDOR_REQUESTS_PARAMS_
|
||||
|
||||
);
|
||||
/* Core USB task, buffering, USB etc */
|
||||
{
|
||||
#ifdef XUD_PRIORITY_HIGH
|
||||
set_core_high_priority_on();
|
||||
#endif
|
||||
|
||||
/* Run UAC2.0 at high-speed, UAC1.0 at full-speed */
|
||||
unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS;
|
||||
|
||||
unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS;
|
||||
|
||||
/* USB interface core */
|
||||
XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN,
|
||||
c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg);
|
||||
}
|
||||
|
||||
/* Core USB audio task, buffering, USB etc */
|
||||
{
|
||||
unsigned x;
|
||||
thread_speed();
|
||||
|
||||
/* Attach mclk count port to mclk clock-block (for feedback) */
|
||||
//set_port_clock(p_for_mclk_count, clk_audio_mclk);
|
||||
#if(AUDIO_IO_TILE != XUD_TILE)
|
||||
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb);
|
||||
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb);
|
||||
start_clock(clk_audio_mclk_usb);
|
||||
#else
|
||||
/* Clock port from same clock-block as I2S */
|
||||
/* TODO remove asm() */
|
||||
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
||||
asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));
|
||||
#endif
|
||||
/* Endpoint & audio buffering cores */
|
||||
XUA_Buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO],/* Audio Out*/
|
||||
#if (NUM_USB_CHAN_IN > 0)
|
||||
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */
|
||||
#endif
|
||||
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */
|
||||
#endif
|
||||
#ifdef MIDI
|
||||
c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4
|
||||
c_midi,
|
||||
#endif
|
||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||
/* Audio Interrupt - only used for interrupts on external clock change */
|
||||
c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT],
|
||||
c_clk_int,
|
||||
#endif
|
||||
c_sof, c_aud_ctl, p_for_mclk_count
|
||||
#if (XUA_HID_ENABLED)
|
||||
, c_xud_in[ENDPOINT_NUMBER_IN_HID]
|
||||
#endif
|
||||
, c_mix_out
|
||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||
, i_pll_ref
|
||||
#endif
|
||||
);
|
||||
//:
|
||||
}
|
||||
|
||||
/* Endpoint 0 Core */
|
||||
{
|
||||
thread_speed();
|
||||
XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_);
|
||||
}
|
||||
|
||||
#endif /* XUA_USB_EN */
|
||||
}
|
||||
|
||||
|
||||
@@ -100,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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2021 XMOS LIMITED.
|
||||
// Copyright 2013-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ typedef struct hidEvent_t {
|
||||
#define HID_MAX_DATA_BYTES ( 4 )
|
||||
#define HID_EVENT_INVALID_ID ( 0x100 )
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
|
||||
/**
|
||||
* \brief Get the data for the next HID Report
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2022 XMOS LIMITED.
|
||||
// Copyright 2019-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <stdint.h>
|
||||
#include <xs1.h>
|
||||
@@ -13,7 +13,7 @@
|
||||
#define DEBUG_PRINT_ENABLE_HID_XC 0
|
||||
#include "debug_print.h"
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod );
|
||||
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime );
|
||||
static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, const unsigned timeWithinPeriod );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2021-2022 XMOS LIMITED.
|
||||
// Copyright 2021-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include "xua_conf_full.h"
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#if XUA_HID_ENABLED
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// Copyright 2021-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
@@ -31,6 +31,19 @@
|
||||
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI, /* 5 wMaxPacketSize */
|
||||
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
|
||||
|
||||
#if (HID_OUT_REQUIRED)
|
||||
|
||||
/* HID Endpoint descriptor (OUT) */
|
||||
HID_ENDPOINT_DESCRIPTOR_LENGTH, /* 0 bLength */
|
||||
HID_ENDPOINT_DESCRIPTOR_TYPE, /* 1 bDescriptorType */
|
||||
ENDPOINT_ADDRESS_OUT_HID, /* 2 bEndpointAddress */
|
||||
HID_ENDPOINT_ATTRIBUTES, /* 3 bmAttributes (INTERRUPT) */
|
||||
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO, /* 4 wMaxPacketSize */
|
||||
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI, /* 5 wMaxPacketSize */
|
||||
ENDPOINT_INT_INTERVAL_OUT_HID, /* 6 bInterval */
|
||||
|
||||
#endif
|
||||
|
||||
#elif (AUDIO_CLASS == 2)
|
||||
|
||||
.HID_In_Endpoint =
|
||||
@@ -44,6 +57,21 @@
|
||||
.bInterval = ENDPOINT_INT_INTERVAL_IN_HID,
|
||||
},
|
||||
|
||||
#if (HID_OUT_REQUIRED)
|
||||
|
||||
.HID_Out_Endpoint =
|
||||
{
|
||||
/* Endpoint descriptor (OUT) */
|
||||
.bLength = sizeof(USB_Descriptor_Endpoint_t),
|
||||
.bDescriptorType = HID_ENDPOINT_DESCRIPTOR_TYPE,
|
||||
.bEndpointAddress = ENDPOINT_ADDRESS_OUT_HID,
|
||||
.bmAttributes = HID_ENDPOINT_ATTRIBUTES,
|
||||
.wMaxPacketSize = HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO,
|
||||
.bInterval = ENDPOINT_INT_INTERVAL_OUT_HID,
|
||||
},
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "Unknown Audio Class"
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// Copyright 2021-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
@@ -15,7 +15,8 @@
|
||||
#define HID_INTERFACE_DESCRIPTOR_LENGTH ( 0x09 ) /* Size of descriptor in Bytes */
|
||||
#define HID_INTERFACE_DESCRIPTOR_TYPE ( 0x04 ) /* Interface 0x04 */
|
||||
#define HID_INTERFACE_ALTERNATE_SETTING ( 0x00 ) /* Value used alternate interfaces using SetInterface Request */
|
||||
#define HID_INTERFACE_NUMBER_OF_ENDPOINTS ( 0x01 ) /* Number of endpoitns for this interface (excluding 0) */
|
||||
#define HID_INTERFACE_NUMBER_OF_ENDPOINTS ( 0x01 + HID_OUT_REQUIRED )
|
||||
/* Number of endpoints for this interface (excluding 0) */
|
||||
#define HID_INTERFACE_CLASS ( 0x03 )
|
||||
#define HID_INTERFACE_SUBCLASS ( 0x00 ) /* No boot device */
|
||||
#define HID_INTERFACE_PROTOCOL ( 0x00 )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2018-2022 XMOS LIMITED.
|
||||
# Copyright 2018-2023 XMOS LIMITED.
|
||||
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
#ifdef SIMULATION
|
||||
|
||||
@@ -41,7 +41,7 @@ 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);
|
||||
@@ -61,5 +61,4 @@ void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame
|
||||
master_mode_clk_setup();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user