Skip to content

Commit

Permalink
applications: nrf5340_audio: Fix audio sync timer off by one tick
Browse files Browse the repository at this point in the history
Fix audio sync timer off by one tick when TASKS_CAPTURE and
TASKS_CLEAR are in a race condition.

TASKS_CAPTURE is prioritized hence can have +30 us more when
RTC tick to trigger TASKS_CLEAR overlap with the capture of
the value.

The fix here initiates the RTC and TIMER sync only when a
capture is requested by the audio subsystem or the timestamp
request. This is in contrast to earlier implementation when
TIMER was sync on every RTC tick.

If a capture is requested in short duration of 30 us then
the race will still be present, but a subsequent fix for it
will be provided in a new commit.

Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
  • Loading branch information
cvinayak committed Dec 11, 2024
1 parent e3e52df commit 5bcc223
Showing 1 changed file with 31 additions and 8 deletions.
39 changes: 31 additions & 8 deletions applications/nrf5340_audio/src/modules/audio_sync_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ static uint32_t timestamp_from_rtc_and_timer_get(uint32_t ticks, uint32_t remain
{
const uint64_t rtc_ticks_in_femto_units = 30517578125UL;
const uint32_t rtc_overflow_time_us = 512000000UL;
uint64_t remainder_fs;

remainder_fs = (uint64_t)remainder_us * 1000000000UL;

if (remainder_fs > rtc_ticks_in_femto_units) {
nrfx_dppi_t dppi = NRFX_DPPI_INSTANCE(0);
nrfx_err_t ret;

ret = nrfx_dppi_channel_enable(&dppi, dppi_channel_timer_sync_with_rtc);
if (ret - NRFX_ERROR_BASE_NUM) {
LOG_ERR("nrfx DPPI channel enable error (timer sync): %d", ret);
}

nrfx_rtc_tick_enable(&audio_sync_lf_timer_instance, true);
}

remainder_fs %= rtc_ticks_in_femto_units;
remainder_us = remainder_fs / 1000000000UL;

return ((ticks * rtc_ticks_in_femto_units) / 1000000000UL) +
(num_rtc_overflows * rtc_overflow_time_us) + remainder_us;
Expand Down Expand Up @@ -128,6 +146,19 @@ static void unused_timer_isr_handler(nrf_timer_event_t event_type, void *ctx)

static void rtc_isr_handler(nrfx_rtc_int_type_t int_type)
{
if (int_type == NRFX_RTC_INT_TICK) {
nrfx_dppi_t dppi = NRFX_DPPI_INSTANCE(0);
nrfx_err_t ret;

nrfx_rtc_tick_enable(&audio_sync_lf_timer_instance, false);

ret = nrfx_dppi_channel_disable(&dppi, dppi_channel_timer_sync_with_rtc);
if (ret - NRFX_ERROR_BASE_NUM) {
LOG_ERR("nrfx DPPI channel disable error (timer sync): %d", ret);
return;
}
}

if (int_type == NRFX_RTC_INT_OVERFLOW) {
num_rtc_overflows++;
}
Expand Down Expand Up @@ -245,14 +276,6 @@ static int audio_sync_timer_init(void)
nrf_timer_subscribe_set(audio_sync_hf_timer_instance.p_reg, NRF_TIMER_TASK_CLEAR,
dppi_channel_timer_sync_with_rtc);

ret = nrfx_dppi_channel_enable(dppi_channel_timer_sync_with_rtc);
if (ret - NRFX_ERROR_BASE_NUM) {
LOG_ERR("nrfx DPPI channel enable error (timer sync): %d", ret);
return -EIO;
}

nrfx_rtc_tick_enable(&audio_sync_lf_timer_instance, false);

nrfx_rtc_enable(&audio_sync_lf_timer_instance);

LOG_DBG("Audio sync timer initialized");
Expand Down

0 comments on commit 5bcc223

Please sign in to comment.