forked from PAWPAW-Mirror/lib_xua
Merge pull request #363 from ed-xmos/feature/sw_pll_sync_ua
Use sw_pll for sync targets on XS3
This commit is contained in:
@@ -14,7 +14,7 @@ HEAD
|
|||||||
* CHANGED: QUAD_SPI_FLASH replaced by XUA_QUAD_SPI_FLASH (default: 1)
|
* CHANGED: QUAD_SPI_FLASH replaced by XUA_QUAD_SPI_FLASH (default: 1)
|
||||||
* CHANGED: UserBufferManagementInit() now takes a sample rate parameter
|
* CHANGED: UserBufferManagementInit() now takes a sample rate parameter
|
||||||
* CHANGED: xcore.ai targets use sigma-delta software PLL for clock recovery of
|
* CHANGED: xcore.ai targets use sigma-delta software PLL for clock recovery of
|
||||||
digital Rx streams by default.
|
digital Rx streams and synch USB audio by default.
|
||||||
|
|
||||||
* Changes to dependencies:
|
* Changes to dependencies:
|
||||||
|
|
||||||
|
|||||||
@@ -12,34 +12,42 @@
|
|||||||
#include "dfu_interface.h"
|
#include "dfu_interface.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "xua_clocking.h"
|
||||||
|
|
||||||
/** The audio driver thread.
|
/** The audio driver thread.
|
||||||
*
|
*
|
||||||
* This function drives I2S ports and handles samples to/from other digital
|
* This function drives I2S ports and handles samples to/from other digital
|
||||||
* I/O threads.
|
* I/O threads.
|
||||||
*
|
*
|
||||||
* \param c_aud Audio sample channel connected to the mixer() thread or the
|
* \param c_aud Audio sample channel connected to the mixer() thread or the
|
||||||
* decouple() thread
|
* decouple() thread
|
||||||
*
|
*
|
||||||
* \param clk_audio_mclk Nullable clockblock to be clocked from master clock
|
* \param clk_audio_mclk Nullable clockblock to be clocked from master clock
|
||||||
*
|
*
|
||||||
* \param clk_audio_bclk Nullable clockblock to be clocked from i2s bit clock
|
* \param clk_audio_bclk Nullable clockblock to be clocked from i2s bit clock
|
||||||
*
|
*
|
||||||
* \param p_mclk_in Master clock inport port (must be 1-bit)
|
* \param p_mclk_in Master clock inport port (must be 1-bit)
|
||||||
*
|
*
|
||||||
* \param p_lrclk Nullable port for I2S sample clock
|
* \param p_lrclk Nullable port for I2S sample clock
|
||||||
*
|
*
|
||||||
* \param p_bclk Nullable port for I2S bit
|
* \param p_bclk Nullable port for I2S bit clock
|
||||||
*
|
*
|
||||||
* \param p_i2s_dac Nullable array of ports for I2S data output lines
|
* \param p_i2s_dac Nullable array of ports for I2S data output lines
|
||||||
*
|
*
|
||||||
* \param p_i2s_adc Nullable array of ports for I2S data input lines
|
* \param p_i2s_adc Nullable array of ports for I2S data input lines
|
||||||
*
|
*
|
||||||
* \param c_spdif_tx Channel connected to S/PDIF transmiter core from lib_spdif
|
* \param i_SoftPll Interface to software PLL task
|
||||||
*
|
*
|
||||||
* \param c_dig Channel connected to the clockGen() thread for
|
* \param c_spdif_tx Channel connected to S/PDIF transmitter core from lib_spdif
|
||||||
* receiving/transmitting samples
|
|
||||||
*
|
*
|
||||||
* \param c_mclk_change Channel notifying clockgen of an mclk frequency change
|
* \param c_dig Channel connected to the clockGen() thread for
|
||||||
|
* receiving/transmitting samples
|
||||||
|
*
|
||||||
|
* \param c_audio_rate_change Channel notifying ep_buffer of an mclk frequency change and sync for stable clock
|
||||||
|
*
|
||||||
|
* \param dfuInterface Interface supporting DFU methods
|
||||||
|
*
|
||||||
|
* \param c_pdm_in Channel for receiving decimated PDM samples
|
||||||
*/
|
*/
|
||||||
void XUA_AudioHub(chanend ?c_aud,
|
void XUA_AudioHub(chanend ?c_aud,
|
||||||
clock ?clk_audio_mclk,
|
clock ?clk_audio_mclk,
|
||||||
@@ -54,12 +62,14 @@ void XUA_AudioHub(chanend ?c_aud,
|
|||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__))
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__))
|
||||||
, chanend c_dig
|
, chanend c_dig
|
||||||
, chanend c_mclk_change
|
|
||||||
#endif
|
#endif
|
||||||
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__))
|
||||||
|
, chanend c_audio_rate_change
|
||||||
|
#endif
|
||||||
|
#if (((XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)) || defined(__DOXYGEN__))
|
||||||
, server interface i_dfu ?dfuInterface
|
, server interface i_dfu ?dfuInterface
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_NUM_PDM_MICS > 0)
|
#if (XUA_NUM_PDM_MICS > 0 || defined(__DOXYGEN__))
|
||||||
, chanend c_pdm_in
|
, chanend c_pdm_in
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
@@ -79,8 +89,29 @@ void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode,
|
|||||||
|
|
||||||
#endif // __XC__
|
#endif // __XC__
|
||||||
|
|
||||||
void UserBufferManagementInit(unsigned samFreq);
|
/**
|
||||||
|
* @brief User buffer management code
|
||||||
|
*
|
||||||
|
* This function is called at the sample rate of the USB Audio stack (e.g,. 48 kHz) and between the two parameter arrays
|
||||||
|
* contain a full multi-channel audio-frame. The first array carries all the data that has been received from the USB host
|
||||||
|
* and is to be presented to the audio interfaces. The second array carries all the data received from the interfaces and
|
||||||
|
* is to be presented to the USB host. The user can chose to intercept and overwrite the samples stored in these arrays.
|
||||||
|
*
|
||||||
|
* \param sampsFromUsbToAudio Samples received from USB host and to be presented to audio interfaces
|
||||||
|
*
|
||||||
|
* \param sampsFromAudioToUsb Samples received from the audio interfaces and to be presented to the USB host
|
||||||
|
*/
|
||||||
void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]);
|
void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User buffer managment init code
|
||||||
|
*
|
||||||
|
* This function is called once, before the first call to UserBufferManagement(), and can be used to initialise any
|
||||||
|
* related user state
|
||||||
|
*
|
||||||
|
* \param sampFreq The initial sample frequency
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void UserBufferManagementInit(unsigned sampFreq);
|
||||||
|
|
||||||
#endif // _XUA_AUDIOHUB_H_
|
#endif // _XUA_AUDIOHUB_H_
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2011-2022 XMOS LIMITED.
|
// Copyright 2011-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#ifndef __XUA_BUFFER_H__
|
#ifndef _XUA_BUFFER_H_
|
||||||
#define __XUA_BUFFER_H__
|
#define _XUA_BUFFER_H_
|
||||||
|
|
||||||
#if __XC__
|
#if __XC__
|
||||||
|
|
||||||
@@ -13,19 +13,21 @@
|
|||||||
* Most of the chanend parameters to the function should be connected to
|
* Most of the chanend parameters to the function should be connected to
|
||||||
* XUD_Manager(). The uses two cores.
|
* XUD_Manager(). The uses two cores.
|
||||||
*
|
*
|
||||||
* \param c_aud_out Audio OUT endpoint channel connected to the XUD
|
* \param c_aud_out Audio OUT endpoint channel connected to the XUD
|
||||||
* \param c_aud_in Audio IN endpoint channel connected to the XUD
|
* \param c_aud_in Audio IN endpoint channel connected to the XUD
|
||||||
* \param c_aud_fb Audio feedback endpoint channel connected to the XUD
|
* \param c_aud_fb Audio feedback endpoint channel connected to the XUD
|
||||||
* \param c_midi_from_host MIDI OUT endpoint channel connected to the XUD
|
* \param c_midi_from_host MIDI OUT endpoint channel connected to the XUD
|
||||||
* \param c_midi_to_host MIDI IN endpoint channel connected to the XUD
|
* \param c_midi_to_host MIDI IN endpoint channel connected to the XUD
|
||||||
* \param c_midi Channel connected to MIDI core
|
* \param c_midi Channel connected to MIDI core
|
||||||
* \param c_int Audio clocking interrupt endpoint channel connected to the XUD
|
* \param c_int Audio clocking interrupt endpoint channel connected to the XUD
|
||||||
* \param c_clk_int Optional chanend connected to the clockGen() thread if present
|
* \param c_clk_int Optional chanend connected to the clockGen() thread if present
|
||||||
* \param c_sof Start of frame channel connected to the XUD
|
* \param c_sof Start of frame channel connected to the XUD
|
||||||
* \param c_aud_ctl Audio control channel connected to Endpoint0()
|
* \param c_aud_ctl Audio control channel connected to Endpoint0()
|
||||||
* \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself)
|
* \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself)
|
||||||
* \param c_aud Channel connected to XUA_AudioHub() core
|
* \param c_aud Channel connected to XUA_AudioHub() core
|
||||||
* \param i_pll_ref Interface to task that toggles reference pin to CS2100
|
* \param c_audio_rate_change Channel to notify and synchronise on audio rate change
|
||||||
|
* \param i_pll_ref Interface to task that toggles reference pin to CS2100
|
||||||
|
* \param c_swpll_update Channel connected to software PLL task. Expects master clock counts based on USB frames.
|
||||||
*/
|
*/
|
||||||
void XUA_Buffer(
|
void XUA_Buffer(
|
||||||
chanend c_aud_out,
|
chanend c_aud_out,
|
||||||
@@ -38,7 +40,7 @@ void XUA_Buffer(
|
|||||||
#if defined(MIDI) || defined(__DOXYGEN__)
|
#if defined(MIDI) || defined(__DOXYGEN__)
|
||||||
chanend c_midi_from_host,
|
chanend c_midi_from_host,
|
||||||
chanend c_midi_to_host,
|
chanend c_midi_to_host,
|
||||||
chanend c_midi,
|
chanend c_midi,
|
||||||
#endif
|
#endif
|
||||||
#if XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__)
|
#if XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__)
|
||||||
chanend ?c_int,
|
chanend ?c_int,
|
||||||
@@ -51,8 +53,14 @@ void XUA_Buffer(
|
|||||||
, chanend c_hid
|
, chanend c_hid
|
||||||
#endif
|
#endif
|
||||||
, chanend c_aud
|
, chanend c_aud
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOXYGEN__)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOYXGEN__)
|
||||||
|
, chanend c_audio_rate_change
|
||||||
|
#if (!XUA_USE_SW_PLL) || defined(__DOXYGEN__)
|
||||||
, client interface pll_ref_if i_pll_ref
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
|
#if (XUA_USE_SW_PLL) || defined(__DOXYGEN__)
|
||||||
|
, chanend c_swpll_update
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -66,7 +74,7 @@ void XUA_Buffer_Ep(chanend c_aud_out,
|
|||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
chanend c_midi_from_host,
|
chanend c_midi_from_host,
|
||||||
chanend c_midi_to_host,
|
chanend c_midi_to_host,
|
||||||
chanend c_midi,
|
chanend c_midi,
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN)
|
||||||
chanend ?c_int,
|
chanend ?c_int,
|
||||||
@@ -81,10 +89,17 @@ void XUA_Buffer_Ep(chanend c_aud_out,
|
|||||||
#ifdef CHAN_BUFF_CTRL
|
#ifdef CHAN_BUFF_CTRL
|
||||||
, chanend c_buff_ctrl
|
, chanend c_buff_ctrl
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOXYGEN__)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOYXGEN__)
|
||||||
|
, chanend c_audio_rate_change
|
||||||
|
#if (!XUA_USE_SW_PLL) || defined(__DOXYGEN__)
|
||||||
, client interface pll_ref_if i_pll_ref
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
|
#if (XUA_USE_SW_PLL) || defined(__DOXYGEN__)
|
||||||
|
, chanend c_swpll_update
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/** Manage the data transfer between the USB audio buffer and the
|
/** Manage the data transfer between the USB audio buffer and the
|
||||||
* Audio I/O driver.
|
* Audio I/O driver.
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
|
|
||||||
|
#include "sw_pll_wrapper.h"
|
||||||
|
|
||||||
interface pll_ref_if
|
interface pll_ref_if
|
||||||
{
|
{
|
||||||
void toggle();
|
void toggle();
|
||||||
@@ -18,17 +20,18 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_sync);
|
|||||||
|
|
||||||
/** Clock generation and digital audio I/O handling.
|
/** Clock generation and digital audio I/O handling.
|
||||||
*
|
*
|
||||||
* \param c_spdif_rx channel connected to S/PDIF receive thread
|
* \param c_spdif_rx channel connected to S/PDIF receive thread
|
||||||
* \param c_adat_rx channel connect to ADAT receive thread
|
* \param c_adat_rx channel connect to ADAT receive thread
|
||||||
* \param i_pll_ref interface to taslk that outputs clock signal to drive external frequency synthesizer
|
* \param i_pll_ref interface to taslk that outputs clock signal to drive external frequency synthesizer
|
||||||
* \param c_audio channel connected to the audio() thread
|
* \param c_audio channel connected to the audio() thread
|
||||||
* \param c_clk_ctl channel connected to Endpoint0() for configuration of the
|
* \param c_clk_ctl channel connected to Endpoint0() for configuration of the
|
||||||
* clock
|
* clock
|
||||||
* \param c_clk_int channel connected to the decouple() thread for clock
|
* \param c_clk_int channel connected to the decouple() thread for clock
|
||||||
* interrupts
|
* interrupts
|
||||||
|
* \param c_audio_rate_change channel to notify of master clock change
|
||||||
* \param p_for_mclk_count_aud port used for counting mclk and providing a timestamp
|
* \param p_for_mclk_count_aud port used for counting mclk and providing a timestamp
|
||||||
|
* \param c_sw_pll channel used to communicate with software PLL task
|
||||||
*
|
*
|
||||||
* \param c_mclk_change channel to notify of master clock change
|
|
||||||
*/
|
*/
|
||||||
void clockGen( streaming chanend ?c_spdif_rx,
|
void clockGen( streaming chanend ?c_spdif_rx,
|
||||||
chanend ?c_adat_rx,
|
chanend ?c_adat_rx,
|
||||||
@@ -36,7 +39,12 @@ void clockGen( streaming chanend ?c_spdif_rx,
|
|||||||
chanend c_audio,
|
chanend c_audio,
|
||||||
chanend c_clk_ctl,
|
chanend c_clk_ctl,
|
||||||
chanend c_clk_int,
|
chanend c_clk_int,
|
||||||
port ?p_for_mclk_count_aud,
|
chanend c_audio_rate_change
|
||||||
chanend c_mclk_change);
|
#if XUA_USE_SW_PLL
|
||||||
|
, port p_for_mclk_count_aud
|
||||||
|
, chanend c_sw_pll
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2023 XMOS LIMITED.
|
// Copyright 2011-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
/*
|
/*
|
||||||
* @brief Defines relating to device configuration and customisation of lib_xua
|
* @brief Defines relating to device configuration and customisation of lib_xua
|
||||||
@@ -11,56 +11,55 @@
|
|||||||
#include "xua_conf.h"
|
#include "xua_conf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default tile arrangement */
|
/*
|
||||||
|
* Tile arrangement defines
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of audio I/O. Default: 0
|
* @brief Location (tile) of audio I/O. Default: 0
|
||||||
*/
|
*/
|
||||||
#ifndef AUDIO_IO_TILE
|
#ifndef AUDIO_IO_TILE
|
||||||
#define AUDIO_IO_TILE (0)
|
#define AUDIO_IO_TILE (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of audio I/O. Default: 0
|
* @brief Location (tile) of audio I/O. Default: 0
|
||||||
*/
|
*/
|
||||||
#ifndef XUD_TILE
|
#ifndef XUD_TILE
|
||||||
#define XUD_TILE (0)
|
#define XUD_TILE (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of MIDI I/O. Default: AUDIO_IO_TILE
|
* @brief Location (tile) of MIDI I/O. Default: AUDIO_IO_TILE
|
||||||
*/
|
*/
|
||||||
#ifndef MIDI_TILE
|
#ifndef MIDI_TILE
|
||||||
#define MIDI_TILE AUDIO_IO_TILE
|
#define MIDI_TILE AUDIO_IO_TILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of SPDIF Tx. Default: AUDIO_IO_TILE
|
* @brief Location (tile) of SPDIF Tx. Default: AUDIO_IO_TILE
|
||||||
*/
|
*/
|
||||||
#ifndef SPDIF_TX_TILE
|
#ifndef SPDIF_TX_TILE
|
||||||
#define SPDIF_TX_TILE AUDIO_IO_TILE
|
#define SPDIF_TX_TILE AUDIO_IO_TILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of PDM Rx. Default: AUDIO_IO_TILE
|
* @brief Location (tile) of PDM Rx. Default: AUDIO_IO_TILE
|
||||||
*/
|
*/
|
||||||
#ifndef PDM_TILE
|
#ifndef PDM_TILE
|
||||||
#define PDM_TILE AUDIO_IO_TILE
|
#define PDM_TILE AUDIO_IO_TILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Location (tile) of reference signal to CS2100. Default: AUDIO_IO_TILE
|
* @brief Location (tile) of reference signal to CS2100. Default: AUDIO_IO_TILE
|
||||||
*/
|
*/
|
||||||
#ifndef PLL_REF_TILE
|
#ifndef PLL_REF_TILE
|
||||||
#define PLL_REF_TILE AUDIO_IO_TILE
|
#define PLL_REF_TILE AUDIO_IO_TILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @brief Disable USB functionalty just leaving AudioHub
|
* Channel based defines
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_USB_EN
|
|
||||||
#define XUA_USB_EN (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of input channels (device to host). Default: NONE (Must be defined by app)
|
* @brief Number of input channels (device to host). Default: NONE (Must be defined by app)
|
||||||
@@ -79,18 +78,57 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of DSD output channels. Default: 0 (disabled)
|
* @brief Number of PDM microphones in the design.
|
||||||
|
*
|
||||||
|
* Default: 0
|
||||||
|
*/
|
||||||
|
#ifndef XUA_NUM_PDM_MICS
|
||||||
|
#define XUA_NUM_PDM_MICS (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of DSD output channels.
|
||||||
|
*
|
||||||
|
* Default: 0 (disabled)
|
||||||
*/
|
*/
|
||||||
#if defined(DSD_CHANS_DAC) && (DSD_CHANS_DAC != 0)
|
#if defined(DSD_CHANS_DAC) && (DSD_CHANS_DAC != 0)
|
||||||
#if defined(NATIVE_DSD) && (NATIVE_DSD == 0)
|
#if defined(NATIVE_DSD) && (NATIVE_DSD == 0)
|
||||||
#undef NATIVE_DSD
|
#undef NATIVE_DSD
|
||||||
#else
|
#else
|
||||||
#define NATIVE_DSD (1) /* Always enable Native DSD when DSD mode is enabled */
|
#define NATIVE_DSD 1 /* Always enable Native DSD when DSD mode is enabled */
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DSD_CHANS_DAC (0)
|
#define DSD_CHANS_DAC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of I2S channesl to DAC/CODEC. Must be a multiple of 2.
|
||||||
|
*
|
||||||
|
* Default: NONE (Must be defined by app)
|
||||||
|
*/
|
||||||
|
#ifndef I2S_CHANS_DAC
|
||||||
|
#error I2S_CHANS_DAC not defined
|
||||||
|
#define I2S_CHANS_DAC 2 /* Define anyway for doxygen */
|
||||||
|
#else
|
||||||
|
#define I2S_WIRES_DAC (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of I2S channels from ADC/CODEC. Must be a multiple of 2.
|
||||||
|
*
|
||||||
|
* Default: NONE (Must be defined by app)
|
||||||
|
*/
|
||||||
|
#ifndef I2S_CHANS_ADC
|
||||||
|
#error I2S_CHANS_ADC not defined
|
||||||
|
#define I2S_CHANS_ADC 2 /* Define anyway for doxygen */
|
||||||
|
#else
|
||||||
|
#define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines relating to the interface to external audio hardware i.e. DAC/ADC
|
||||||
|
*/
|
||||||
|
|
||||||
#define XUA_PCM_FORMAT_I2S (0)
|
#define XUA_PCM_FORMAT_I2S (0)
|
||||||
#define XUA_PCM_FORMAT_TDM (1)
|
#define XUA_PCM_FORMAT_TDM (1)
|
||||||
/**
|
/**
|
||||||
@@ -103,7 +141,7 @@
|
|||||||
#error Bad value for XUA_PCM_FORMAT
|
#error Bad value for XUA_PCM_FORMAT
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define XUA_PCM_FORMAT XUA_PCM_FORMAT_I2S
|
#define XUA_PCM_FORMAT XUA_PCM_FORMAT_I2S
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,89 +152,12 @@
|
|||||||
**/
|
**/
|
||||||
#ifndef I2S_CHANS_PER_FRAME
|
#ifndef I2S_CHANS_PER_FRAME
|
||||||
#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM)
|
||||||
#define I2S_CHANS_PER_FRAME (8)
|
#define I2S_CHANS_PER_FRAME 8
|
||||||
#else
|
#else
|
||||||
#define I2S_CHANS_PER_FRAME (2)
|
#define I2S_CHANS_PER_FRAME 2
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Number of IS2 channesl to DAC/CODEC. Must be a multiple of 2.
|
|
||||||
*
|
|
||||||
* Default: NONE (Must be defined by app)
|
|
||||||
*/
|
|
||||||
#ifndef I2S_CHANS_DAC
|
|
||||||
#error I2S_CHANS_DAC not defined
|
|
||||||
#define I2S_CHANS_DAC 2 /* Define anyway for doxygen */
|
|
||||||
#else
|
|
||||||
#define I2S_WIRES_DAC (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Number of I2S channels from ADC/CODEC. Must be a multiple of 2.
|
|
||||||
*
|
|
||||||
* Default: NONE (Must be defined by app)
|
|
||||||
*/
|
|
||||||
#ifndef I2S_CHANS_ADC
|
|
||||||
#error I2S_CHANS_ADC not defined
|
|
||||||
#define I2S_CHANS_ADC 2 /* Define anyway for doxygen */
|
|
||||||
#else
|
|
||||||
#define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Ratio of the I2S sample rate to the USB Audio sample rate. Up and
|
|
||||||
* down-sampling will be enabled as necessary when the rates differ.
|
|
||||||
*
|
|
||||||
* Default: 1 i.e. I2S and USB Audio are running at the same sample rate.
|
|
||||||
*/
|
|
||||||
#ifndef AUD_TO_USB_RATIO
|
|
||||||
#define AUD_TO_USB_RATIO (1)
|
|
||||||
#else
|
|
||||||
#if (AUD_TO_USB_RATIO != 3) && (AUD_TO_USB_RATIO != 1)
|
|
||||||
#error Unsupported I2S to USB Audio sample rate ratio
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Ratio of the I2S sample rate to the PDM microphone decimator sample
|
|
||||||
* rate.
|
|
||||||
*
|
|
||||||
* Default: 1 i.e. I2S and PDM microphone decimators are running at the same sample rate.
|
|
||||||
*/
|
|
||||||
#ifndef AUD_TO_MICS_RATIO
|
|
||||||
#define AUD_TO_MICS_RATIO (1)
|
|
||||||
#else
|
|
||||||
#if (AUD_TO_MICS_RATIO != 3) && (AUD_TO_MICS_RATIO != 1)
|
|
||||||
#error Unsupported I2S to PDM microphone decimator sample rate ratio
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Only downsample one channel per input I2S frame.
|
|
||||||
*
|
|
||||||
* Default: 0 i.e. mono mode is disabled, all input channels will be downsampled.
|
|
||||||
*/
|
|
||||||
#ifndef I2S_DOWNSAMPLE_MONO_IN
|
|
||||||
#define I2S_DOWNSAMPLE_MONO_IN (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Number of incoming (device to host) I2S channels to downsample.
|
|
||||||
*
|
|
||||||
* Default: The number of I2S incoming channels, or half this if mono downsampling is enabled.
|
|
||||||
*/
|
|
||||||
#if (I2S_DOWNSAMPLE_MONO_IN == 1)
|
|
||||||
#define I2S_DOWNSAMPLE_CHANS_IN (I2S_CHANS_ADC / 2)
|
|
||||||
#if ((I2S_DOWNSAMPLE_FACTOR_IN > 1) && (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM))
|
|
||||||
#error Mono I2S input downsampling is not avaliable in TDM mode
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
* @brief Number of bits per channel for I2S/TDM. Supported values: 16/32-bit.
|
||||||
*
|
*
|
||||||
@@ -211,21 +172,82 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Max supported sample frequency for device (Hz). Default: 192000
|
* @brief Ratio of the I2S sample rate to the USB Audio sample rate. Up and
|
||||||
|
* down-sampling will be enabled as necessary when the rates differ.
|
||||||
|
*
|
||||||
|
* Default: 1 i.e. I2S and USB Audio are running at the same sample rate.
|
||||||
|
*/
|
||||||
|
#ifndef AUD_TO_USB_RATIO
|
||||||
|
#define AUD_TO_USB_RATIO (1)
|
||||||
|
#else
|
||||||
|
#if (AUD_TO_USB_RATIO != 3) && (AUD_TO_USB_RATIO != 1)
|
||||||
|
#error Unsupported I2S to USB Audio sample rate ratio
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ratio of the I2S sample rate to the PDM microphone decimator sample
|
||||||
|
* rate.
|
||||||
|
*
|
||||||
|
* Default: 1 i.e. I2S and PDM microphone decimators are running at the same sample rate.
|
||||||
|
*/
|
||||||
|
#ifndef AUD_TO_MICS_RATIO
|
||||||
|
#define AUD_TO_MICS_RATIO (1)
|
||||||
|
#else
|
||||||
|
#if (AUD_TO_MICS_RATIO != 3) && (AUD_TO_MICS_RATIO != 1)
|
||||||
|
#error Unsupported I2S to PDM microphone decimator sample rate ratio
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Only downsample one channel per input I2S frame.
|
||||||
|
*
|
||||||
|
* Default: 0 i.e. mono mode is disabled, all input channels will be downsampled.
|
||||||
|
*/
|
||||||
|
#ifndef I2S_DOWNSAMPLE_MONO_IN
|
||||||
|
#define I2S_DOWNSAMPLE_MONO_IN (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of incoming (device to host) I2S channels to downsample.
|
||||||
|
*
|
||||||
|
* Default: The number of I2S incoming channels, or half this if mono downsampling is enabled.
|
||||||
|
*/
|
||||||
|
#if (I2S_DOWNSAMPLE_MONO_IN == 1)
|
||||||
|
#define I2S_DOWNSAMPLE_CHANS_IN (I2S_CHANS_ADC / 2)
|
||||||
|
#if ((I2S_DOWNSAMPLE_FACTOR_IN > 1) && (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM))
|
||||||
|
#error Mono I2S input downsampling is not avaliable in TDM mode
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clocking related defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Max supported sample frequency for device (Hz).
|
||||||
|
*
|
||||||
|
* Default: 192000Hz
|
||||||
*/
|
*/
|
||||||
#ifndef MAX_FREQ
|
#ifndef MAX_FREQ
|
||||||
#define MAX_FREQ (192000)
|
#define MAX_FREQ (192000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Min supported sample frequency for device (Hz). Default 44100
|
* @brief Min supported sample frequency for device (Hz).
|
||||||
|
*
|
||||||
|
* Default: 44100Hz
|
||||||
*/
|
*/
|
||||||
#ifndef MIN_FREQ
|
#ifndef MIN_FREQ
|
||||||
#define MIN_FREQ (44100)
|
#define MIN_FREQ (44100)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Master clock defines for 44100 rates (in Hz). Default: NONE (Must be defined by app)
|
* @brief Master clock defines for 44100 rates (in Hz).
|
||||||
|
*
|
||||||
|
* Default: NONE (Must be defined by app)
|
||||||
*/
|
*/
|
||||||
#ifndef MCLK_441
|
#ifndef MCLK_441
|
||||||
#error MCLK_441 not defined
|
#error MCLK_441 not defined
|
||||||
@@ -233,13 +255,29 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Master clock defines for 48000 rates (in Hz). Default: NONE (Must be defined by app)
|
* @brief Master clock defines for 48000 rates (in Hz).
|
||||||
|
*
|
||||||
|
* Default: NONE (Must be defined by app)
|
||||||
*/
|
*/
|
||||||
#ifndef MCLK_48
|
#ifndef MCLK_48
|
||||||
#error MCLK_48 not defined
|
#error MCLK_48 not defined
|
||||||
#define MCLK_48 (256 * 48000) /* Define anyway for doygen */
|
#define MCLK_48 (256 * 48000) /* Define anyway for doygen */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable/disable the use of the secondary/application PLL for generating and recovering master-clocks.
|
||||||
|
* Only available on xcore.ai devices.
|
||||||
|
*
|
||||||
|
* Default: Enabled (for xcore.ai devices)
|
||||||
|
*/
|
||||||
|
#ifndef XUA_USE_SW_PLL
|
||||||
|
#if defined(__XS3A__)
|
||||||
|
#define XUA_USE_SW_PLL (1)
|
||||||
|
#else
|
||||||
|
#define XUA_USE_SW_PLL (0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default device sample frequency. A safe default should be used.
|
* @brief Default device sample frequency. A safe default should be used.
|
||||||
*
|
*
|
||||||
@@ -249,10 +287,25 @@
|
|||||||
#define DEFAULT_FREQ (MIN_FREQ)
|
#define DEFAULT_FREQ (MIN_FREQ)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Audio Class Defines */
|
#define DEFAULT_MCLK (((DEFAULT_FREQ % 7350) == 0) ? MCLK_441 : MCLK_48)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB Audio Class Version.
|
* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
||||||
|
*
|
||||||
|
* 0: XMOS is I2S master. 1: CODEC is I2s master.
|
||||||
|
*
|
||||||
|
* Default: 0 (XMOS is master)
|
||||||
|
*/
|
||||||
|
#ifndef CODEC_MASTER
|
||||||
|
#define CODEC_MASTER (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Audio Class defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB Audio Class Version
|
||||||
*
|
*
|
||||||
* Default: 2 (Audio Class version 2.0)
|
* Default: 2 (Audio Class version 2.0)
|
||||||
*/
|
*/
|
||||||
@@ -261,9 +314,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Whether or not to fall back to Audio Class 1.0 in USB Full-speed.
|
* @brief Enable/disable fall back to Audio Class 1.0 in USB Full-speed.
|
||||||
*
|
*
|
||||||
* Default: 0 (Disabled i.e. do not fall back to UAC 1.0
|
* Default: Disabled
|
||||||
*/
|
*/
|
||||||
#ifndef AUDIO_CLASS_FALLBACK
|
#ifndef AUDIO_CLASS_FALLBACK
|
||||||
#define AUDIO_CLASS_FALLBACK (0)
|
#define AUDIO_CLASS_FALLBACK (0)
|
||||||
@@ -278,7 +331,7 @@
|
|||||||
#if (AUDIO_CLASS == 2)
|
#if (AUDIO_CLASS == 2)
|
||||||
/* Whether to run in Audio Class 2.0 mode in USB Full-speed */
|
/* Whether to run in Audio Class 2.0 mode in USB Full-speed */
|
||||||
#if !defined(FULL_SPEED_AUDIO_2) && (AUDIO_CLASS_FALLBACK == 0)
|
#if !defined(FULL_SPEED_AUDIO_2) && (AUDIO_CLASS_FALLBACK == 0)
|
||||||
#define FULL_SPEED_AUDIO_2 (1) /* Default to falling back to UAC2 */
|
#define FULL_SPEED_AUDIO_2 1 /* Default to falling back to UAC2 */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -295,16 +348,17 @@
|
|||||||
#error AUDIO_CLASS set to 1 and FULL_SPEED_AUDIO_2 enabled!
|
#error AUDIO_CLASS set to 1 and FULL_SPEED_AUDIO_2 enabled!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
/* Feature defines */
|
* Feature defines
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of PDM microphones in the design.
|
* @brief Disable USB functionalty just leaving AudioHub
|
||||||
*
|
*
|
||||||
* Default: None
|
* Default: Enabled
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_NUM_PDM_MICS
|
#ifndef XUA_USB_EN
|
||||||
#define XUA_NUM_PDM_MICS (0)
|
#define XUA_USB_EN (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,18 +372,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a frame of microphone data samples.
|
* @brief Size of a frame of microphone data samples. Default: 1
|
||||||
*
|
|
||||||
* Default: 1
|
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_MIC_FRAME_SIZE
|
#ifndef XUA_MIC_FRAME_SIZE
|
||||||
#define XUA_MIC_FRAME_SIZE (1)
|
#define XUA_MIC_FRAME_SIZE (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable MIDI functionality including buffering, descriptors etc.
|
* @brief Enable MIDI functionality including buffering, descriptors etc. Default: DISABLED
|
||||||
*
|
|
||||||
* Default: 0 (Disabled)
|
|
||||||
*/
|
*/
|
||||||
#ifndef MIDI
|
#ifndef MIDI
|
||||||
#define MIDI (0)
|
#define MIDI (0)
|
||||||
@@ -350,7 +400,7 @@
|
|||||||
* @brief Enables SPDIF Tx. Default: 0 (Disabled)
|
* @brief Enables SPDIF Tx. Default: 0 (Disabled)
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_SPDIF_TX_EN
|
#ifndef XUA_SPDIF_TX_EN
|
||||||
#define XUA_SPDIF_TX_EN (0)
|
#define XUA_SPDIF_TX_EN (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -359,16 +409,14 @@
|
|||||||
* Default: 0 (i.e. channels 0 & 1)
|
* Default: 0 (i.e. channels 0 & 1)
|
||||||
* */
|
* */
|
||||||
#ifndef SPDIF_TX_INDEX
|
#ifndef SPDIF_TX_INDEX
|
||||||
#define SPDIF_TX_INDEX (0)
|
#define SPDIF_TX_INDEX (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables ADAT Tx.
|
* @brief Enables ADAT Tx. Default: 0 (Disabled)
|
||||||
*
|
|
||||||
* Default: 0 (Disabled)
|
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_ADAT_TX_EN
|
#ifndef XUA_ADAT_TX_EN
|
||||||
#define XUA_ADAT_TX_EN (0)
|
#define XUA_ADAT_TX_EN (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -377,25 +425,21 @@
|
|||||||
* Default: 0 (i.e. channels [0:7])
|
* Default: 0 (i.e. channels [0:7])
|
||||||
* */
|
* */
|
||||||
#ifndef ADAT_TX_INDEX
|
#ifndef ADAT_TX_INDEX
|
||||||
#define ADAT_TX_INDEX (0)
|
#define ADAT_TX_INDEX (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables SPDIF Rx.
|
* @brief Enables SPDIF Rx. Default: 0 (Disabled)
|
||||||
*
|
|
||||||
* Default: 0 (Disabled)
|
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_SPDIF_RX_EN
|
#ifndef XUA_SPDIF_RX_EN
|
||||||
#define XUA_SPDIF_RX_EN (0)
|
#define XUA_SPDIF_RX_EN (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables ADAT Rx.
|
* @brief Enables ADAT Rx. Default: 0 (Disabled)
|
||||||
*
|
|
||||||
* Default: 0 (Disabled)
|
|
||||||
*/
|
*/
|
||||||
#ifndef XUA_ADAT_RX_EN
|
#ifndef XUA_ADAT_RX_EN
|
||||||
#define XUA_ADAT_RX_EN (0)
|
#define XUA_ADAT_RX_EN (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -450,20 +494,11 @@
|
|||||||
* Default: 1 (Enabled)
|
* Default: 1 (Enabled)
|
||||||
*/
|
*/
|
||||||
#if !defined(XUA_DFU_EN)
|
#if !defined(XUA_DFU_EN)
|
||||||
#define XUA_DFU_EN (1)
|
#define XUA_DFU_EN (1)
|
||||||
#elif defined(XUA_DFU_EN) && (XUA_DFU_EN == 0)
|
#elif defined(XUA_DFU_EN) && (XUA_DFU_EN == 0)
|
||||||
#undef XUA_DFU_EN
|
#undef XUA_DFU_EN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Use a QSPI (rather than SPI) flash for DFU (and boot)
|
|
||||||
*
|
|
||||||
* Default: 1 (True i.e use QSPI flash)
|
|
||||||
*/
|
|
||||||
#if !defined(XUA_QUAD_SPI_FLASH)
|
|
||||||
#define XUA_QUAD_SPI_FLASH (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable HID playback controls functionality.
|
* @brief Enable HID playback controls functionality.
|
||||||
*
|
*
|
||||||
@@ -472,7 +507,7 @@
|
|||||||
* Default 0 (Disabled)
|
* Default 0 (Disabled)
|
||||||
*/
|
*/
|
||||||
#ifndef HID_CONTROLS
|
#ifndef HID_CONTROLS
|
||||||
#define HID_CONTROLS (0)
|
#define HID_CONTROLS (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -488,12 +523,11 @@
|
|||||||
* You must also supply your own function to deal with the HID endpoint(s)
|
* You must also supply your own function to deal with the HID endpoint(s)
|
||||||
* in this case.
|
* in this case.
|
||||||
*/
|
*/
|
||||||
#if( 0 < HID_CONTROLS )
|
#if (HID_CONTROLS) || defined (__DOXYGEN__)
|
||||||
#define XUA_HID_ENABLED (1)
|
#define XUA_HID_ENABLED (1)
|
||||||
#define XUA_OR_STATIC_HID_ENABLED (1)
|
#define XUA_OR_STATIC_HID_ENABLED (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(__static_hid_report_h_exists__)
|
#if defined(__static_hid_report_h_exists__)
|
||||||
#define XUA_OR_STATIC_HID_ENABLED (1)
|
#define XUA_OR_STATIC_HID_ENABLED (1)
|
||||||
#endif
|
#endif
|
||||||
@@ -506,18 +540,7 @@
|
|||||||
* Default 0 (Disabled)
|
* Default 0 (Disabled)
|
||||||
*/
|
*/
|
||||||
#ifndef HID_OUT_REQUIRED
|
#ifndef HID_OUT_REQUIRED
|
||||||
#define HID_OUT_REQUIRED (0)
|
#define HID_OUT_REQUIRED (0)
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
|
||||||
*
|
|
||||||
* 0: XMOS is I2S master. 1: CODEC is I2s master.
|
|
||||||
*
|
|
||||||
* Default: 0 (XMOS is master)
|
|
||||||
*/
|
|
||||||
#ifndef CODEC_MASTER
|
|
||||||
#define CODEC_MASTER (0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -526,7 +549,7 @@
|
|||||||
* Default: ""
|
* Default: ""
|
||||||
*/
|
*/
|
||||||
#ifndef SERIAL_STR
|
#ifndef SERIAL_STR
|
||||||
#define SERIAL_STR ""
|
#define SERIAL_STR ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -535,7 +558,7 @@
|
|||||||
* Default: "XMOS"
|
* Default: "XMOS"
|
||||||
*/
|
*/
|
||||||
#ifndef VENDOR_STR
|
#ifndef VENDOR_STR
|
||||||
#define VENDOR_STR "XMOS"
|
#define VENDOR_STR "XMOS"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,7 +567,7 @@
|
|||||||
* Default: 0x20B1 (XMOS)
|
* Default: 0x20B1 (XMOS)
|
||||||
*/
|
*/
|
||||||
#ifndef VENDOR_ID
|
#ifndef VENDOR_ID
|
||||||
#define VENDOR_ID (0x20B1)
|
#define VENDOR_ID (0x20B1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -586,7 +609,7 @@
|
|||||||
*/
|
*/
|
||||||
#if (AUDIO_CLASS == 1) || (AUDIO_CLASS_FALLBACK) || defined(__DOXYGEN__)
|
#if (AUDIO_CLASS == 1) || (AUDIO_CLASS_FALLBACK) || defined(__DOXYGEN__)
|
||||||
#ifndef PID_AUDIO_1
|
#ifndef PID_AUDIO_1
|
||||||
#define PID_AUDIO_1 (0x0003)
|
#define PID_AUDIO_1 (0x0003)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -596,28 +619,28 @@
|
|||||||
* Default: 0x0002
|
* Default: 0x0002
|
||||||
*/
|
*/
|
||||||
#ifndef PID_AUDIO_2
|
#ifndef PID_AUDIO_2
|
||||||
#define PID_AUDIO_2 (0x0002)
|
#define PID_AUDIO_2 (0x0002)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
|
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
|
||||||
*/
|
*/
|
||||||
#ifndef BCD_DEVICE_J
|
#ifndef BCD_DEVICE_J
|
||||||
#define BCD_DEVICE_J (1)
|
#define BCD_DEVICE_J (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
|
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
|
||||||
*/
|
*/
|
||||||
#ifndef BCD_DEVICE_M
|
#ifndef BCD_DEVICE_M
|
||||||
#define BCD_DEVICE_M (2)
|
#define BCD_DEVICE_M (2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
|
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
|
||||||
*/
|
*/
|
||||||
#ifndef BCD_DEVICE_N
|
#ifndef BCD_DEVICE_N
|
||||||
#define BCD_DEVICE_N (0)
|
#define BCD_DEVICE_N (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1021,7 +1044,7 @@
|
|||||||
* Default: 1 (Enabled)
|
* Default: 1 (Enabled)
|
||||||
*/
|
*/
|
||||||
#ifndef OUTPUT_VOLUME_CONTROL
|
#ifndef OUTPUT_VOLUME_CONTROL
|
||||||
#define OUTPUT_VOLUME_CONTROL (1)
|
#define OUTPUT_VOLUME_CONTROL (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1030,7 +1053,7 @@
|
|||||||
* Default: 1 (Enabled)
|
* Default: 1 (Enabled)
|
||||||
*/
|
*/
|
||||||
#ifndef INPUT_VOLUME_CONTROL
|
#ifndef INPUT_VOLUME_CONTROL
|
||||||
#define INPUT_VOLUME_CONTROL (1)
|
#define INPUT_VOLUME_CONTROL (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Power */
|
/* Power */
|
||||||
@@ -1072,7 +1095,7 @@
|
|||||||
* Default: 0 (Disabled)
|
* Default: 0 (Disabled)
|
||||||
*/
|
*/
|
||||||
#ifndef MIXER
|
#ifndef MIXER
|
||||||
#define MIXER (0)
|
#define MIXER (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1082,11 +1105,11 @@
|
|||||||
*/
|
*/
|
||||||
#if (MIXER)
|
#if (MIXER)
|
||||||
#ifndef MAX_MIX_COUNT
|
#ifndef MAX_MIX_COUNT
|
||||||
#define MAX_MIX_COUNT (8)
|
#define MAX_MIX_COUNT (8)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifndef MAX_MIX_COUNT
|
#ifndef MAX_MIX_COUNT
|
||||||
#define MAX_MIX_COUNT (0)
|
#define MAX_MIX_COUNT (0)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1098,7 +1121,7 @@
|
|||||||
* Default: 18
|
* Default: 18
|
||||||
*/
|
*/
|
||||||
#ifndef MIX_INPUTS
|
#ifndef MIX_INPUTS
|
||||||
#define MIX_INPUTS (18)
|
#define MIX_INPUTS (18)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Volume processing defines */
|
/* Volume processing defines */
|
||||||
@@ -1110,7 +1133,7 @@
|
|||||||
* Default: 0x8100 (-127db)
|
* Default: 0x8100 (-127db)
|
||||||
*/
|
*/
|
||||||
#ifndef MIN_VOLUME
|
#ifndef MIN_VOLUME
|
||||||
#define MIN_VOLUME (0x8100)
|
#define MIN_VOLUME (0x8100)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -1120,7 +1143,7 @@
|
|||||||
* Default: 0x0000 (0db)
|
* Default: 0x0000 (0db)
|
||||||
*/
|
*/
|
||||||
#ifndef MAX_VOLUME
|
#ifndef MAX_VOLUME
|
||||||
#define MAX_VOLUME (0x0000)
|
#define MAX_VOLUME (0x0000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1129,7 +1152,7 @@
|
|||||||
* Default: 0x100 (1db)
|
* Default: 0x100 (1db)
|
||||||
*/
|
*/
|
||||||
#ifndef VOLUME_RES
|
#ifndef VOLUME_RES
|
||||||
#define VOLUME_RES (0x100)
|
#define VOLUME_RES (0x100)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1139,7 +1162,7 @@
|
|||||||
* Default: 0x8100 (-127db)
|
* Default: 0x8100 (-127db)
|
||||||
*/
|
*/
|
||||||
#ifndef MIN_MIXER_VOLUME
|
#ifndef MIN_MIXER_VOLUME
|
||||||
#define MIN_MIXER_VOLUME (0x8100)
|
#define MIN_MIXER_VOLUME (0x8100)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1148,7 +1171,7 @@
|
|||||||
* Default: 0x0000 (0db)
|
* Default: 0x0000 (0db)
|
||||||
*/
|
*/
|
||||||
#ifndef MAX_MIXER_VOLUME
|
#ifndef MAX_MIXER_VOLUME
|
||||||
#define MAX_MIXER_VOLUME (0x0000)
|
#define MAX_MIXER_VOLUME (0x0000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1157,36 +1180,36 @@
|
|||||||
* Default: 0x100 (1db)
|
* Default: 0x100 (1db)
|
||||||
*/
|
*/
|
||||||
#ifndef VOLUME_RES_MIXER
|
#ifndef VOLUME_RES_MIXER
|
||||||
#define VOLUME_RES_MIXER (0x100)
|
#define VOLUME_RES_MIXER (0x100)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Handle out volume control in the mixer - enabled by default if mixer enabled */
|
/* Handle out volume control in the mixer - enabled by default */
|
||||||
#ifndef OUT_VOLUME_IN_MIXER
|
#ifndef OUT_VOLUME_IN_MIXER
|
||||||
#if MIXER
|
#if MIXER
|
||||||
#define OUT_VOLUME_IN_MIXER (1)
|
#define OUT_VOLUME_IN_MIXER (1)
|
||||||
#else
|
#else
|
||||||
#define OUT_VOLUME_IN_MIXER (0)
|
#define OUT_VOLUME_IN_MIXER (0)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Apply out volume controls after the mix. Only relevant when OUT_VOLUME_IN_MIXER enabled. Enabled by default */
|
/* Apply out volume controls after the mix. Only relevant when OUT_VOLUME_IN_MIXER enabled. Enabled by default */
|
||||||
#ifndef OUT_VOLUME_AFTER_MIX
|
#ifndef OUT_VOLUME_AFTER_MIX
|
||||||
#define OUT_VOLUME_AFTER_MIX (1)
|
#define OUT_VOLUME_AFTER_MIX (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Handle in volume control in the mixer - disabled by default */
|
/* Handle in volume control in the mixer - disabled by default */
|
||||||
#ifndef IN_VOLUME_IN_MIXER
|
#ifndef IN_VOLUME_IN_MIXER
|
||||||
#define IN_VOLUME_IN_MIXER (0)
|
#define IN_VOLUME_IN_MIXER (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Apply in volume controls after the mix. Only relevant when IN_VOLUMNE_IN MIXER enabled. Enabled by default */
|
/* Apply in volume controls after the mix. Only relevant when IN_VOLUMNE_IN MIXER enabled. Enabled by default */
|
||||||
#ifndef IN_VOLUME_AFTER_MIX
|
#ifndef IN_VOLUME_AFTER_MIX
|
||||||
#define IN_VOLUME_AFTER_MIX (1)
|
#define IN_VOLUME_AFTER_MIX (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Always enable explicit feedback EP, even when input stream is present */
|
/* Always enable explicit feedback EP, even when input stream is present */
|
||||||
#ifndef UAC_FORCE_FEEDBACK_EP
|
#ifndef UAC_FORCE_FEEDBACK_EP
|
||||||
#define UAC_FORCE_FEEDBACK_EP (1)
|
#define UAC_FORCE_FEEDBACK_EP (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(UAC_FORCE_FEEDBACK_EP) && UAC_FORCE_FEEDBACK_EP == 0)
|
#if (defined(UAC_FORCE_FEEDBACK_EP) && UAC_FORCE_FEEDBACK_EP == 0)
|
||||||
@@ -1194,9 +1217,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Synchronisation defines */
|
/* Synchronisation defines */
|
||||||
#define XUA_SYNCMODE_ASYNC (1) // USB_ENDPOINT_SYNCTYPE_ASYNC
|
#define XUA_SYNCMODE_ASYNC (1) // USB_ENDPOINT_SYNCTYPE_ASYNC
|
||||||
#define XUA_SYNCMODE_ADAPT (2) // USB_ENDPOINT_SYNCTYPE_ADAPT
|
#define XUA_SYNCMODE_ADAPT (2) // USB_ENDPOINT_SYNCTYPE_ADAPT
|
||||||
#define XUA_SYNCMODE_SYNC (3) // USB_ENDPOINT_SYNCTYPE_SYNC
|
#define XUA_SYNCMODE_SYNC (3) // USB_ENDPOINT_SYNCTYPE_SYNC
|
||||||
|
|
||||||
#ifndef XUA_SYNCMODE
|
#ifndef XUA_SYNCMODE
|
||||||
#define XUA_SYNCMODE XUA_SYNCMODE_ASYNC
|
#define XUA_SYNCMODE XUA_SYNCMODE_ASYNC
|
||||||
@@ -1276,6 +1299,8 @@ enum USBEndpointNumber_Out
|
|||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
#define AUDIO_STOP_FOR_DFU (0x12345678)
|
#define AUDIO_STOP_FOR_DFU (0x12345678)
|
||||||
|
#define AUDIO_START_FROM_DFU (0x87654321)
|
||||||
|
#define AUDIO_REBOOT_FROM_DFU (0xa5a5a5a5)
|
||||||
|
|
||||||
/* Result of db_to_mult(MAX_VOLUME, 8, 29) */
|
/* Result of db_to_mult(MAX_VOLUME, 8, 29) */
|
||||||
#define MAX_VOLUME_MULT (0x20000000)
|
#define MAX_VOLUME_MULT (0x20000000)
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ Frequencies and Clocks
|
|||||||
.. doxygendefine:: DEFAULT_FREQ
|
.. doxygendefine:: DEFAULT_FREQ
|
||||||
.. doxygendefine:: MCLK_441
|
.. doxygendefine:: MCLK_441
|
||||||
.. doxygendefine:: MCLK_48
|
.. doxygendefine:: MCLK_48
|
||||||
|
.. doxygendefine:: XUA_USE_SW_PLL
|
||||||
|
|
||||||
Audio Class
|
Audio Class
|
||||||
-----------
|
-----------
|
||||||
|
|||||||
@@ -1,74 +1,49 @@
|
|||||||
Required User Function Definitions
|
|newpage|
|
||||||
==================================
|
|
||||||
|
|
||||||
The following functions need to be defined by an application using the XMOS USB Audio framework.
|
User Function Definitions
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The following functions can be defined by an application using `lib_xua`.
|
||||||
|
|
||||||
|
.. note:: Default, empty, implementations of these functions are provided in `lib_xua`. These are marked
|
||||||
|
as weak symbols so the application can simply define its own version of them.
|
||||||
|
|
||||||
External Audio Hardware Configuration Functions
|
External Audio Hardware Configuration Functions
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
.. c:function:: void AudioHwInit(chanend ?c_codec)
|
The following functions can be optionally used by the design to configure external audio hardware.
|
||||||
|
As a minimum, in most applications, it is expected that a implementation of `AudioHwConfig()` will need
|
||||||
|
to be provided.
|
||||||
|
|
||||||
This function is called when the audio core starts after the
|
.. doxygenfunction:: AudioHwInit
|
||||||
device boots up and should initialize the external audio harware e.g. clocking, DAC, ADC etc
|
.. doxygenfunction:: AudioHwConfig
|
||||||
|
.. doxygenfunction:: AudioHwConfig_Mute
|
||||||
:param c_codec: An optional chanend that was original passed into
|
.. doxygenfunction:: AudioHwConfig_UnMute
|
||||||
:c:func:`audio` that can be used to communicate
|
|
||||||
with other cores.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void AudioHwConfig(unsigned samFreq, unsigned mclk, chanend ?c_codec, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
Audio Stream Start/Stop Functions
|
||||||
|
---------------------------------
|
||||||
This function is called when the audio core starts or changes
|
|
||||||
sample rate. It should configure the extenal audio hardware to run at the specified
|
|
||||||
sample rate given the supplied master clock frequency.
|
|
||||||
|
|
||||||
:param samFreq: The sample frequency in Hz that the hardware should be configured to (in Hz).
|
|
||||||
|
|
||||||
:param mclk: The master clock frequency that is required in Hz.
|
|
||||||
|
|
||||||
:param c_codec: An optional chanend that was original passed into
|
|
||||||
:c:func:`audio` that can be used to communicate
|
|
||||||
with other cores.
|
|
||||||
|
|
||||||
:param dsdMode: Signifies if the audio hardware should be configured for DSD operation
|
|
||||||
|
|
||||||
:param sampRes_DAC: The sample resolution of the DAC stream
|
|
||||||
|
|
||||||
:param sampRes_ADC: The sample resolution of the ADC stream
|
|
||||||
|
|
||||||
|
|
||||||
Audio Streaming Functions
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
The following functions can be optionally used by the design. They can be useful for mute lines etc.
|
The following functions can be optionally used by the design. They can be useful for mute lines etc.
|
||||||
|
|
||||||
.. c:function:: void AudioStreamStart(void)
|
.. doxygenfunction:: UserAudioStreamStart
|
||||||
|
.. doxygenfunction:: UserAudioStreamStop
|
||||||
|
.. doxygenfunction:: UserAudioInputStreamStart
|
||||||
|
.. doxygenfunction:: UserAudioInputStreamStop
|
||||||
|
.. doxygenfunction:: UserAudioOutputStreamStart
|
||||||
|
.. doxygenfunction:: UserAudioOutputStreamStop
|
||||||
|
|
||||||
This function is called when the audio stream from device to host
|
Host Active Functions
|
||||||
starts.
|
---------------------
|
||||||
|
|
||||||
.. c:function:: void AudioStreamStop(void)
|
|
||||||
|
|
||||||
This function is called when the audio stream from device to host stops.
|
|
||||||
|
|
||||||
Host Active
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The following function can be used to signal that the device is connected to a valid host.
|
The following function can be used to signal that the device is connected to a valid host.
|
||||||
|
|
||||||
This is called on a change in state.
|
.. doxygenfunction:: UserHostActive
|
||||||
|
|
||||||
.. c:function:: void AudioStreamStart(int active)
|
|
||||||
|
|
||||||
:param active: Indicates if the host is active or not. 1 for active else 0.
|
|
||||||
|
|
||||||
|
|
||||||
HID Controls
|
HID Controls
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The following function is called when the device wishes to read physical user input (buttons etc).
|
The following function is called when the device wishes to read physical user input (buttons etc).
|
||||||
|
The function should write relevant HID bits into this array. The bit ordering and functionality is defined by the HID report descriptor used.
|
||||||
|
|
||||||
.. c:function:: void UserReadHIDButtons(unsigned char hidData[])
|
.. doxygenfunction:: UserHIDGetData
|
||||||
|
|
||||||
:param hidData: The function should write relevant HID bits into this array. The bit ordering and functionality is defined by the HID report descriptor used.
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,11 @@ Setting the synchronisation mode of the device is done using the define in :ref:
|
|||||||
- USB synchronisation mode
|
- USB synchronisation mode
|
||||||
- ``XUA_SYNCMODE_ASYNC``
|
- ``XUA_SYNCMODE_ASYNC``
|
||||||
|
|
||||||
When operating in synchronous mode an external Cirrus Logic CS2100 device is required for master clock
|
When operating in synchronous mode a local master clock must be generated that is synchronised to the incoming
|
||||||
generation. The codebase expects to drive a synchronisation signal to this external device
|
SoF rate from USB. Either an external Cirrus Logic CS2100 device is required for this purpose
|
||||||
|
or, on xcore.ai devices, the on-chip application PLL may be used via lib_sw_pll.
|
||||||
|
In the case of using the CS2100, the codebase expects to drive a synchronisation signal to this external device
|
||||||
|
as a reference.
|
||||||
|
|
||||||
The programmer should ensure the define in :ref:`opt_sync_ref_defines` is set appropriately.
|
The programmer should ensure the define in :ref:`opt_sync_ref_defines` is set appropriately.
|
||||||
|
|
||||||
@@ -56,8 +59,11 @@ The programmer should ensure the define in :ref:`opt_sync_ref_defines` is set ap
|
|||||||
* - ``PLL_REF_TILE``
|
* - ``PLL_REF_TILE``
|
||||||
- Tile location of reference to CS2100 device
|
- Tile location of reference to CS2100 device
|
||||||
- ``AUDIO_IO_TILE``
|
- ``AUDIO_IO_TILE``
|
||||||
|
* - ``XUA_USE_SW_PLL``
|
||||||
|
- Whether or not to use sw_pll to recover the clock (xcore.ai only)
|
||||||
|
- 1 for xcore.ai targets. May be overridden to 0 in ``xua_conf.h``
|
||||||
|
|
||||||
The codebase expects this reference signal port to be defined in the application XN file as ``PORT_PLL_REF``.
|
The codebase expects the CS2100 reference signal port to be defined in the application XN file as ``PORT_PLL_REF``.
|
||||||
This may be a port of any bit-width, however, connection to bit[0] is assumed::
|
This may be a port of any bit-width, however, connection to bit[0] is assumed::
|
||||||
|
|
||||||
<Port Location="XS1_PORT_1A" Name="PORT_PLL_REF"/>
|
<Port Location="XS1_PORT_1A" Name="PORT_PLL_REF"/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
XMOSNEWSTYLE = 2
|
XMOSNEWSTYLE = 2
|
||||||
DOXYGEN_DIRS=../../api
|
DOXYGEN_DIRS=../../api ../../src/core/user/audiostream ../../src/core/user/hostactive ../../src/core/user/hid ../../src/core/user/audiohw
|
||||||
SOURCE_INCLUDE_DIRS=../../../lib_xua
|
SOURCE_INCLUDE_DIRS=../../../lib_xua
|
||||||
SPHINX_MASTER_DOC=lib_xua
|
SPHINX_MASTER_DOC=lib_xua
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ set(LIB_INCLUDES api
|
|||||||
src/core/support
|
src/core/support
|
||||||
src/core/user
|
src/core/user
|
||||||
src/core/user/audiostream
|
src/core/user/audiostream
|
||||||
|
src/core/user/audiohw
|
||||||
src/core/user/hid
|
src/core/user/hid
|
||||||
src/core/user/hostactive
|
src/core/user/hostactive
|
||||||
src/hid
|
src/hid
|
||||||
@@ -26,7 +27,7 @@ set(LIB_DEPENDENT_MODULES "lib_locks"
|
|||||||
"lib_xassert"
|
"lib_xassert"
|
||||||
"lib_xud"
|
"lib_xud"
|
||||||
"lib_adat"
|
"lib_adat"
|
||||||
"lib_sw_pll(develop)")
|
"lib_sw_pll")
|
||||||
|
|
||||||
set(LIB_COMPILER_FLAGS -O3 -DREF_CLK_FREQ=100 -fasm-linenum -fcomment-asm)
|
set(LIB_COMPILER_FLAGS -O3 -DREF_CLK_FREQ=100 -fasm-linenum -fcomment-asm)
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS) \
|
|||||||
src/core/support \
|
src/core/support \
|
||||||
src/core/user \
|
src/core/user \
|
||||||
src/core/user/audiostream \
|
src/core/user/audiostream \
|
||||||
|
src/core/user/audiohw \
|
||||||
src/core/user/hid \
|
src/core/user/hid \
|
||||||
src/core/user/hostactive \
|
src/core/user/hostactive \
|
||||||
src/hid \
|
src/hid \
|
||||||
@@ -70,6 +71,7 @@ SOURCE_DIRS = src/core \
|
|||||||
src/core/ports \
|
src/core/ports \
|
||||||
src/core/support \
|
src/core/support \
|
||||||
src/core/user/audiostream \
|
src/core/user/audiostream \
|
||||||
|
src/core/user/audiohw \
|
||||||
src/core/user/hostactive \
|
src/core/user/hostactive \
|
||||||
src/core/xuduser \
|
src/core/xuduser \
|
||||||
src/dfu \
|
src/dfu \
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
|
|
||||||
|
#include "audiohw.h"
|
||||||
#include "audioports.h"
|
#include "audioports.h"
|
||||||
#include "mic_array_conf.h"
|
#include "mic_array_conf.h"
|
||||||
#if (XUA_SPDIF_TX_EN)
|
#if (XUA_SPDIF_TX_EN)
|
||||||
@@ -640,7 +641,9 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
#endif
|
#endif
|
||||||
#if (XUA_ADAT_RX_EN || XUA_SPDIF_RX_EN)
|
#if (XUA_ADAT_RX_EN || XUA_SPDIF_RX_EN)
|
||||||
, chanend c_dig_rx
|
, chanend c_dig_rx
|
||||||
, chanend c_mclk_change
|
#endif
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
|
, chanend c_audio_rate_change
|
||||||
#endif
|
#endif
|
||||||
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
|
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
|
||||||
, server interface i_dfu ?dfuInterface
|
, server interface i_dfu ?dfuInterface
|
||||||
@@ -800,15 +803,23 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Configure Clocking/CODEC/DAC/ADC for SampleFreq/MClk */
|
/* Configure Clocking/CODEC/DAC/ADC for SampleFreq/MClk */
|
||||||
AudioHwConfig(curFreq, mClk, dsdMode, curSamRes_DAC, curSamRes_ADC);
|
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
|
||||||
/* Notify clockgen of new mCLk */
|
|
||||||
c_mclk_change <: mClk;
|
|
||||||
c_mclk_change <: curFreq;
|
|
||||||
|
|
||||||
/* Wait for ACK back from clockgen to signal clocks all good */
|
/* User should mute audio hardware */
|
||||||
c_mclk_change :> int _;
|
AudioHwConfig_Mute();
|
||||||
|
|
||||||
|
/* User code should configure audio harware for SampleFreq/MClk etc */
|
||||||
|
AudioHwConfig(curFreq, mClk, dsdMode, curSamRes_DAC, curSamRes_ADC);
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
|
/* Notify clockgen of new mCLk */
|
||||||
|
c_audio_rate_change <: mClk;
|
||||||
|
c_audio_rate_change <: curFreq;
|
||||||
|
|
||||||
|
/* Wait for ACK back from clockgen or ep_buffer to signal clocks all good */
|
||||||
|
c_audio_rate_change :> int _;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* User should unmute audio hardware */
|
||||||
|
AudioHwConfig_UnMute();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!firstRun)
|
if(!firstRun)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2023 XMOS LIMITED.
|
// Copyright 2011-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
#if XUA_USB_EN
|
#if XUA_USB_EN
|
||||||
@@ -105,7 +105,12 @@ void XUA_Buffer(
|
|||||||
#endif
|
#endif
|
||||||
, chanend c_aud
|
, chanend c_aud
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
, chanend c_audio_rate_change
|
||||||
|
#if(XUA_USE_SW_PLL)
|
||||||
|
, chanend c_sw_pll
|
||||||
|
#else
|
||||||
, client interface pll_ref_if i_pll_ref
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -141,7 +146,12 @@ void XUA_Buffer(
|
|||||||
, c_buff_ctrl
|
, c_buff_ctrl
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
, i_pll_ref
|
, c_audio_rate_change
|
||||||
|
#if(XUA_USE_SW_PLL)
|
||||||
|
, c_sw_pll
|
||||||
|
#else
|
||||||
|
, i_pll_ref
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -190,8 +200,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#ifdef CHAN_BUFF_CTRL
|
#ifdef CHAN_BUFF_CTRL
|
||||||
, chanend c_buff_ctrl
|
, chanend c_buff_ctrl
|
||||||
#endif
|
#endif
|
||||||
#if XUA_SYNCMODE == XUA_SYNCMODE_SYNC
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
, chanend c_audio_rate_change
|
||||||
|
#if (XUA_USE_SW_PLL)
|
||||||
|
, chanend c_sw_pll
|
||||||
|
#else
|
||||||
, client interface pll_ref_if i_pll_ref
|
, client interface pll_ref_if i_pll_ref
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -247,7 +262,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#if (NUM_USB_CHAN_IN > 0)
|
#if (NUM_USB_CHAN_IN > 0)
|
||||||
unsigned bufferIn = 1;
|
unsigned bufferIn = 1;
|
||||||
#endif
|
#endif
|
||||||
unsigned sofCount = 0;
|
int sofCount = 0;
|
||||||
|
|
||||||
unsigned mod_from_last_time = 0;
|
unsigned mod_from_last_time = 0;
|
||||||
#ifdef FB_TOLERANCE_TEST
|
#ifdef FB_TOLERANCE_TEST
|
||||||
@@ -294,7 +309,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
unsigned iap_ea_native_interface_alt_setting = 0;
|
unsigned iap_ea_native_interface_alt_setting = 0;
|
||||||
unsigned iap_ea_native_control_to_send = 0;
|
unsigned iap_ea_native_control_to_send = 0;
|
||||||
unsigned iap_ea_native_incoming = 0;
|
unsigned iap_ea_native_incoming = 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -357,6 +371,24 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#ifndef LOCAL_CLOCK_MARGIN
|
#ifndef LOCAL_CLOCK_MARGIN
|
||||||
#define LOCAL_CLOCK_MARGIN (1000)
|
#define LOCAL_CLOCK_MARGIN (1000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (XUA_USE_SW_PLL)
|
||||||
|
/* Setup the phase frequency detector */
|
||||||
|
const unsigned controller_rate_hz = 100;
|
||||||
|
const unsigned pfd_ppm_max = 2000; /* PPM range before we assume unlocked */
|
||||||
|
|
||||||
|
sw_pll_pfd_state_t sw_pll_pfd;
|
||||||
|
sw_pll_pfd_init(&sw_pll_pfd,
|
||||||
|
1, /* How often the PFD is invoked per call */
|
||||||
|
masterClockFreq / controller_rate_hz, /* pll ratio integer */
|
||||||
|
0, /* Assume precise timing of sampling */
|
||||||
|
pfd_ppm_max);
|
||||||
|
outuint(c_sw_pll, masterClockFreq);
|
||||||
|
outct(c_sw_pll, XS1_CT_END);
|
||||||
|
inuint(c_sw_pll); /* receive ACK */
|
||||||
|
inct(c_sw_pll);
|
||||||
|
|
||||||
|
#else /* XUA_USE_SW_PLL */
|
||||||
timer t_sofCheck;
|
timer t_sofCheck;
|
||||||
unsigned timeLastEdge;
|
unsigned timeLastEdge;
|
||||||
unsigned timeNextEdge;
|
unsigned timeNextEdge;
|
||||||
@@ -365,6 +397,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
i_pll_ref.toggle();
|
i_pll_ref.toggle();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) */
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
XUD_Result_t result;
|
XUD_Result_t result;
|
||||||
@@ -427,7 +461,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
/* Reset FB */
|
/* Reset FB */
|
||||||
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
||||||
* to stabilise (i.e. sofCount == 128 to fire) */
|
* to stabilise (i.e. sofCount == 128 to fire) */
|
||||||
sofCount = 1;
|
sofCount = 0;
|
||||||
clocks = 0;
|
clocks = 0;
|
||||||
clockcounter = 0;
|
clockcounter = 0;
|
||||||
mod_from_last_time = 0;
|
mod_from_last_time = 0;
|
||||||
@@ -450,7 +484,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
masterClockFreq = MCLK_441;
|
masterClockFreq = MCLK_441;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* (MAX_FREQ != MIN_FREQ) */
|
||||||
/* Ideally we want to wait for handshake (and pass back up) here. But we cannot keep this
|
/* Ideally we want to wait for handshake (and pass back up) here. But we cannot keep this
|
||||||
* core locked, it must stay responsive to packets (MIDI etc) and SOFs. So, set a flag and check for
|
* core locked, it must stay responsive to packets (MIDI etc) and SOFs. So, set a flag and check for
|
||||||
* handshake elsewhere */
|
* handshake elsewhere */
|
||||||
@@ -502,13 +536,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Pass on sample freq change to decouple() via global flag (saves a chanend) */
|
/* Pass on sample freq change to decouple() via global flag (saves a chanend) */
|
||||||
/* Note: freqChange flags now used to communicate other commands also */
|
/* Note: freqChange_flag now used to communicate other commands also */
|
||||||
SET_SHARED_GLOBAL0(g_freqChange, cmd); /* Set command */
|
SET_SHARED_GLOBAL0(g_freqChange, cmd); /* Set command */
|
||||||
SET_SHARED_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */
|
SET_SHARED_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && (!XUA_USE_SW_PLL)
|
||||||
case t_sofCheck when timerafter(timeNextEdge) :> void:
|
case t_sofCheck when timerafter(timeNextEdge) :> void:
|
||||||
i_pll_ref.toggle();
|
i_pll_ref.toggle();
|
||||||
timeLastEdge = timeNextEdge;
|
timeLastEdge = timeNextEdge;
|
||||||
@@ -523,28 +557,61 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
/* SOF notification from XUD_Manager() */
|
/* SOF notification from XUD_Manager() */
|
||||||
case inuint_byref(c_sof, u_tmp):
|
case inuint_byref(c_sof, u_tmp):
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
/* This really could (should) be done in decouple. However, for a quick demo this is okay
|
|
||||||
* Decouple expects a 16:16 number in fixed point stored in the global g_speed */
|
|
||||||
unsigned usbSpeed;
|
unsigned usbSpeed;
|
||||||
int framesPerSec;
|
|
||||||
GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed);
|
GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed);
|
||||||
static int sofCount = 0;
|
static int sofCount = 0;
|
||||||
|
#if (XUA_USE_SW_PLL)
|
||||||
|
/* Run PFD and sw_pll controller at 100Hz */
|
||||||
|
const int sofFreqDivider = (usbSpeed == XUD_SPEED_HS) ? (8000 / controller_rate_hz) : (1000 / controller_rate_hz);
|
||||||
|
#else /* (XUA_USE_SW_PLL) */
|
||||||
|
/* 1000 toggles per second for CS2100 reference -> 500 Hz */
|
||||||
|
const int toggleRateHz = 1000;
|
||||||
|
const int sofFreqDivider = (usbSpeed == XUD_SPEED_HS) ? (8000 / toggleRateHz) : (1000 / toggleRateHz);
|
||||||
|
#endif /* (XUA_USE_SW_PLL) */
|
||||||
|
|
||||||
framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000;
|
sofCount++;
|
||||||
|
if (sofCount == sofFreqDivider)
|
||||||
clocks = ((int64_t) sampleFreq << 16) / framesPerSec;
|
|
||||||
|
|
||||||
asm volatile("stw %0, dp[g_speed]"::"r"(clocks));
|
|
||||||
|
|
||||||
sofCount += 1000;
|
|
||||||
if (sofCount == framesPerSec)
|
|
||||||
{
|
{
|
||||||
|
#if (XUA_USE_SW_PLL)
|
||||||
|
/* Grab port timer count, run through PFD and send to sw_pll */
|
||||||
|
unsigned short mclk_pt;
|
||||||
|
asm volatile("getts %0, res[%1]" : "=r" (mclk_pt) : "r" (p_off_mclk));
|
||||||
|
|
||||||
|
uint8_t first_loop = 0;
|
||||||
|
unsafe{
|
||||||
|
sw_pll_calc_error_from_port_timers(&sw_pll_pfd, &first_loop, mclk_pt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int error = 0;
|
||||||
|
if(!first_loop)
|
||||||
|
{
|
||||||
|
error = sw_pll_pfd.mclk_diff;
|
||||||
|
}
|
||||||
|
sw_pll_pfd.mclk_pt_last = mclk_pt;
|
||||||
|
|
||||||
|
/* Send error to sw_pll */
|
||||||
|
outuint(c_sw_pll, error);
|
||||||
|
outct(c_sw_pll, XS1_CT_END);
|
||||||
|
|
||||||
|
#else /* (XUA_USE_SW_PLL) */
|
||||||
|
/* Do toggle for CS2100 reference clock */
|
||||||
/* Port is accessed via interface to allow flexibilty with location */
|
/* Port is accessed via interface to allow flexibilty with location */
|
||||||
i_pll_ref.toggle();
|
i_pll_ref.toggle();
|
||||||
t_sofCheck :> timeLastEdge;
|
t_sofCheck :> timeLastEdge;
|
||||||
sofCount = 0;
|
|
||||||
timeNextEdge = timeLastEdge + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
|
timeNextEdge = timeLastEdge + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
|
||||||
|
#endif /* (XUA_USE_SW_PLL) */
|
||||||
|
sofCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This really could (should) be done in decouple. However, for a quick demo this is okay
|
||||||
|
* Decouple expects a 16:16 number in fixed point stored in the global g_speed */
|
||||||
|
|
||||||
|
const int framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000;
|
||||||
|
|
||||||
|
clocks = ((int64_t) sampleFreq << 16) / framesPerSec;
|
||||||
|
asm volatile("stw %0, dp[g_speed]"::"r"(clocks));
|
||||||
|
|
||||||
|
|
||||||
#elif (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
#elif (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC)
|
||||||
|
|
||||||
/* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to
|
/* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to
|
||||||
@@ -646,7 +713,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
clockcounter = 0;
|
clockcounter = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
||||||
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
|
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
|
||||||
* expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format.
|
* expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format.
|
||||||
@@ -691,7 +757,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
clocks < (expected_fb + FB_TOLERANCE))
|
clocks < (expected_fb + FB_TOLERANCE))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int usb_speed;
|
|
||||||
asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks
|
asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks
|
||||||
|
|
||||||
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
|
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
|
||||||
@@ -897,8 +962,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XUA_HID_ENABLED
|
#if (XUA_HID_ENABLED)
|
||||||
/* HID Report Data */
|
/* HID Report Data */
|
||||||
case XUD_SetData_Select(c_hid, ep_hid, result):
|
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||||
hid_ready_flag = 0U;
|
hid_ready_flag = 0U;
|
||||||
unsigned reportTime;
|
unsigned reportTime;
|
||||||
@@ -911,7 +976,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
/* Received word from MIDI thread - Check for ACK or Data */
|
/* Received word from MIDI thread - Check for ACK or Data */
|
||||||
case midi_get_ack_or_data(c_midi, is_ack, datum):
|
case midi_get_ack_or_data(c_midi, is_ack, datum):
|
||||||
if (is_ack)
|
if (is_ack)
|
||||||
{
|
{
|
||||||
@@ -963,6 +1028,33 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
break;
|
break;
|
||||||
#endif /* ifdef MIDI */
|
#endif /* ifdef MIDI */
|
||||||
|
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
case c_audio_rate_change :> u_tmp:
|
||||||
|
unsigned selected_mclk_rate = u_tmp;
|
||||||
|
c_audio_rate_change :> u_tmp; /* Sample rate is discarded as only care about mclk */
|
||||||
|
#if (XUA_USE_SW_PLL)
|
||||||
|
sw_pll_pfd_init(&sw_pll_pfd,
|
||||||
|
1, /* How often the PFD is invoked per call */
|
||||||
|
selected_mclk_rate / controller_rate_hz, /* pll muliplication ratio integer */
|
||||||
|
0, /* Assume precise timing of sampling */
|
||||||
|
pfd_ppm_max);
|
||||||
|
restart_sigma_delta(c_sw_pll, selected_mclk_rate);
|
||||||
|
/* Delay ACK until sw_pll says it is ready */
|
||||||
|
#else
|
||||||
|
c_audio_rate_change <: 0; /* ACK back to audio to release I2S immediately */
|
||||||
|
#endif /* XUA_USE_SW_PLL */
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if (XUA_USE_SW_PLL)
|
||||||
|
/* This is fired when sw_pll has completed initialising a new mclk_rate */
|
||||||
|
case inuint_byref(c_sw_pll, u_tmp):
|
||||||
|
inct(c_sw_pll);
|
||||||
|
c_audio_rate_change <: 0; /* ACK back to audio to release */
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif /* (XUA_USE_SW_PLL) */
|
||||||
|
#endif /* (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) */
|
||||||
|
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
/* Received word from iap thread - Check for ACK or Data */
|
/* Received word from iap thread - Check for ACK or Data */
|
||||||
case iap_get_ack_or_reset_or_data(c_iap, is_ack_iap, is_reset, datum_iap):
|
case iap_get_ack_or_reset_or_data(c_iap, is_ack_iap, is_reset, datum_iap):
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,17 +4,9 @@
|
|||||||
#ifndef _SW_PLL_WRAPPPER_H_
|
#ifndef _SW_PLL_WRAPPPER_H_
|
||||||
#define _SW_PLL_WRAPPPER_H_
|
#define _SW_PLL_WRAPPPER_H_
|
||||||
|
|
||||||
/* By default we use SW_PLL for Digital Rx configs running on xcore.ai */
|
#include "xua.h"
|
||||||
/* Note: Not yet implemented for Synchronous mode */
|
|
||||||
#ifdef __XS3A__
|
|
||||||
#ifndef USE_SW_PLL
|
|
||||||
#define USE_SW_PLL 1
|
|
||||||
#endif /* USE_SW_PLL */
|
|
||||||
#else
|
|
||||||
#define USE_SW_PLL 0
|
|
||||||
#endif /* __XS3A__ */
|
|
||||||
|
|
||||||
#if USE_SW_PLL
|
#if XUA_USE_SW_PLL
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "sw_pll.h"
|
#include "sw_pll.h"
|
||||||
@@ -27,29 +19,29 @@ extern "C"
|
|||||||
/** Task that receives an error term, passes it through a PI controller and periodically
|
/** Task that receives an error term, passes it through a PI controller and periodically
|
||||||
* calclulates a sigma delta output value and sends it to the PLL fractional register.
|
* calclulates a sigma delta output value and sends it to the PLL fractional register.
|
||||||
*
|
*
|
||||||
* \param c_sigma_delta Channel connected to the clocking thread to pass raw error terms.
|
* \param c_sw_pll Channel connected to the clocking thread to pass raw error terms.
|
||||||
* \param selected_mclk_rate_ptr Pointer to the mclk rate variable declared in clockgen.
|
|
||||||
*/
|
*/
|
||||||
void SigmaDeltaTask(chanend c_sigma_delta, unsigned * unsafe selected_mclk_rate_ptr);
|
void sw_pll_task(chanend c_sw_pll);
|
||||||
|
|
||||||
/** Helper function that sends a special restart command. It causes the SDM task
|
/** Helper function that sends a special restart command. It causes the SDM task
|
||||||
* to quit and restart using the new mclk.
|
* to quit and restart using the new mclk.
|
||||||
*
|
*
|
||||||
* \param c_sigma_delta Channel connected to the clocking thread to pass raw error terms.
|
* \param c_sw_pll Channel connected to the clocking thread to pass raw error terms.
|
||||||
|
* \param mclk_Rate The mclk frequency in Hz.
|
||||||
*/
|
*/
|
||||||
void restart_sigma_delta(chanend c_sigma_delta);
|
void restart_sigma_delta(chanend c_sw_pll, unsigned mclk_rate);
|
||||||
|
|
||||||
/** Performs a frequency comparsion between the incoming digital Rx stream and the local mclk.
|
/** Performs a frequency comparsion between the incoming digital Rx stream and the local mclk.
|
||||||
*
|
*
|
||||||
* \param mclk_time_stamp The captured mclk count (using port timer) at the time of sample Rx.
|
* \param mclk_time_stamp The captured mclk count (using port timer) at the time of sample Rx.
|
||||||
* \param mclks_per_sample The nominal number of mclks per audio sample.
|
* \param mclks_per_sample The nominal number of mclks per audio sample.
|
||||||
* \param c_sigma_delta Channel connected to the sigma delta and controller thread.
|
* \param c_sw_pll Channel connected to the sigma delta and controller thread.
|
||||||
* \param receivedSamples The number of received samples since tha last call to this function.
|
* \param receivedSamples The number of received samples since tha last call to this function.
|
||||||
* \param reset_sw_pll_pfd Reference to a flag which will be used to signal reset of this function's state.
|
* \param reset_sw_pll_pfd Reference to a flag which will be used to signal reset of this function's state.
|
||||||
*/
|
*/
|
||||||
void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
||||||
unsigned mclks_per_sample,
|
unsigned mclks_per_sample,
|
||||||
chanend c_sigma_delta,
|
chanend c_sw_pll,
|
||||||
int receivedSamples,
|
int receivedSamples,
|
||||||
int &reset_sw_pll_pfd);
|
int &reset_sw_pll_pfd);
|
||||||
|
|
||||||
@@ -61,5 +53,5 @@ void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
|||||||
* returns The SDM update interval in ticks and the initial DCO setting for nominal frequency */
|
* returns The SDM update interval in ticks and the initial DCO setting for nominal frequency */
|
||||||
{unsigned, unsigned} InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk);
|
{unsigned, unsigned} InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk);
|
||||||
|
|
||||||
#endif /* USE_SW_PLL */
|
#endif /* XUA_USE_SW_PLL */
|
||||||
#endif /* _SW_PLL_WRAPPPER_H_ */
|
#endif /* _SW_PLL_WRAPPPER_H_ */
|
||||||
@@ -7,10 +7,10 @@
|
|||||||
#include "sw_pll_wrapper.h"
|
#include "sw_pll_wrapper.h"
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
|
|
||||||
#if USE_SW_PLL
|
#if XUA_USE_SW_PLL
|
||||||
|
|
||||||
|
|
||||||
{unsigned, unsigned} InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk)
|
{unsigned, unsigned} init_sw_pll(sw_pll_state_t &sw_pll, unsigned mClk)
|
||||||
{
|
{
|
||||||
/* Autogenerated SDM App PLL setup by dco_model.py using 22.5792_1M profile */
|
/* Autogenerated SDM App PLL setup by dco_model.py using 22.5792_1M profile */
|
||||||
/* Input freq: 24000000
|
/* Input freq: 24000000
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
||||||
unsigned mclks_per_sample,
|
unsigned mclks_per_sample,
|
||||||
chanend c_sigma_delta,
|
chanend c_sw_pll,
|
||||||
int receivedSamples,
|
int receivedSamples,
|
||||||
int &reset_sw_pll_pfd)
|
int &reset_sw_pll_pfd)
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,8 @@ void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* send PFD output to the sigma delta thread */
|
/* send PFD output to the sigma delta thread */
|
||||||
outuint(c_sigma_delta, (int) f_error);
|
outuint(c_sw_pll, (int) f_error);
|
||||||
|
outct(c_sw_pll, XS1_CT_END);
|
||||||
|
|
||||||
last_mclk_time_stamp = mclk_time_stamp;
|
last_mclk_time_stamp = mclk_time_stamp;
|
||||||
control_loop_counter = 0;
|
control_loop_counter = 0;
|
||||||
@@ -114,79 +115,88 @@ void do_sw_pll_phase_frequency_detector_dig_rx( unsigned short mclk_time_stamp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SigmaDeltaTask(chanend c_sigma_delta, unsigned * unsafe selected_mclk_rate_ptr){
|
void sw_pll_task(chanend c_sw_pll){
|
||||||
/* Zero is an invalid number and the SDM will not write the frac reg until
|
/* Zero is an invalid number and the SDM will not write the frac reg until
|
||||||
the first control value has been received. This avoids issues with
|
the first control value has been received. This avoids issues with
|
||||||
channel lockup if two tasks (eg. init and SDM) try to write at the same time. */
|
channel lockup if two tasks (eg. init and SDM) try to write at the same time. */
|
||||||
|
|
||||||
int f_error = 0;
|
while(1)
|
||||||
int dco_setting = 0; /* gets set at InitSWPLL */
|
|
||||||
unsigned sdm_interval = 0; /* gets set at InitSWPLL */
|
|
||||||
sw_pll_state_t sw_pll;
|
|
||||||
|
|
||||||
unsafe
|
|
||||||
{
|
{
|
||||||
|
unsigned selected_mclk_rate = inuint(c_sw_pll);
|
||||||
|
inct(c_sw_pll);
|
||||||
|
|
||||||
|
int f_error = 0;
|
||||||
|
int dco_setting = 0; /* gets set at init_sw_pll */
|
||||||
|
unsigned sdm_interval = 0; /* gets set at init_sw_pll */
|
||||||
|
sw_pll_state_t sw_pll;
|
||||||
|
|
||||||
/* initialse the SDM and gather SDM initial settings */
|
/* initialse the SDM and gather SDM initial settings */
|
||||||
{sdm_interval, dco_setting} = InitSWPLL(sw_pll, (unsigned)*selected_mclk_rate_ptr);
|
{sdm_interval, dco_setting} = init_sw_pll(sw_pll, selected_mclk_rate);
|
||||||
}
|
|
||||||
|
|
||||||
tileref_t this_tile = get_local_tile_id();
|
tileref_t this_tile = get_local_tile_id();
|
||||||
|
|
||||||
timer tmr;
|
timer tmr;
|
||||||
int32_t time_trigger;
|
int32_t time_trigger;
|
||||||
tmr :> time_trigger;
|
tmr :> time_trigger;
|
||||||
int running = 1;
|
time_trigger += sdm_interval; /* ensure first loop has correct delay */
|
||||||
|
int running = 1;
|
||||||
|
|
||||||
outuint(c_sigma_delta, 0); /* Signal back via clockgen to audio to start I2S */
|
outuint(c_sw_pll, 0); /* Signal back via clockgen to audio to start I2S */
|
||||||
|
outct(c_sw_pll, XS1_CT_END);
|
||||||
|
|
||||||
unsigned rx_word = 0;
|
unsigned rx_word = 0;
|
||||||
while(running)
|
while(running)
|
||||||
{
|
|
||||||
/* Poll for new SDM control value */
|
|
||||||
select
|
|
||||||
{
|
{
|
||||||
case inuint_byref(c_sigma_delta, rx_word):
|
/* Poll for new SDM control value */
|
||||||
if(rx_word == DISABLE_SDM)
|
select
|
||||||
{
|
{
|
||||||
f_error = 0;
|
case inuint_byref(c_sw_pll, rx_word):
|
||||||
running = 0;
|
inct(c_sw_pll);
|
||||||
}
|
if(rx_word == DISABLE_SDM)
|
||||||
else
|
|
||||||
{
|
|
||||||
f_error = (int32_t)rx_word;
|
|
||||||
unsafe
|
|
||||||
{
|
{
|
||||||
sw_pll_sdm_do_control_from_error(&sw_pll, -f_error);
|
f_error = 0;
|
||||||
dco_setting = sw_pll.sdm_state.current_ctrl_val;
|
running = 0;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
break;
|
{
|
||||||
|
f_error = (int32_t)rx_word;
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
sw_pll_sdm_do_control_from_error(&sw_pll, -f_error);
|
||||||
|
dco_setting = sw_pll.sdm_state.current_ctrl_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* Do nothing & fall-through. Above case polls only once per loop */
|
/* Do nothing & fall-through. Above case polls only once per loop */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until the timer value has been reached
|
/* Wait until the timer value has been reached
|
||||||
This implements a timing barrier and keeps
|
This implements a timing barrier and keeps
|
||||||
the loop rate constant. */
|
the loop rate constant. */
|
||||||
select
|
select
|
||||||
{
|
{
|
||||||
case tmr when timerafter(time_trigger) :> int _:
|
case tmr when timerafter(time_trigger) :> int _:
|
||||||
time_trigger += sdm_interval;
|
time_trigger += sdm_interval;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sw_pll_do_sigma_delta(&sw_pll.sdm_state, this_tile, dco_setting);
|
sw_pll_do_sigma_delta(&sw_pll.sdm_state, this_tile, dco_setting);
|
||||||
}
|
}
|
||||||
} /* if running */
|
} /* while running */
|
||||||
|
} /* while(1) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void restart_sigma_delta(chanend c_sigma_delta)
|
void restart_sigma_delta(chanend c_sw_pll, unsigned selected_mclk_rate)
|
||||||
{
|
{
|
||||||
outuint(c_sigma_delta, DISABLE_SDM); /* Resets SDM */
|
outuint(c_sw_pll, DISABLE_SDM); /* Resets SDM */
|
||||||
|
outct(c_sw_pll, XS1_CT_END);
|
||||||
|
outuint(c_sw_pll, selected_mclk_rate);
|
||||||
|
outct(c_sw_pll, XS1_CT_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_SW_PLL */
|
#endif /* XUA_USE_SW_PLL */
|
||||||
|
|||||||
@@ -314,7 +314,13 @@ void usb_audio_io(chanend ?c_aud_in,
|
|||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
, client interface pll_ref_if i_pll_ref
|
, client interface pll_ref_if i_pll_ref
|
||||||
, port ?p_for_mclk_count_aud
|
#endif
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
, chanend c_audio_rate_change
|
||||||
|
#endif
|
||||||
|
#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL)
|
||||||
|
, port p_for_mclk_count_aud
|
||||||
|
, chanend c_sw_pll
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -324,15 +330,13 @@ void usb_audio_io(chanend ?c_aud_in,
|
|||||||
|
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
chan c_dig_rx;
|
chan c_dig_rx;
|
||||||
chan c_mclk_change; /* Notification of new mclk freq to clockgen */
|
chan c_audio_rate_change; /* Notification of new mclk freq to clockgen and synch */
|
||||||
|
#if XUA_USE_SW_PLL
|
||||||
/* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/
|
/* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/
|
||||||
if(!isnull(p_for_mclk_count_aud))
|
unsigned x = 0;
|
||||||
{
|
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
||||||
unsigned x = 0;
|
asm("setclk res[%0], %1"::"r"(p_for_mclk_count_aud), "r"(x));
|
||||||
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
|
#endif /* XUA_USE_SW_PLL */
|
||||||
asm("setclk res[%0], %1"::"r"(p_for_mclk_count_aud), "r"(x));
|
|
||||||
}
|
|
||||||
#endif /* (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) */
|
#endif /* (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) */
|
||||||
|
|
||||||
#if (XUA_NUM_PDM_MICS > 0) && (PDM_TILE == AUDIO_IO_TILE)
|
#if (XUA_NUM_PDM_MICS > 0) && (PDM_TILE == AUDIO_IO_TILE)
|
||||||
@@ -378,7 +382,9 @@ void usb_audio_io(chanend ?c_aud_in,
|
|||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
, c_dig_rx
|
, c_dig_rx
|
||||||
, c_mclk_change
|
#endif
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
|
, c_audio_rate_change
|
||||||
#endif
|
#endif
|
||||||
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
|
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
|
||||||
, dfuInterface
|
, dfuInterface
|
||||||
@@ -405,8 +411,12 @@ void usb_audio_io(chanend ?c_aud_in,
|
|||||||
c_dig_rx,
|
c_dig_rx,
|
||||||
c_clk_ctl,
|
c_clk_ctl,
|
||||||
c_clk_int,
|
c_clk_int,
|
||||||
p_for_mclk_count_aud,
|
c_audio_rate_change
|
||||||
c_mclk_change);
|
#if XUA_USE_SW_PLL
|
||||||
|
, p_for_mclk_count_aud
|
||||||
|
, c_sw_pll
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -483,9 +493,16 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) )
|
||||||
interface pll_ref_if i_pll_ref;
|
interface pll_ref_if i_pll_ref;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL)
|
||||||
|
chan c_sw_pll;
|
||||||
|
#endif
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
chan c_audio_rate_change; /* Notification of new mclk freq to ep_buffer */
|
||||||
|
#endif
|
||||||
chan c_sof;
|
chan c_sof;
|
||||||
chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */
|
chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */
|
||||||
chan c_xud_in[ENDPOINT_COUNT_IN];
|
chan c_xud_in[ENDPOINT_COUNT_IN];
|
||||||
@@ -507,7 +524,7 @@ int main()
|
|||||||
{
|
{
|
||||||
USER_MAIN_CORES
|
USER_MAIN_CORES
|
||||||
|
|
||||||
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN))
|
||||||
on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref);
|
on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref);
|
||||||
#endif
|
#endif
|
||||||
on tile[XUD_TILE]:
|
on tile[XUD_TILE]:
|
||||||
@@ -578,7 +595,12 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
, c_mix_out
|
, c_mix_out
|
||||||
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
, c_audio_rate_change
|
||||||
|
#if (!XUA_USE_SW_PLL)
|
||||||
, i_pll_ref
|
, i_pll_ref
|
||||||
|
#else
|
||||||
|
, c_sw_pll
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
//:
|
//:
|
||||||
@@ -593,6 +615,10 @@ int main()
|
|||||||
#endif /* XUA_USB_EN */
|
#endif /* XUA_USB_EN */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL)
|
||||||
|
on tile[AUDIO_IO_TILE]: sw_pll_task(c_sw_pll);
|
||||||
|
#endif
|
||||||
|
|
||||||
on tile[AUDIO_IO_TILE]:
|
on tile[AUDIO_IO_TILE]:
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -609,14 +635,16 @@ int main()
|
|||||||
, dfuInterface
|
, dfuInterface
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_NUM_PDM_MICS > 0)
|
#if (XUA_NUM_PDM_MICS > 0)
|
||||||
#if (PDM_TILE == AUDIO_IO_TILE)
|
|
||||||
, c_ds_output
|
|
||||||
#endif
|
|
||||||
, c_pdm_pcm
|
|
||||||
#endif
|
#endif
|
||||||
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
|
||||||
, i_pll_ref
|
, i_pll_ref
|
||||||
|
#endif
|
||||||
|
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
|
||||||
|
, c_audio_rate_change
|
||||||
|
#endif
|
||||||
|
#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL)
|
||||||
, p_for_mclk_count_audio
|
, p_for_mclk_count_audio
|
||||||
|
, c_sw_pll
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
29
lib_xua/src/core/user/audiohw/audiohw.c
Normal file
29
lib_xua/src/core/user/audiohw/audiohw.c
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2023-2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
/* Default implementations of AudioHwInit(), AudioHwConfig(), AudioHwConfig_Mute() and AudioHwConfig_UnMute() */
|
||||||
|
|
||||||
|
void AudioHwInit() __attribute__ ((weak));
|
||||||
|
void AudioHwInit()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC) __attribute__ ((weak));
|
||||||
|
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioHwConfig_Mute() __attribute__ ((weak));
|
||||||
|
void AudioHwConfig_Mute()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioHwConfig_UnMute() __attribute__ ((weak));
|
||||||
|
void AudioHwConfig_UnMute()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
54
lib_xua/src/core/user/audiohw/audiohw.h
Normal file
54
lib_xua/src/core/user/audiohw/audiohw.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2023-2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
#ifndef _AUDIO_HW_H_
|
||||||
|
#define _AUDIO_HW_H_
|
||||||
|
|
||||||
|
/* The functions below should be implemented for the external audio hardware arrangement of a specific design.
|
||||||
|
* Note, default (empty) implementations of these are provided in audiohub_user.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User audio hardware initialisation code
|
||||||
|
*
|
||||||
|
* This function is called when the device starts up and should contain user code to perform any required audio hardware initialisation
|
||||||
|
*/
|
||||||
|
void AudioHwInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User audio hardware configuration code
|
||||||
|
*
|
||||||
|
* This function is called when on sample rate change and should contain user code to configure audio hardware
|
||||||
|
* (clocking, CODECs etc) for a specific mClk/Sample frequency
|
||||||
|
*
|
||||||
|
* \param samFreq The new sample frequency (in Hz)
|
||||||
|
*
|
||||||
|
* \param mClk The new master clock frequency (in Hz)
|
||||||
|
*
|
||||||
|
* \param dsdMode DSD mode, DSD_MODE_NATIVE, DSD_MODE_DOP or DSD_MODE_OFF
|
||||||
|
*
|
||||||
|
* \param sampRes_DAC Playback sample resolution (in bits)
|
||||||
|
*
|
||||||
|
* \param sampRes_ADC Record sample resolution (in bits)
|
||||||
|
*/
|
||||||
|
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User code mute audio hardware
|
||||||
|
*
|
||||||
|
* This function is called before AudioHwConfig() and should contain user code to mute audio hardware before a
|
||||||
|
* sample rate change in order to reduced audible pops/clicks
|
||||||
|
*
|
||||||
|
* Note, if using the application PLL of a xcore.ai device this function will be called before the master-clock is
|
||||||
|
* changed
|
||||||
|
*/
|
||||||
|
void AudioHwConfig_Mute(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User code to un-mute audio hardware
|
||||||
|
*
|
||||||
|
* This function is called after AudioHwConfig() and should contain user code to un-mute audio hardware after a
|
||||||
|
* sample rate change
|
||||||
|
*/
|
||||||
|
void AudioHwConfig_UnMute(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,30 +1,51 @@
|
|||||||
// Copyright 2011-2021 XMOS LIMITED.
|
// Copyright 2011-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#ifndef _AUDIOSTREAM_H_
|
#ifndef _AUDIOSTREAM_H_
|
||||||
#define _AUDIOSTREAM_H_
|
#define _AUDIOSTREAM_H_
|
||||||
|
|
||||||
/* Functions that handle functions that must occur on stream start/stop e.g. DAC mute/un-mute
|
/* Functions that handle functionality that occur on stream start/stop e.g. DAC mute/un-mute.
|
||||||
*
|
* They should be implemented for the external audio hardware arrangement of a specific design.
|
||||||
* THESE NEED IMPLEMENTING FOR A SPECIFIC DESIGN
|
*/
|
||||||
*
|
|
||||||
* */
|
|
||||||
|
|
||||||
/* Any actions required for stream start e.g. DAC un-mute - run every stream start */
|
/**
|
||||||
|
* @brief User stream start code
|
||||||
|
*
|
||||||
|
* User code to perform any actions required at every stream start - either input or output
|
||||||
|
*/
|
||||||
void UserAudioStreamStart(void);
|
void UserAudioStreamStart(void);
|
||||||
|
|
||||||
/* Any actions required on stream stop e.g. DAC mute - run every steam stop */
|
/**
|
||||||
|
* @brief User stream stop code
|
||||||
|
*
|
||||||
|
* User code to perform any actions required on every stream stop - either input or output*/
|
||||||
void UserAudioStreamStop(void);
|
void UserAudioStreamStop(void);
|
||||||
|
|
||||||
/* Any actions required on input stream start */
|
/**
|
||||||
|
* @brief User input stream stop code
|
||||||
|
*
|
||||||
|
* User code to perform any actions required on input stream start i.e. device to host
|
||||||
|
*/
|
||||||
void UserAudioInputStreamStart(void);
|
void UserAudioInputStreamStart(void);
|
||||||
|
|
||||||
/* Any actions required on input stream stop */
|
/**
|
||||||
|
* @brief User input stream stop code
|
||||||
|
*
|
||||||
|
* User code to perform any actions required on input stream stop i.e. device to host
|
||||||
|
*/
|
||||||
void UserAudioInputStreamStop(void);
|
void UserAudioInputStreamStop(void);
|
||||||
|
|
||||||
/* Any actions required on output stream start */
|
/**
|
||||||
|
* @brief User output stream start code
|
||||||
|
*
|
||||||
|
* User code to perform any actions required on output stream start i.e. host to device
|
||||||
|
*/
|
||||||
void UserAudioOutputStreamStart(void);
|
void UserAudioOutputStreamStart(void);
|
||||||
|
|
||||||
/* Any actions required on output stream stop */
|
/**
|
||||||
|
* @brief User output stream stop code
|
||||||
|
*
|
||||||
|
* User code to perfrom any actions required on output stream stop i.e. host to device
|
||||||
|
*/
|
||||||
void UserAudioOutputStreamStop(void);
|
void UserAudioOutputStreamStop(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
// Copyright 2013-2023 XMOS LIMITED.
|
// Copyright 2013-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Human Interface Device (HID) API
|
* @brief Human Interface Device (HID) API
|
||||||
*
|
*
|
||||||
* This file defines the Application Programming Interface (API) used to record HID
|
* This file defines the Application Programming Interface (API) used to record HID
|
||||||
* events and retrieve a HID Report for sending to a host.
|
* events and retrieve a HID Report for sending to a host.
|
||||||
* The using application has the responsibility to fulfill this API.
|
* The using application has the responsibility to fulfill this API.
|
||||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __USER_HID_H__
|
#ifndef _USER_HID_H_
|
||||||
#define __USER_HID_H__
|
#define _USER_HID_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -34,22 +34,16 @@ typedef struct hidEvent_t {
|
|||||||
#define HID_MAX_DATA_BYTES ( 4 )
|
#define HID_MAX_DATA_BYTES ( 4 )
|
||||||
#define HID_EVENT_INVALID_ID ( 0x100 )
|
#define HID_EVENT_INVALID_ID ( 0x100 )
|
||||||
|
|
||||||
#if XUA_HID_ENABLED
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the data for the next HID Report
|
* \brief Get the data for the next HID Report
|
||||||
*
|
*
|
||||||
* \note This function returns the HID data as a list of unsigned char because the
|
|
||||||
* \c XUD_SetReady_In() accepts data for transmission to the USB Host using
|
|
||||||
* this type.
|
|
||||||
*
|
|
||||||
* \param[in] id The HID Report ID (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
* \param[in] id The HID Report ID (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||||
* Set to zero if the application provides only one HID Report
|
* Set to zero if the application provides only one HID Report
|
||||||
* which does not include a Report ID
|
* which does not include a Report ID
|
||||||
* \param[out] hidData The HID data
|
* \param[out] hidData The HID data
|
||||||
* If using Report IDs, this function places the Report ID in
|
* If using Report IDs, this function places the Report ID in
|
||||||
* the first element; otherwise the first element holds the
|
* the first element; otherwise the first element holds the
|
||||||
* first byte of HID event data.
|
* first byte of HID event data.
|
||||||
*
|
*
|
||||||
* \returns The length of the HID Report in the \a hidData argument
|
* \returns The length of the HID Report in the \a hidData argument
|
||||||
* \retval Zero means no new HID event data has been recorded for the given \a id
|
* \retval Zero means no new HID event data has been recorded for the given \a id
|
||||||
@@ -57,9 +51,8 @@ typedef struct hidEvent_t {
|
|||||||
size_t UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BYTES ]);
|
size_t UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BYTES ]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize HID processing
|
* \brief Initialize HID processing
|
||||||
*/
|
*/
|
||||||
void UserHIDInit( void );
|
void UserHIDInit( void );
|
||||||
|
|
||||||
#endif /* ( 0 < HID_CONTROLS ) */
|
#endif /* _USER_HID_H_ */
|
||||||
#endif /* __USER_HID_H__ */
|
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
// Copyright 2013-2021 XMOS LIMITED.
|
// Copyright 2013-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User host active code
|
||||||
|
*
|
||||||
|
* This function can be used to perform user defined actions based on host present/not-present events.
|
||||||
|
* This function is called on a change in state.
|
||||||
|
*
|
||||||
|
* \param active Indicates if the host is active or not. 1 for active, else 0
|
||||||
|
*/
|
||||||
void UserHostActive(int active);
|
void UserHostActive(int active);
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ TEST_FLAGS ?=
|
|||||||
|
|
||||||
XCC_FLAGS_HS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
|
XCC_FLAGS_HS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
|
||||||
-DBUS_SPEED=2 \
|
-DBUS_SPEED=2 \
|
||||||
|
-DXUA_USE_SW_PLL=0 \
|
||||||
$(TEST_FLAGS)
|
$(TEST_FLAGS)
|
||||||
|
|
||||||
XCC_FLAGS_FS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
|
XCC_FLAGS_FS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
|
||||||
-DBUS_SPEED=1 \
|
-DBUS_SPEED=1 \
|
||||||
|
-DXUA_USE_SW_PLL=0 \
|
||||||
$(TEST_FLAGS)
|
$(TEST_FLAGS)
|
||||||
|
|
||||||
TARGET = test_xs3_600.xn
|
TARGET = test_xs3_600.xn
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 XMOS LIMITED.
|
// Copyright 2022-2024 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/* Simple test to ensure reference clock to CS2100 device continues when SOF clock not available
|
/* Simple test to ensure reference clock to CS2100 device continues when SOF clock not available
|
||||||
@@ -173,6 +173,7 @@ int main()
|
|||||||
chan c_in[EP_COUNT_IN];
|
chan c_in[EP_COUNT_IN];
|
||||||
chan c_sof;
|
chan c_sof;
|
||||||
chan c_aud_ctl;
|
chan c_aud_ctl;
|
||||||
|
chan c_audio_rate_change;
|
||||||
|
|
||||||
interface pll_ref_if i_pll_ref;
|
interface pll_ref_if i_pll_ref;
|
||||||
|
|
||||||
@@ -185,7 +186,7 @@ int main()
|
|||||||
|
|
||||||
XUA_Buffer_Ep(c_out[1], /* USB Audio Out*/
|
XUA_Buffer_Ep(c_out[1], /* USB Audio Out*/
|
||||||
c_in[1], /* USB Audio In */
|
c_in[1], /* USB Audio In */
|
||||||
c_sof, c_aud_ctl, p_off_mclk, i_pll_ref
|
c_sof, c_aud_ctl, p_off_mclk, c_audio_rate_change, i_pll_ref
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,4 +194,6 @@ int main()
|
|||||||
|
|
||||||
checker();
|
checker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user