Skip to content

Commit 6bb4cb5

Browse files
tmon-nordicjhedberg
authored andcommitted
samples: usb: uac2: explicit: Fix SOF offset integer conversion glitch
Rework the formula used to convert timer CC values to SOF offset to eliminate a "division glitch" happening around SOF crossing, i.e. when the framestart shifts from being captured shortly before SOF to being captured shortly after SOF. When audio samples are consumed faster than nominal, i.e. when there is +1 samples every now and then, the reported SOF offset at High-Speed was going 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, "glitch" 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, ... With the fix the SOF offset goes as expected from 0 to -1, i.e. there is no jump from 0 to 7 around the SOF crossing and the reported SOF offset goes linearly (until it is correclty bumped from negative values back to positive values when +1 sample packet is transmitted on I2S). Signed-off-by: Tomasz Moń <[email protected]>
1 parent ff50dfb commit 6bb4cb5

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ static void update_sof_offset(struct feedback_ctx *ctx, uint32_t sof_cc,
272272
int sof_offset;
273273

274274
if (!IS_ENABLED(CONFIG_APP_USE_I2S_LRCLK_EDGES_COUNTER)) {
275-
uint32_t clks_per_edge;
275+
uint32_t nominator;
276276

277277
/* Convert timer clock (independent from both Audio clock and
278278
* USB host SOF clock) to fake sample clock shifted by P values.
@@ -282,18 +282,17 @@ static void update_sof_offset(struct feedback_ctx *ctx, uint32_t sof_cc,
282282
* when regulated and therefore the relative clock frequency
283283
* discrepancies are essentially negligible.
284284
*/
285-
clks_per_edge = sof_cc / ctx->counts_per_sof;
286-
sof_cc /= MAX(clks_per_edge, 1);
287-
framestart_cc /= MAX(clks_per_edge, 1);
285+
nominator = MIN(sof_cc, framestart_cc) * ctx->counts_per_sof;
286+
sof_offset = nominator / MAX(sof_cc, 1);
287+
} else {
288+
sof_offset = framestart_cc;
288289
}
289290

290291
/* /2 because we treat the middle as a turning point from being
291292
* "too late" to "too early".
292293
*/
293-
if (framestart_cc > ctx->counts_per_sof/2) {
294-
sof_offset = framestart_cc - ctx->counts_per_sof;
295-
} else {
296-
sof_offset = framestart_cc;
294+
if (sof_offset > ctx->counts_per_sof/2) {
295+
sof_offset -= ctx->counts_per_sof;
297296
}
298297

299298
/* The heuristic above is not enough when the offset gets too large.

0 commit comments

Comments
 (0)