Hello,
I am developing a USB to I2s bridge using the xk-audio-316-mc-ab and sw_usb_audio 8.1.0. I want to sync the XMOS USB audio master clock with the crystal oscillator on an external PCB. It is ultra low phase noise, and I plan to use this clock for subsequent processing before sending the I2S stream to the DAC.
Is it possible to use the CS2100CP fractional N clock multiplier on the XMOS board to create the MCLK_XMOS signal and sync it with my own low phase noise oscillator?
It seems like it should be possible if I connect my oscillator to pin 5 of the CS2100--the PLL_SYNC signal.
I am running the application
# Audio Class 2, Async, I2S Master, 2xInput, 2xOutput
2AMi2o2xxxxxx
with build flags -DUSE_FRACTIONAL_N=1 -DXUA_USE_SW_PLL=0 -DXUA_SPDIF_RX_EN=1
I have gotten MCLK_DIR and EXT_PLL_SEL both low, so the CS2100CP is creating the master clock instead of the sw pll. But I see on the scope that the XMOS is driving PLL_SYNC with some 300Hz signal. Where does this come from, and can I turn off this output and use my own oscillator to drive PLL_SYNC?
If this is not possible, what can I do instead to sync with external clock? Should I use the Word Clock in BNC connector on the board? The manual hints at this:
"It multiplies up the PLL_SYNC signal which is generated by the xcore.ai device based on the desired external source (so S/PDIF in frame signal or word clock in)." But I cant find any code showing how to do it.
Thanks
USB to I2S and synchronizing mclk with an external clock
-
- Member
- Posts: 15
- Joined: Sat Dec 16, 2023 11:44 pm
-
- Member
- Posts: 8
- Joined: Tue Jul 16, 2024 9:52 am
- Location: Bristol, UK
I don't know of any code using the word clock in, but I can at least explain the 300Hz signal: this is generated by the clockGen thread. This thread counts the S/PDIF samples that are received to determine the incoming sample rate. With the application PLL disabled, a pin is toggled to generate the input to the CS2100. The frequency of 300Hz is chosen as a convenient frequency that can be generated by the xcore based on the supported sample rates of the incoming S/PDIF signal.
The relevant code is here: https://github.com/xmos/lib_xua/blob/v4 ... en.xc#L653
There isn't a configuration option to stop this while also having the application PLL disabled, so if you want to drive PLL_SYNC from your own source you would need to modify this code to stop the generation of the PLL reference in clockGen. This isn't trivial because there is a timer-based fallback which approximates the transitions on the pin if they aren't updated from the function counting S/PDIF samples.
The relevant code is here: https://github.com/xmos/lib_xua/blob/v4 ... en.xc#L653
There isn't a configuration option to stop this while also having the application PLL disabled, so if you want to drive PLL_SYNC from your own source you would need to modify this code to stop the generation of the PLL reference in clockGen. This isn't trivial because there is a timer-based fallback which approximates the transitions on the pin if they aren't updated from the function counting S/PDIF samples.
XMOS, Senior Software Engineer
-
- Member
- Posts: 15
- Joined: Sat Dec 16, 2023 11:44 pm
Ok, I think I understand the explanation. The sample rate has to be determined in order to use an incoming SPDIF signal. What if I only use USB? Does the sample rate still get determined by counting the received frames?
I guess more importantly, does the 300Hz signal in concert with the PLL in the CS2100 allow for synchronous operation with the incoming data stream for SPDIF and USB? If so, that would mean I cannot just inject a 24.576MHz clock onto XMOS pin 7 because it would be asynchronous. But maybe I can use my external oscillator as the timing reference for the CS2100 as the datasheet shows: If I understand correctly, asynchronous USB mode allows the XMOS, at its MCLK rate, to request data from the computer. So, I will try to configure the XMOS to use asynchronous USB mode and use neither the software PLL nor the CS2100 PLL but instead directly connect my offboard MCLK. Ill see if that works.
You do not have the required permissions to view the files attached to this post.
-
Verified
- XCore Legend
- Posts: 1070
- Joined: Thu Dec 10, 2009 9:20 pm
- Location: Bristol, UK
What frequency is this external oscillator?
If its an "audio" freq, just use that directly and don't use any of the clock generation on the XMOS device/board.
If you need to support multiple mclk frequencies (i.e. 44.1 AND 48.k then some more thought will be required since the USB host expects to be in control of the sample rate and, in turn, the master clock frequency.
If its an "audio" freq, just use that directly and don't use any of the clock generation on the XMOS device/board.
If you need to support multiple mclk frequencies (i.e. 44.1 AND 48.k then some more thought will be required since the USB host expects to be in control of the sample rate and, in turn, the master clock frequency.
Technical Director @ XMOS. Opinions expressed are my own
-
- Member
- Posts: 15
- Joined: Sat Dec 16, 2023 11:44 pm
Yes Ross, they are audio frequencies 49.152 and 45.158, divided in half by a clock divider IC.
I could not figure out what combination of build flags work to shut off both the internal sw pll and the cs2100, so I ended up sending the disable command to the cs2100 config register to shut it off. Then I could inject my oscillator on R93 of the board and it works well enough for prototyping. The USB audio is now synchronous with my MCK.
If the sample rate changes in the USB host, does the XMOS processor get notified somehow? Or does it have some way to detect the sample rate? The oscillators on my external board have disable pins, so I could send a signal from the XMOS to enable the correct oscillator to match the sample rate.
I could not figure out what combination of build flags work to shut off both the internal sw pll and the cs2100, so I ended up sending the disable command to the cs2100 config register to shut it off. Then I could inject my oscillator on R93 of the board and it works well enough for prototyping. The USB audio is now synchronous with my MCK.
If the sample rate changes in the USB host, does the XMOS processor get notified somehow? Or does it have some way to detect the sample rate? The oscillators on my external board have disable pins, so I could send a signal from the XMOS to enable the correct oscillator to match the sample rate.
-
Verified
- XCore Legend
- Posts: 1070
- Joined: Thu Dec 10, 2009 9:20 pm
- Location: Bristol, UK
Just provide your own versions of AudioHwInit() and AudioHwConfig()
AudioHwInit() gets called once at startup. AudioHwConfig() gets called on SR (and format) change.
Blank implementations of these will mean no clocks are setup, or any other external hardware for that matter.
There is full documentation of this in https://github.com/xmos/sw_usb_audio/re ... _audio.pdf
Add your clock selection logic into these functions :)
AudioHwInit() gets called once at startup. AudioHwConfig() gets called on SR (and format) change.
Blank implementations of these will mean no clocks are setup, or any other external hardware for that matter.
There is full documentation of this in https://github.com/xmos/sw_usb_audio/re ... _audio.pdf
Add your clock selection logic into these functions :)
Technical Director @ XMOS. Opinions expressed are my own
-
- Member
- Posts: 15
- Joined: Sat Dec 16, 2023 11:44 pm
Yes! I got that working. AudioHwConfig() is called when the sample rate changes and the value is available in samFreq. Thank you!