Audio Sink Timing in ASCC

We have some questions on Audio Sink Timing in ASCC.

  1. As 1st RF frame pulse is generated by “sync word”, how is 2nd RF frame pulse generated for reading 2nd AUDIOSINK_PHASE_CNT for measuring audio sink cycles? Is it generated by “sync word” of 2nd packet in 2nd interval time or it is still be generated by 1st interval time? If it is still from 1st interval time, what root cause is it generated or there is 2nd sync word placed near ending byte of 1st packet?
  2. For AUDIOSINK_CFG register, we can set it to 1 ~ 16. How do we set its value. May we say if the data packet is longer, we set bigger value while short packet does smaller value. For example, whether the payload is 300 bytes with value = 16 while the payload is 20 bytes with value = 2. Is it possible to occur that the longer payload tranmitted time is larger than 16 audio sink cycles’ time set at AUDIOSINK_CFG = 16 (max) so that ASCC only measures the partial packet data, not a complete one? What result will it happen? Thanks for your feedback.

The ASCC is able to measure two values: AUDIOSINK_PHASE_CNT and AUDIOSINK_PERIOD_CNT
The units of the measurements are SYSCLK cycles.

If the Audio Sink Clock is derived from SYSCLK then you don’t need to make that measurement since it is known. It sounds like this describes your application, so the rest of the paragraph is for others. For cases where the Audio Sink Clock is derived from a clock asynchronous to SYSCLK, the ASCC can be configured to measure the number of SYSCLK cycles over 1-16 Audio Sink Clock cycles. Using the long interval will allow the measurement of the Audio Sink Clock more accurately. If the Audio Sink Clock is measured over N cycles, the measurement resolution of an Audio Sink Clock period can be measured with a resolution of 1/N SYSCLK periods.

The AUDIOSINK_CNT measurement requires two frame pulses for the measurement as you observe. At the 1st frame pulse this value will be read and reset to zero and the reading should be discarded. The AUDIOSINK_PHASE_CNT value should be read and stored. Now on subsequent frame pulse interrupts the AUDIOSINK_CNT value is valid. That reading plus the difference between the current and prior phase count readings plus the known AUDIOSINK_PERIOD_CNT allows the calculation of the number of SYSCLKs between the frame pulses.

The hardware reference manual section 13.3 covers these values, the associated registers and interrupts, and the recommended measurement procedures in detail.

Thank you for using the Community Forum.

Dear Jamie,

Thanks a lot for your clear comments.

As to subsequent frame pulse (2nd frame pulse), does it generate in last CRC byte of data packet?

The frame sync pulse is generated upon reception of the sync word which follows the preamble in the BLE packet.

As each data packet only includes one sync word, the 1st frame sync pulse happens at 1st data packet. The 2nd frame sync pulse is supposed to be from 2nd data packet. Assuming the connection interval is 40ms, master and slave will include active and standby time. The running clock (SYSCLK) frequency in active and standby time are different, how do we use ASCC? If 1st and 2nd frame sync pulses are in the same connection interval. Whether there is a 2nd sych word in the ending of data packet? Thanks.

Hi, Henry: the ASCC we can use for measure the timing of the frame periods of a BLE/RF host relative to the internal audio sampling rate or that of a connected external device.

at first you can calculate the audio sink period by
image
and then to calculate the audio sink clock cycles which is what we want

Hi Snow,

Thanks for your feedback. I am not sure if I really understand definitions of these counter, period and cycles in two equations. Let me assume value for them.
Assuming
AUDIOSINK_CFG_PERIODS = 16,
periodSYSTEM = 1/16MHz
AUDIOSINK_PERIOD_CNT = 1000 (= 16MHz/16KHz if USRCLK = 16KHz)


period= (1000/(16+1)) x 1/16MHz = 3.67us. Is it correct?

Assuming
AUDIOSINK_CNT[i] = 16
AUDIOSINK_PHASE_CNT[i-1] = 20
UDIOSINK_PHASE_CNT[i] = 16
AUDIOSINK_PERIOD_CNT[i-1] = 992


audio sink clock cycles = 16 + (20 - 16) /( 992/16 + 1) = 16 x 4/63 = 16.03
Is it correct on audio sink clock cycles = 16.03? Is it AUDIOSINK CNT [i-1] (= previous AUDIOSINK CNT) for equation calculation next time?

First, the equation is a little confusing in that in the denominator “AUDIOSINK_CFG_PERIODS” refers to the register value which is between 0 and 15. If you’ve set the register to 15, then the measurement interval is 16 periods and 16 is the value to use in the denominator of the equation.

period= (1000/(16+1)) x 1/16MHz = 3.67us. Is it correct?

This is not possible because the AUDIOSINK_CFG_PERIODS register value is maximum of 15. Assuming that’s the value in the register, and that the AUDIOSINK_PERIOD_CNT value is 1000, then

period= (1000/(15+1)) x 1/16MHz = 3.90625us (256kHz)

However, in your example you derived what you expect to see in AUDIOSINK_PERIOD_CNT as 16MHz/16kHz if USRCLK = 16kHz. Since the measurement interval is 16 AUDIOSINK clock periods, the expected value is actually 16 * 16MHz/16kHz = 16000. And in that case:

period=(16000/16)x 1/16MHz = 62.5us (16kHz)

So we can see that the calculated period is indeed the period of the sink clock.

Assuming
AUDIOSINK_CNT[i] = 16
AUDIOSINK_PHASE_CNT[i-1] = 20
UDIOSINK_PHASE_CNT[i] = 16
AUDIOSINK_PERIOD_CNT[i-1] = 992

audio sink clock cycles = 16 + (20 - 16) /( 992/16 + 1) = 16 x 4/63 = 16.03
Is it correct on audio sink clock cycles = 16.03? Is it AUDIOSINK CNT [i-1] (= previous AUDIOSINK CNT) for equation calculation next time?

There is a missing parenthesis in the equation, and the “x” in “16 x 4/63” should be an addition. Given your input values it should be:
audio sink clock cycles = 16 + (20 - 16) /( 992/(16 + 1)) = 16 + 4/58.353 = 16.07

However, given your indicated setup where AudioSinkClock is approximately 16kHz but presumably asynchronous to SYSCLK, the value 992 is much lower than expected. It would more likely be 16x that value, but not exactly 16x, so a good illustrative value would be something like 15990. With that correction, a phase shift of 4 sysclk cycles (20 - 16) over the measurement interval would yield:
audio sink clock cycles = 16 + (20-16)/(15990/(15+1)) = 16.004

Hi Jamie,

Thanks a lot for quite clear explanation how to use the 2 equations.

I have two more questions.

  1. Where is AUDIOSINK_PERIOD_CNT[i-1] stored for next calculation of equation about AUDIOSINK_PERIOD_CNT[i] . Whether it is automatically stored in AUDIO_SINK_PERIODS_1 ~ 16 in PERIODS_CFG in 13.3.1.2 AUDIOSINK_CFG.
  2. As to phase counter application, RSL10 hardware reference mentions 4-FSK, Whether RSL10 uses 4 phases for frequency drift measurement at phase counter? Thanks.

Allow me to add one more question. After running ASCC equations, how does master notify slave of clock frequency correction or master corrects its clock frequency to match slave? Thanks.

The software application is responsible for storing AUDIOSINK_PERIOD_CNT[i] for use on the next interrupt as AUDIOSINK_PERIOD_CNT[i-1]

4-FSK is referenced in the RF Front-End section of the hardware reference manual. This is unrelated to the measurements being made by the ASCC. The ASCC is measuring the timing difference between the arrival of the frames vs the configured sink clock.

After running ASCC equations, how does master notify slave of clock frequency correction or master corrects its clock frequency to match slave?

In typical audio applications, the clock difference would be given to the ASRC block which would perform rate adaptation on the audio samples. You previously stated in your application you did not need audio, but you needed a way to measure the clock difference which is what this topic has been about. Since your application is specific to you, it’s not clear how to advise you on what to do with the measurement.

For data streaming applications, the options are usually:
a) run a timer based on sysclk, then stop and restart the timer every so often once enough phase error has built up to keep it in phase with the master
b) use a functional block such as the ASRC to rate adapt the data from the master to the sink clock
c) send information back to the master to have it adjust it’s data generation rate.

If you’re not streaming data and simply need to keep Real Time Clocks synchronized, then you’d add or subtract the notion of real time by the measured frequency difference between master and sink.

Really, its up to your application’s needs as to how to rate adapt if you’re implementing your own custom protocol.

Dear Jamie,

Thanks a lot for your several suggestions on handling clock difference.

We are thinking our idea whether it follows (a) of your suggestions. Let me describe it and help review if our idea is correct.

  1. Assuming the connection interval is 40ms, master transmits a data packet to slave twice. The 1st time data packet starts to transmit at time = 0ms. Data transmission time takes 2ms, 2nd time data packet transmits at time = 20ms. Also, the data transmission can be finished in 2ms like 1st time data packet. The operation steps of every connection interval are shown as follows:
    (1) Transmission of data (TX): 2ms.
    (2) No TX: 18ms
    (3) TX: 2ms.
    (4) No Tx: 18ms.
    (5) Go back to step (1).
    Here, may we say master prepares two audio sink clocks for slave ASCC measurement?
  2. The slave operates ASCC by steps below.
    (1) Assuming Slave can use ASCC to read two audio sink clocks from master.
    (2) Next, using 1st AUDIOSINK_PHASE_CNT and 2nd AUDIOSINK_PHASE_CNT can get a new Audiosink Clock Cycles.
    (3) After Audiosink Clock Cycles are measured, Audiosink Periods CNT can be got as well.
    (4) Clock difference of master and slave = 2 (fixed Audiosink Clock Cycles) x 40ms (fixed period for slave) – Audiosink Clock Cycles (measured and variable master data) x 40ms (close to 40ms period from master). (4) Go back step (2).
  3. RSL10 supports RTC crystal tuning in standby and active modes. However, it seems RSL10 doesn’t support 48MHz clock trimming in active mode in RSL10 hardware reference. May RSL10 let us trim 48MHz crystal clock like ASRC trimming in active mode? Is there any side effect when trimming 48MHz cyrstal clock for slave. Thanks.

After the step 1 sequence the ASCC would have two BLE frame pulses for measuring the configured sink clock. There would likely be many audio sink clock cycles between those two frame pulses.

As for step 2, you seem to be suggesting the ASCC would be used to measure the difference in clock rates for one pair of frames, then for the next pair of frames which gives the 40ms update rate. However the suggested way of using the ASCC is to update the measurement every frame, or once every 20ms in your case. Consider the drawing below. At packet 1, the first AUDIOSINK_PHASE_CNT is measured. At packet 2, the second AUDIOSINK_PHASE_CNT is measured and the clock difference may be determined. The second AUDIOSINK_PHASE_CNT is stored as the “First” and at packet 3 the new AUDIOSINK_PHASE_CNT is the “second” and the difference in clock rates can be measured again, allowing the clock measurement to be updated every 20ms.
image

There is no way to tune the crystal oscillator frequency on the RSL10 side.

Thanks a lot for you suggestions. Let me confirm if my understanding is correct.

  1. When master transmits the packet to slave, is the Sink clock from USRCLK in slave (not from many audio samples of master)?
  2. As to clock difference, we measure AUDIOSINK_PHASE_CNT for each packet. These AUDIOSINK_PHASE_CNT values are assumed like 100 (1st time), 110, 105, 120, 130 (last). The slave knows max clock difference is 30 (= 130 -100). It seems to be your nice understanding and previous suggestion for us. It looks workable for our application.
  3. We don’t realize why ASRC can adapt source frequency (audio sample rate) to match sink frequency. For our application by AUDIOSINK_PHASE_CNT and packet, 48MHz doesn’t support clock trimming like ASRC. Which way is for ASRC clock trimming? May our application follow ASRC clock trimming way or we need to use ASRC for clock difference trimming? Thanks.

Could you help reply some questions below?

  1. Where may we set audio sink clock frequency? We don’t find out its setting in hardware reference.
  2. Does an audio sink clock cycle include left and right channels’ audio?
  3. For data streaming applications, “a) run a timer based on sysclk, then stop and restart the timer every so often once enough phase error has built up to keep it in phase with the master”, could you describe more on how to handle it. (1) It seems not to use AUDIOSINK_PERIOD_CNT. (2) Which way in RSL10 can let master and slave start and stop their timers in sync? After that, we do timer data comparison (phase error check) for clock difference. Thanks.

Where may we set audio sink clock frequency? We don’t find out its setting in hardware reference.

The Hardware Reference Manual describes the audio sink clock as measured by the ASCC on page 389. It is sourced from a DIO or the STANDBYCLK. So to measure the local SYSCLK vs the remote clock (as indicated by the arriving BLE Frame pulses) you can generate a USRCLK, send it out on a DIO, loop it back on another DIO and configure that DIO as the audio sink clock input to the ASCC.

Does an audio sink clock cycle include left and right channels’ audio?

Typically this is the case but his depends entirely on your application and hardware configuration.

For data streaming applications, “a) run a timer based on sysclk, then stop and restart the timer every so often once enough phase error has built up to keep it in phase with the master”, could you describe more on how to handle it. (1) It seems not to use AUDIOSINK_PERIOD_CNT. (2) Which way in RSL10 can let master and slave start and stop their timers in sync? After that, we do timer data comparison (phase error check) for clock difference.

This line of questioning makes it sound like you are trying to synchronize audio between a remote source clock and the local sink clock which is what the ASRC block is designed to do. An example of the usage of the ASRC block can be found in the remote_mix_rx_raw project. The other proposed ideas require some more work and we don’t have example code for them.

To answer the questions directly: There is no method to start and stop timers in the remote master and local slave in sync. The proposed idea is that once you know the difference in rate between the local clock and remote clock, you can calculate the amount of phase shift between the local and remote clocks over some time interval. Say for example we know that the local clock is 20ppm faster than the remote. You could use a local timer running at the sample rate of 16kHz based on the local clock. Over a period of 0.1s the local clock would be ahead of the remote clock by 0.1 * 20e-6 * 16000 = 0.032 samples. With a 16MHz SYSCLK, that would be 0.032 / 16000 * 8000000 = 160 SYSCLK cycles. So every 0.1s you’d stop the local timer for 160 cycles and restart it to keep it in phase with the remote clock. Stopping it for exactly 160 SYSCLK cycles may be challenging, but as you’re continuously measuring the phase error between the local and remote clocks you can continuously make these periodic adjustments based on the latest measurement and accumulated error.

Honestly though, the ASRC is meant for rate adapting audio samples. Initially you were suggesting you didn’t want to send audio but wanted to keep the slave sync’d with the master for some other purpose. If you are processing audio, I’d suggesting making use of the ASRC.

I’m just now seeing this prior post. The ASRC does not trim the local clock. Rather it performs sample rate conversion. Essentially it is inserting or removing samples from the sink to match the rate of the incoming samples. A rudimentary implementation of rate adaptation is to do just that. However that could sound bad. Instead the ASRC uses interpolation to up the sample rate to a much higher rate, then decimation to reduce the sample rate to the desired fraction of the incoming rate. In this way the audio is rate adapted yet quality is preserved. So it’s not the clocks being adjusted to be in sync, but the audio is being resampled from the source frequency to match the sink frequency.

Hi Jamie,
Thanks a lot for clear explanation on differences of ASRC, clock and timer. It is quite helpful to guide us to select data packet, not audio transmission and a timer running. We are sorry very much to bother you for long time and indeed obtain great supports.

1 Like

No apology is necessary. The Community Forum is for open discussion and building a store of knowledge for all to benefit. Thank you for contributing.