diff --git a/lib_xua/api/xua_audiohub.h b/lib_xua/api/xua_audiohub.h index 8fa29eef..12c44379 100644 --- a/lib_xua/api/xua_audiohub.h +++ b/lib_xua/api/xua_audiohub.h @@ -12,6 +12,8 @@ #include "dfu_interface.h" #endif +#include "xua_clocking.h" + /** The audio driver thread. * * This function drives I2S ports and handles samples to/from other digital @@ -34,6 +36,8 @@ * * \param p_i2s_adc Nullable array of ports for I2S data input lines * + * \param i_SoftPll Interface to software PLL task + * * \param c_spdif_tx Channel connected to S/PDIF transmiter core from lib_spdif * * \param c_dig Channel connected to the clockGen() thread for @@ -49,6 +53,9 @@ void XUA_AudioHub(chanend ?c_aud, buffered _XUA_CLK_DIR port:32 ?p_bclk, buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC], buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC] +#if (XUA_USE_APP_PLL) || defined(__DOXYGEN__) + , client interface SoftPll_if i_SoftPll +#endif #if (XUA_SPDIF_TX_EN) || defined(__DOXYGEN__) , chanend c_spdif_tx #endif diff --git a/lib_xua/api/xua_buffer.h b/lib_xua/api/xua_buffer.h index d7d182d7..a1299079 100644 --- a/lib_xua/api/xua_buffer.h +++ b/lib_xua/api/xua_buffer.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. -#ifndef __XUA_BUFFER_H__ -#define __XUA_BUFFER_H__ +#ifndef _XUA_BUFFER_H_ +#define _XUA_BUFFER_H_ #if __XC__ @@ -26,6 +26,7 @@ * \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself) * \param c_aud Channel connected to XUA_AudioHub() core * \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( chanend c_aud_out, @@ -38,7 +39,7 @@ void XUA_Buffer( #if defined(MIDI) || defined(__DOXYGEN__) chanend c_midi_from_host, chanend c_midi_to_host, - chanend c_midi, + chanend c_midi, #endif #if XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__) chanend ?c_int, @@ -51,8 +52,13 @@ void XUA_Buffer( , chanend c_hid #endif , chanend c_aud -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOXYGEN__) +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOYXGEN__) + #if (!XUA_USE_APP_PLL) || defined(__DOXYGEN__) , client interface pll_ref_if i_pll_ref + #endif + #if (XUA_USE_APP_PLL) || defined(__DOXYGEN__) + , chanend c_swpll_update + #endif #endif ); @@ -66,7 +72,7 @@ void XUA_Buffer_Ep(chanend c_aud_out, #ifdef MIDI chanend c_midi_from_host, chanend c_midi_to_host, - chanend c_midi, + chanend c_midi, #endif #if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) chanend ?c_int, @@ -81,10 +87,16 @@ void XUA_Buffer_Ep(chanend c_aud_out, #ifdef CHAN_BUFF_CTRL , chanend c_buff_ctrl #endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOXYGEN__) +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || defined(__DOYXGEN__) + #if (!XUA_USE_APP_PLL) || defined(__DOXYGEN__) , client interface pll_ref_if i_pll_ref + #endif + #if (XUA_USE_APP_PLL) || defined(__DOXYGEN__) + , chanend c_swpll_update + #endif #endif - ); + ); + /** Manage the data transfer between the USB audio buffer and the * Audio I/O driver. diff --git a/lib_xua/api/xua_clocking.h b/lib_xua/api/xua_clocking.h index 8a9f8b83..f24ab1b5 100644 --- a/lib_xua/api/xua_clocking.h +++ b/lib_xua/api/xua_clocking.h @@ -38,5 +38,18 @@ void clockGen( streaming chanend ?c_spdif_rx, chanend c_clk_int, port ?p_for_mclk_count_aud, chanend c_mclk_change); + + +interface SoftPll_if +{ + void init(int mclk_hz); +}; + +#if (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC) +[[distributable]] +#endif +void XUA_SoftPll(tileref tile, server interface SoftPll_if i_softPll, chanend c_update); + +#endif #endif diff --git a/lib_xua/api/xua_conf_default.h b/lib_xua/api/xua_conf_default.h index 685f5672..0fbb1046 100644 --- a/lib_xua/api/xua_conf_default.h +++ b/lib_xua/api/xua_conf_default.h @@ -11,56 +11,55 @@ #include "xua_conf.h" #endif -/* Default tile arrangement */ +/* + * Tile arrangement defines + */ /** * @brief Location (tile) of audio I/O. Default: 0 */ #ifndef AUDIO_IO_TILE -#define AUDIO_IO_TILE (0) +#define AUDIO_IO_TILE (0) #endif /** * @brief Location (tile) of audio I/O. Default: 0 */ #ifndef XUD_TILE -#define XUD_TILE (0) +#define XUD_TILE (0) #endif /** * @brief Location (tile) of MIDI I/O. Default: AUDIO_IO_TILE */ #ifndef MIDI_TILE -#define MIDI_TILE AUDIO_IO_TILE +#define MIDI_TILE AUDIO_IO_TILE #endif /** * @brief Location (tile) of SPDIF Tx. Default: AUDIO_IO_TILE */ #ifndef SPDIF_TX_TILE -#define SPDIF_TX_TILE AUDIO_IO_TILE +#define SPDIF_TX_TILE AUDIO_IO_TILE #endif /** * @brief Location (tile) of PDM Rx. Default: AUDIO_IO_TILE */ #ifndef PDM_TILE -#define PDM_TILE AUDIO_IO_TILE +#define PDM_TILE AUDIO_IO_TILE #endif /** * @brief Location (tile) of reference signal to CS2100. Default: AUDIO_IO_TILE */ #ifndef PLL_REF_TILE -#define PLL_REF_TILE AUDIO_IO_TILE +#define PLL_REF_TILE AUDIO_IO_TILE #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) @@ -79,18 +78,57 @@ #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(NATIVE_DSD) && (NATIVE_DSD == 0) #undef NATIVE_DSD #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 #else - #define DSD_CHANS_DAC (0) + #define DSD_CHANS_DAC 0 #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_TDM (1) /** @@ -103,7 +141,7 @@ #error Bad value for XUA_PCM_FORMAT #endif #else - #define XUA_PCM_FORMAT XUA_PCM_FORMAT_I2S + #define XUA_PCM_FORMAT XUA_PCM_FORMAT_I2S #endif /** @@ -114,89 +152,12 @@ **/ #ifndef I2S_CHANS_PER_FRAME #if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) - #define I2S_CHANS_PER_FRAME (8) + #define I2S_CHANS_PER_FRAME 8 #else - #define I2S_CHANS_PER_FRAME (2) + #define I2S_CHANS_PER_FRAME 2 #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. * @@ -211,21 +172,82 @@ #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 #define MAX_FREQ (192000) #endif /** - * @brief Min supported sample frequency for device (Hz). Default 44100 + * @brief Min supported sample frequency for device (Hz). + * + * Default: 44100Hz */ #ifndef MIN_FREQ #define MIN_FREQ (44100) #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 #error MCLK_441 not defined @@ -233,13 +255,34 @@ #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 #error MCLK_48 not defined #define MCLK_48 (256 * 48000) /* Define anyway for doygen */ #endif +/** + * @brief Enable/disable the use of the secondary/application PLL for generating master-clocks. + * Only available on xcore.ai devices. + * + * Default: Enabled (for xcore.ai devices) + */ +#ifndef XUA_USE_APP_PLL + #if defined(__XS3A__) + #if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) + /* Currently must use an external CS2100 device for syncing to external digital streams */ + #define XUA_USE_APP_PLL (0) + #else + #define XUA_USE_APP_PLL (1) + #endif + #else + #define XUA_USE_APP_PLL (0) + #endif +#endif + /** * @brief Default device sample frequency. A safe default should be used. * @@ -249,10 +292,25 @@ #define DEFAULT_FREQ (MIN_FREQ) #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) */ @@ -261,9 +319,9 @@ #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 #define AUDIO_CLASS_FALLBACK (0) @@ -278,7 +336,7 @@ #if (AUDIO_CLASS == 2) /* Whether to run in Audio Class 2.0 mode in USB Full-speed */ #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 @@ -295,16 +353,17 @@ #error AUDIO_CLASS set to 1 and FULL_SPEED_AUDIO_2 enabled! #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 -#define XUA_NUM_PDM_MICS (0) +#ifndef XUA_USB_EN +#define XUA_USB_EN (1) #endif /** @@ -318,18 +377,14 @@ #endif /** - * @brief Size of a frame of microphone data samples. - * - * Default: 1 + * @brief Size of a frame of microphone data samples. Default: 1 */ #ifndef XUA_MIC_FRAME_SIZE #define XUA_MIC_FRAME_SIZE (1) #endif /** - * @brief Enable MIDI functionality including buffering, descriptors etc. - * - * Default: 0 (Disabled) + * @brief Enable MIDI functionality including buffering, descriptors etc. Default: DISABLED */ #ifndef MIDI #define MIDI (0) @@ -350,7 +405,7 @@ * @brief Enables SPDIF Tx. Default: 0 (Disabled) */ #ifndef XUA_SPDIF_TX_EN -#define XUA_SPDIF_TX_EN (0) +#define XUA_SPDIF_TX_EN (0) #endif /** @@ -359,16 +414,14 @@ * Default: 0 (i.e. channels 0 & 1) * */ #ifndef SPDIF_TX_INDEX -#define SPDIF_TX_INDEX (0) +#define SPDIF_TX_INDEX (0) #endif /** - * @brief Enables ADAT Tx. - * - * Default: 0 (Disabled) + * @brief Enables ADAT Tx. Default: 0 (Disabled) */ #ifndef XUA_ADAT_TX_EN -#define XUA_ADAT_TX_EN (0) +#define XUA_ADAT_TX_EN (0) #endif /** @@ -377,25 +430,21 @@ * Default: 0 (i.e. channels [0:7]) * */ #ifndef ADAT_TX_INDEX -#define ADAT_TX_INDEX (0) +#define ADAT_TX_INDEX (0) #endif /** - * @brief Enables SPDIF Rx. - * - * Default: 0 (Disabled) + * @brief Enables SPDIF Rx. Default: 0 (Disabled) */ #ifndef XUA_SPDIF_RX_EN -#define XUA_SPDIF_RX_EN (0) +#define XUA_SPDIF_RX_EN (0) #endif /** - * @brief Enables ADAT Rx. - * - * Default: 0 (Disabled) + * @brief Enables ADAT Rx. Default: 0 (Disabled) */ #ifndef XUA_ADAT_RX_EN -#define XUA_ADAT_RX_EN (0) +#define XUA_ADAT_RX_EN (0) #endif /** @@ -450,20 +499,11 @@ * Default: 1 (Enabled) */ #if !defined(XUA_DFU_EN) -#define XUA_DFU_EN (1) +#define XUA_DFU_EN (1) #elif defined(XUA_DFU_EN) && (XUA_DFU_EN == 0) #undef XUA_DFU_EN #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. * @@ -472,7 +512,7 @@ * Default 0 (Disabled) */ #ifndef HID_CONTROLS -#define HID_CONTROLS (0) +#define HID_CONTROLS (0) #endif /** @@ -488,12 +528,11 @@ * You must also supply your own function to deal with the HID endpoint(s) * in this case. */ -#if( 0 < HID_CONTROLS ) +#if (HID_CONTROLS) || defined (__DOXYGEN__) #define XUA_HID_ENABLED (1) #define XUA_OR_STATIC_HID_ENABLED (1) #endif - #if defined(__static_hid_report_h_exists__) #define XUA_OR_STATIC_HID_ENABLED (1) #endif @@ -506,18 +545,7 @@ * Default 0 (Disabled) */ #ifndef HID_OUT_REQUIRED -#define HID_OUT_REQUIRED (0) -#endif - -/** - * @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks) - * - * 0: XMOS is I2S master. 1: CODEC is I2s master. - * - * Default: 0 (XMOS is master) - */ -#ifndef CODEC_MASTER -#define CODEC_MASTER (0) +#define HID_OUT_REQUIRED (0) #endif /** @@ -526,7 +554,7 @@ * Default: "" */ #ifndef SERIAL_STR -#define SERIAL_STR "" +#define SERIAL_STR "" #endif /** @@ -535,7 +563,7 @@ * Default: "XMOS" */ #ifndef VENDOR_STR -#define VENDOR_STR "XMOS" +#define VENDOR_STR "XMOS" #endif /** @@ -544,7 +572,7 @@ * Default: 0x20B1 (XMOS) */ #ifndef VENDOR_ID -#define VENDOR_ID (0x20B1) +#define VENDOR_ID (0x20B1) #endif /** @@ -586,7 +614,7 @@ */ #if (AUDIO_CLASS == 1) || (AUDIO_CLASS_FALLBACK) || defined(__DOXYGEN__) #ifndef PID_AUDIO_1 -#define PID_AUDIO_1 (0x0003) +#define PID_AUDIO_1 (0x0003) #endif #endif @@ -596,28 +624,28 @@ * Default: 0x0002 */ #ifndef PID_AUDIO_2 -#define PID_AUDIO_2 (0x0002) +#define PID_AUDIO_2 (0x0002) #endif /** * @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 -#define BCD_DEVICE_J (1) +#define BCD_DEVICE_J (1) #endif /** * @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 -#define BCD_DEVICE_M (2) +#define BCD_DEVICE_M (2) #endif /** * @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 -#define BCD_DEVICE_N (0) +#define BCD_DEVICE_N (0) #endif /** @@ -1021,7 +1049,7 @@ * Default: 1 (Enabled) */ #ifndef OUTPUT_VOLUME_CONTROL -#define OUTPUT_VOLUME_CONTROL (1) +#define OUTPUT_VOLUME_CONTROL (1) #endif /** @@ -1030,7 +1058,7 @@ * Default: 1 (Enabled) */ #ifndef INPUT_VOLUME_CONTROL -#define INPUT_VOLUME_CONTROL (1) +#define INPUT_VOLUME_CONTROL (1) #endif /* Power */ @@ -1072,7 +1100,7 @@ * Default: 0 (Disabled) */ #ifndef MIXER -#define MIXER (0) +#define MIXER (0) #endif /** @@ -1082,11 +1110,11 @@ */ #if (MIXER) #ifndef MAX_MIX_COUNT - #define MAX_MIX_COUNT (8) + #define MAX_MIX_COUNT (8) #endif #else #ifndef MAX_MIX_COUNT - #define MAX_MIX_COUNT (0) + #define MAX_MIX_COUNT (0) #endif #endif @@ -1098,7 +1126,7 @@ * Default: 18 */ #ifndef MIX_INPUTS - #define MIX_INPUTS (18) + #define MIX_INPUTS (18) #endif /* Volume processing defines */ @@ -1110,7 +1138,7 @@ * Default: 0x8100 (-127db) */ #ifndef MIN_VOLUME -#define MIN_VOLUME (0x8100) +#define MIN_VOLUME (0x8100) #endif @@ -1120,7 +1148,7 @@ * Default: 0x0000 (0db) */ #ifndef MAX_VOLUME -#define MAX_VOLUME (0x0000) +#define MAX_VOLUME (0x0000) #endif /** @@ -1129,7 +1157,7 @@ * Default: 0x100 (1db) */ #ifndef VOLUME_RES -#define VOLUME_RES (0x100) +#define VOLUME_RES (0x100) #endif /** @@ -1139,7 +1167,7 @@ * Default: 0x8100 (-127db) */ #ifndef MIN_MIXER_VOLUME -#define MIN_MIXER_VOLUME (0x8100) +#define MIN_MIXER_VOLUME (0x8100) #endif /** @@ -1148,7 +1176,7 @@ * Default: 0x0000 (0db) */ #ifndef MAX_MIXER_VOLUME -#define MAX_MIXER_VOLUME (0x0000) +#define MAX_MIXER_VOLUME (0x0000) #endif /** @@ -1157,36 +1185,32 @@ * Default: 0x100 (1db) */ #ifndef VOLUME_RES_MIXER -#define VOLUME_RES_MIXER (0x100) +#define VOLUME_RES_MIXER (0x100) #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 -#if MIXER - #define OUT_VOLUME_IN_MIXER (1) -#else - #define OUT_VOLUME_IN_MIXER (0) -#endif +#define OUT_VOLUME_IN_MIXER (1) #endif /* Apply out volume controls after the mix. Only relevant when OUT_VOLUME_IN_MIXER enabled. Enabled by default */ #ifndef OUT_VOLUME_AFTER_MIX -#define OUT_VOLUME_AFTER_MIX (1) +#define OUT_VOLUME_AFTER_MIX (1) #endif /* Handle in volume control in the mixer - disabled by default */ #ifndef IN_VOLUME_IN_MIXER -#define IN_VOLUME_IN_MIXER (0) +#define IN_VOLUME_IN_MIXER (0) #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 relebant when IN_VOLUMNE_IN MIXER enabled. Enabled by default */ #ifndef IN_VOLUME_AFTER_MIX -#define IN_VOLUME_AFTER_MIX (1) +#define IN_VOLUME_AFTER_MIX (1) #endif /* Always enable explicit feedback EP, even when input stream is present */ #ifndef UAC_FORCE_FEEDBACK_EP -#define UAC_FORCE_FEEDBACK_EP (1) +#define UAC_FORCE_FEEDBACK_EP (1) #endif #if (defined(UAC_FORCE_FEEDBACK_EP) && UAC_FORCE_FEEDBACK_EP == 0) @@ -1194,9 +1218,9 @@ #endif /* Synchronisation defines */ -#define XUA_SYNCMODE_ASYNC (1) // USB_ENDPOINT_SYNCTYPE_ASYNC -#define XUA_SYNCMODE_ADAPT (2) // USB_ENDPOINT_SYNCTYPE_ADAPT -#define XUA_SYNCMODE_SYNC (3) // USB_ENDPOINT_SYNCTYPE_SYNC +#define XUA_SYNCMODE_ASYNC (1) // USB_ENDPOINT_SYNCTYPE_ASYNC +#define XUA_SYNCMODE_ADAPT (2) // USB_ENDPOINT_SYNCTYPE_ADAPT +#define XUA_SYNCMODE_SYNC (3) // USB_ENDPOINT_SYNCTYPE_SYNC #ifndef XUA_SYNCMODE #define XUA_SYNCMODE XUA_SYNCMODE_ASYNC @@ -1276,6 +1300,8 @@ enum USBEndpointNumber_Out #endif /* __ASSEMBLER__ */ #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) */ #define MAX_VOLUME_MULT (0x20000000) @@ -1378,7 +1404,7 @@ enum USBEndpointNumber_Out /* Some defines that allow us to remove unused code */ /* Useful for dropping lower part of macs in volume processing... */ -#if (FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS > 24) || \ +#if (FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24) || \ (((FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24)) && (OUTPUT_FORMAT_COUNT > 1)) || \ (((FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS > 24)) && (OUTPUT_FORMAT_COUNT > 2)) #define STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED 1 @@ -1412,29 +1438,29 @@ enum USBEndpointNumber_Out #endif /* Useful for dropping lower part of macs in volume processing... */ -#if (FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS > 24) - #define STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED 1 -#else - #define STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED 0 -#endif + #if (FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS > 24) || (FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS > 24) + #define STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED 1 + #else + #define STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED 0 + #endif -#if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 4) || (HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 4)) - #define STREAM_FORMAT_INPUT_SUBSLOT_4_USED 1 -#else - #define STREAM_FORMAT_INPUT_SUBSLOT_4_USED 0 -#endif + #if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 4) || (HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 4)) + #define STREAM_FORMAT_INPUT_SUBSLOT_4_USED 1 + #else + #define STREAM_FORMAT_INPUT_SUBSLOT_4_USED 0 + #endif -#if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 3) || (HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 3)) - #define STREAM_FORMAT_INPUT_SUBSLOT_3_USED 1 -#else - #define STREAM_FORMAT_INPUT_SUBSLOT_3_USED 0 -#endif + #if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 3) || (HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 3)) + #define STREAM_FORMAT_INPUT_SUBSLOT_3_USED 1 + #else + #define STREAM_FORMAT_INPUT_SUBSLOT_3_USED 0 + #endif -#if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 2) || (HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 2)) - #define STREAM_FORMAT_INPUT_SUBSLOT_2_USED 1 -#else - #define STREAM_FORMAT_INPUT_SUBSLOT_2_USED 0 -#endif + #if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 2) || (HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 2)) + #define STREAM_FORMAT_INPUT_SUBSLOT_2_USED 1 + #else + #define STREAM_FORMAT_INPUT_SUBSLOT_2_USED 0 + #endif #if MAX_FREQ < MIN_FREQ #error MAX_FREQ should be >= MIN_FREQ!! diff --git a/lib_xua/doc/rst/api_defines.rst b/lib_xua/doc/rst/api_defines.rst index a67b08fd..a9a395a0 100644 --- a/lib_xua/doc/rst/api_defines.rst +++ b/lib_xua/doc/rst/api_defines.rst @@ -8,9 +8,9 @@ An application using the USB audio framework needs to have defines set for confi Defaults for these defines are found in ``xua_conf_default.h``. These defines should be over-ridden in an optional header file ``xua_conf.h`` file or in the ``Makefile`` -for a relevant build configuration. +for a relevant build configuration. -This section fully documents all of the settable defines and their default values (where appropriate). +This section fully documents all of the settable defines and their default values (where appropriate). Code Location (tile) -------------------- @@ -25,12 +25,12 @@ Code Location (tile) Channel Counts -------------- -.. doxygendefine:: NUM_USB_CHAN_OUT -.. doxygendefine:: NUM_USB_CHAN_IN -.. doxygendefine:: I2S_CHANS_DAC -.. doxygendefine:: I2S_CHANS_ADC +.. doxygendefine:: NUM_USB_CHAN_OUT +.. doxygendefine:: NUM_USB_CHAN_IN +.. doxygendefine:: I2S_CHANS_DAC +.. doxygendefine:: I2S_CHANS_ADC -Frequencies and Clocks +Frequencies and Clocks ---------------------- .. doxygendefine:: MAX_FREQ @@ -38,6 +38,7 @@ Frequencies and Clocks .. doxygendefine:: DEFAULT_FREQ .. doxygendefine:: MCLK_441 .. doxygendefine:: MCLK_48 +.. doxygendefine:: USE_SW_PLL Audio Class ----------- diff --git a/lib_xua/doc/rst/api_user_functions.rst b/lib_xua/doc/rst/api_user_functions.rst index e0728647..e9c1ed61 100644 --- a/lib_xua/doc/rst/api_user_functions.rst +++ b/lib_xua/doc/rst/api_user_functions.rst @@ -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 ----------------------------------------------- -.. 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 - device boots up and should initialize the external audio harware e.g. clocking, DAC, ADC etc +.. doxygenfunction:: AudioHwInit +.. doxygenfunction:: AudioHwConfig +.. doxygenfunction:: AudioHwConfig_Mute +.. doxygenfunction:: AudioHwConfig_UnMute - :param c_codec: An optional chanend that was original passed into - :c:func:`audio` that can be used to communicate - with other cores. - -.. c:function:: void AudioHwConfig(unsigned samFreq, unsigned mclk, chanend ?c_codec, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC) - - 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 -------------------------- +Audio Stream Start/Stop Functions +--------------------------------- 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 - starts. - -.. c:function:: void AudioStreamStop(void) - - This function is called when the audio stream from device to host stops. - -Host Active ------------ +Host Active Functions +--------------------- 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. - -.. c:function:: void AudioStreamStart(int active) - - :param active: Indicates if the host is active or not. 1 for active else 0. - +.. doxygenfunction:: UserHostActive HID Controls ------------ 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[]) - - :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. - +.. doxygenfunction:: UserHIDGetData diff --git a/lib_xua/doc/rst/xdoc.conf b/lib_xua/doc/rst/xdoc.conf index 4d522c83..ae22d5a0 100644 --- a/lib_xua/doc/rst/xdoc.conf +++ b/lib_xua/doc/rst/xdoc.conf @@ -1,5 +1,5 @@ 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 SPHINX_MASTER_DOC=lib_xua diff --git a/lib_xua/src/core/audiohub/xua_audiohub.xc b/lib_xua/src/core/audiohub/xua_audiohub.xc index 3089523a..3c6ce660 100755 --- a/lib_xua/src/core/audiohub/xua_audiohub.xc +++ b/lib_xua/src/core/audiohub/xua_audiohub.xc @@ -20,6 +20,7 @@ #include "xua.h" +#include "audiohw.h" #include "audioports.h" #include "mic_array_conf.h" #if (XUA_SPDIF_TX_EN) @@ -635,6 +636,9 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk, buffered _XUA_CLK_DIR port:32 ?p_bclk, buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC], buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC] + #if (XUA_USE_APP_PLL) + , client interface SoftPll_if i_softPll + #endif #if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE) , chanend c_spdif_out #endif @@ -663,6 +667,12 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk, unsigned divide; unsigned firstRun = 1; +#if (XUA_USE_APP_PLL) + /* Use xCORE.ai Secondary PLL to generate master clock + * This could be "fixed" for async mode or adjusted if in sync mode */ + i_softPll.init(DEFAULT_MCLK); +#endif + /* Clock master clock-block from master-clock port */ /* Note, marked unsafe since other cores may be using this mclk port */ configure_clock_src(clk_audio_mclk, p_mclk_in); @@ -800,6 +810,15 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk, } #endif /* Configure Clocking/CODEC/DAC/ADC for SampleFreq/MClk */ + + /* User should mute audio hardware */ + AudioHwConfig_Mute(); + + #if (XUA_USE_APP_PLL) + i_softPll.init(mClk); + #endif + + /* User code should configure audio harware for SampleFreq/MClk etc */ AudioHwConfig(curFreq, mClk, dsdMode, curSamRes_DAC, curSamRes_ADC); #if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) /* Notify clockgen of new mCLk */ @@ -809,6 +828,9 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk, /* Wait for ACK back from clockgen to signal clocks all good */ c_mclk_change :> int _; #endif + + /* User should unmute audio hardware */ + AudioHwConfig_UnMute(); } if(!firstRun) diff --git a/lib_xua/src/core/buffer/ep/ep_buffer.xc b/lib_xua/src/core/buffer/ep/ep_buffer.xc index a2e42199..2a7ee928 100644 --- a/lib_xua/src/core/buffer/ep/ep_buffer.xc +++ b/lib_xua/src/core/buffer/ep/ep_buffer.xc @@ -105,7 +105,11 @@ void XUA_Buffer( #endif , chanend c_aud #if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + #if(XUA_USE_APP_PLL) + , chanend c_swpll_update + #else , client interface pll_ref_if i_pll_ref + #endif #endif ) { @@ -141,7 +145,11 @@ void XUA_Buffer( , c_buff_ctrl #endif #if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , i_pll_ref + #if(XUA_USE_APP_PLL) + , c_swpll_update + #else + , i_pll_ref + #endif #endif ); @@ -190,8 +198,12 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #ifdef CHAN_BUFF_CTRL , chanend c_buff_ctrl #endif -#if XUA_SYNCMODE == XUA_SYNCMODE_SYNC +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + #if (XUA_USE_APP_PLL) + , chanend c_swpll_update + #else , client interface pll_ref_if i_pll_ref + #endif #endif ) { @@ -247,7 +259,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #if (NUM_USB_CHAN_IN > 0) unsigned bufferIn = 1; #endif - unsigned sofCount = 0; + int sofCount = 0; + int pllUpdate = 0; unsigned mod_from_last_time = 0; #ifdef FB_TOLERANCE_TEST @@ -294,7 +307,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out, unsigned iap_ea_native_interface_alt_setting = 0; unsigned iap_ea_native_control_to_send = 0; unsigned iap_ea_native_incoming = 0; - #endif #endif @@ -357,12 +369,16 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #ifndef LOCAL_CLOCK_MARGIN #define LOCAL_CLOCK_MARGIN (1000) #endif + +#if (!XUA_USE_APP_PLL) timer t_sofCheck; unsigned timeLastEdge; unsigned timeNextEdge; t_sofCheck :> timeLastEdge; timeNextEdge + LOCAL_CLOCK_INCREMENT; i_pll_ref.toggle(); +#endif + #endif while(1) @@ -427,7 +443,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out, /* Reset FB */ /* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback * to stabilise (i.e. sofCount == 128 to fire) */ - sofCount = 1; + sofCount = 0; + pllUpdate = 0; clocks = 0; clockcounter = 0; mod_from_last_time = 0; @@ -502,13 +519,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out, } #endif /* 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_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */ } break; } -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && (!XUA_USE_APP_PLL) case t_sofCheck when timerafter(timeNextEdge) :> void: i_pll_ref.toggle(); timeLastEdge = timeNextEdge; @@ -528,7 +545,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out, unsigned usbSpeed; int framesPerSec; GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed); - static int sofCount = 0; framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000; @@ -539,12 +555,27 @@ void XUA_Buffer_Ep(register chanend c_aud_out, sofCount += 1000; if (sofCount == framesPerSec) { + sofCount = 0; + pllUpdate++; +#if (!XUA_USE_APP_PLL) /* Port is accessed via interface to allow flexibilty with location */ i_pll_ref.toggle(); t_sofCheck :> timeLastEdge; - sofCount = 0; timeNextEdge = timeLastEdge + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN; +#endif } +#if (XUA_USE_APP_PLL) + // Update PLL @ 100Hz + if(pllUpdate == 10) + { + pllUpdate = 0; + unsigned short mclk_pt; + asm volatile("getts %0, res[%1]" : "=r" (mclk_pt) : "r" (p_off_mclk)); + outuint(c_swpll_update, mclk_pt); + outct(c_swpll_update, XS1_CT_END); + } +#endif + #elif (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC) /* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to @@ -646,7 +677,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out, clockcounter = 0; } #else - /* Assuming 48kHz from a 24.576 master clock (0.0407uS period) * 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. @@ -897,8 +927,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #endif #endif -#if XUA_HID_ENABLED - /* HID Report Data */ +#if (XUA_HID_ENABLED) + /* HID Report Data */ case XUD_SetData_Select(c_hid, ep_hid, result): hid_ready_flag = 0U; unsigned reportTime; @@ -911,7 +941,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #endif #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): if (is_ack) { diff --git a/lib_xua/src/core/main.xc b/lib_xua/src/core/main.xc index c4403acb..6bfb1b30 100755 --- a/lib_xua/src/core/main.xc +++ b/lib_xua/src/core/main.xc @@ -316,6 +316,9 @@ void usb_audio_io(chanend ?c_aud_in, , client interface pll_ref_if i_pll_ref , port ?p_for_mclk_count_aud #endif + #if (XUA_USE_APP_PLL) + , client interface SoftPll_if i_softPll + #endif ) { #if (MIXER) @@ -373,6 +376,9 @@ void usb_audio_io(chanend ?c_aud_in, #define AUDIO_CHANNEL c_aud_in #endif XUA_AudioHub(AUDIO_CHANNEL, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc +if (XUA_USE_APP_PLL) + , i_softPll +#endif #if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE) , c_spdif_tx #endif @@ -483,9 +489,14 @@ int main() #endif #endif -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) +#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC) && !XUA_USE_APP_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) interface pll_ref_if i_pll_ref; #endif + +#if (XUA_USE_APP_PLL) + interface SoftPll_if i_softPll; + chan c_swpll_update; +#endif chan c_sof; chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */ chan c_xud_in[ENDPOINT_COUNT_IN]; @@ -507,7 +518,7 @@ int main() { 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_APP_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref); #endif on tile[XUD_TILE]: @@ -520,6 +531,10 @@ int main() DFUHandler(dfuInterface, null); #endif +#if (XUA_USE_APP_PLL) + //XUA_SoftPll(tile[0], i_softPll, c_swpll_update); +#endif + /* Core USB task, buffering, USB etc */ { #ifdef XUD_PRIORITY_HIGH @@ -578,7 +593,13 @@ int main() #endif , c_mix_out #if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + #if (!XUA_USE_APP_PLL) + , i_pll_ref + #else + , c_swpll_update + #endif +#endif #endif ); //: @@ -593,6 +614,10 @@ int main() #endif /* XUA_USB_EN */ } +#if(XUA_USE_APP_PLL) + on tile[AUDIO_IO_TILE]: XUA_SoftPll(tile[0], i_softPll, c_swpll_update); +#endif + on tile[AUDIO_IO_TILE]: { @@ -616,6 +641,10 @@ int main() #endif #if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) , i_pll_ref +#endif +if (XUA_USE_APP_PLL) + , i_softPll +#endif , p_for_mclk_count_audio #endif ); diff --git a/lib_xua/src/core/user/audiohw/audiohw.c b/lib_xua/src/core/user/audiohw/audiohw.c new file mode 100644 index 00000000..a7713c2c --- /dev/null +++ b/lib_xua/src/core/user/audiohw/audiohw.c @@ -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; +} + diff --git a/lib_xua/src/core/user/audiohw/audiohw.h b/lib_xua/src/core/user/audiohw/audiohw.h new file mode 100644 index 00000000..aa839991 --- /dev/null +++ b/lib_xua/src/core/user/audiohw/audiohw.h @@ -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 diff --git a/lib_xua/src/core/user/audiostream/audiostream.h b/lib_xua/src/core/user/audiostream/audiostream.h index 1f27774e..4e1ce5e2 100644 --- a/lib_xua/src/core/user/audiostream/audiostream.h +++ b/lib_xua/src/core/user/audiostream/audiostream.h @@ -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. #ifndef _AUDIOSTREAM_H_ #define _AUDIOSTREAM_H_ -/* Functions that handle functions that must occur on stream start/stop e.g. DAC mute/un-mute - * - * THESE NEED IMPLEMENTING FOR A SPECIFIC DESIGN - * - * */ +/* 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. + */ -/* 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); -/* 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); -/* 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); -/* 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); -/* 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); -/* 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); #endif diff --git a/lib_xua/src/core/user/hid/user_hid.h b/lib_xua/src/core/user/hid/user_hid.h index d5b2b425..419682f2 100644 --- a/lib_xua/src/core/user/hid/user_hid.h +++ b/lib_xua/src/core/user/hid/user_hid.h @@ -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. /** * @brief Human Interface Device (HID) API * * 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. * Document section numbers refer to the HID Device Class Definition, version 1.11. */ -#ifndef __USER_HID_H__ -#define __USER_HID_H__ +#ifndef _USER_HID_H_ +#define _USER_HID_H_ #include @@ -34,22 +34,16 @@ typedef struct hidEvent_t { #define HID_MAX_DATA_BYTES ( 4 ) #define HID_EVENT_INVALID_ID ( 0x100 ) -#if XUA_HID_ENABLED - /** * \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) * 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 * If using Report IDs, this function places the Report ID in - * the first element; otherwise the first element holds the - * first byte of HID event data. + * the first element; otherwise the first element holds the + * first byte of HID event data. * * \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 @@ -57,9 +51,8 @@ typedef struct hidEvent_t { size_t UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BYTES ]); /** - * \brief Initialize HID processing + * \brief Initialize HID processing */ void UserHIDInit( void ); -#endif /* ( 0 < HID_CONTROLS ) */ -#endif /* __USER_HID_H__ */ +#endif /* _USER_HID_H_ */ diff --git a/lib_xua/src/core/user/hostactive/hostactive.h b/lib_xua/src/core/user/hostactive/hostactive.h index fa100d10..c4c2d302 100644 --- a/lib_xua/src/core/user/hostactive/hostactive.h +++ b/lib_xua/src/core/user/hostactive/hostactive.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. +/** + * @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); diff --git a/tests/test_sync_clk_basic/Makefile b/tests/test_sync_clk_basic/Makefile index 513f2614..86e4e277 100644 --- a/tests/test_sync_clk_basic/Makefile +++ b/tests/test_sync_clk_basic/Makefile @@ -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 \ -DBUS_SPEED=2 \ + -DXUA_USE_APP_PLL=0 \ $(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 \ -DBUS_SPEED=1 \ + -DXUA_USE_APP_PLL=0 \ $(TEST_FLAGS) TARGET = test_xs3_600.xn