Hi there
For proper playback of LE Audio, it's required to get the current time of the Bluetooth Controller.
In the LE Audio examples (nrf/application/nrf5340_audio) on the NRF5340 this is done with the functions in audio_sync_timer.c.
I've read the documentation and the actual code for this, which uses a combined timer of the RTC and a 1 MHz HF clock to construct the current time in us.
However, there seems to be a race condition between capturing both timers at the same time and the RTC tick resetting the HF timer.
When constantly polling audio_sync_timer_capture(), the time sometimes jumps ahead by about 30 us.
Here's sample code that could be placed at the end of the main() function to demonstrate this:
// Test monotonicity uint32_t timestamps_us[10]; int counter; for (counter = 0; counter < 1000000; counter++){ // progress bar if ((counter % 1000) == 0) { LOG_ERR("%u", counter); } // get some timestamps int i; for (i=0;i<10;i++){ timestamps_us[i] = audio_sync_timer_capture(); } // check if there's a negative delta int incorrect_entry = -1; for (i=1;i<10;i++){ if (timestamps_us[i-1] > timestamps_us[i]){ incorrect_entry = i-1; } } // report error if (incorrect_entry >= 0){ LOG_ERR("\nIncorrect timestamp:"); for (i=0;i<10;i++){ if (incorrect_entry == i){ LOG_ERR("t[%u] = %u <<--", i, timestamps_us[i]); } else { LOG_ERR("t[%u] = %u", i, timestamps_us[i]); } } break; } }
When running this, I get:
Incorrect timestamp: HL [00:00:02.332,122] <err> main: t[0] = 88708 HL [00:00:02.332,122] <err> main: t[1] = 88712 HL [00:00:02.332,122] <err> main: t[2] = 88745 UNEXPECTED HL [00:00:02.332,122] <err> main: t[3] = 88717 HL [00:00:02.332,122] <err> main: t[4] = 88719 HL [00:00:02.332,153] <err> main: t[5] = 88722 HL [00:00:02.332,153] <err> main: t[6] = 88725 HL [00:00:02.332,153] <err> main: t[7] = 88728 HL [00:00:02.332,153] <err> main: t[8] = 88731 HL [00:00:02.332,153] <err> main: t[9] = 88734
For testing, we've called the function twice in a row, and discarded the measurement when the difference between both readings was more than 10 us, but I imagine that code that requires the accurate Bluetooth time might even run in interrup context and/or blocked interrupts, so calling it multiple times is not ideal.
I'm not too familiar with the nRF5x peripherals. Would it be possible to correct this function to always report the correct time?
Thanks
Matthias