Skip to content

Commit e44fbca

Browse files
dhalberttannewt
authored andcommitted
PDMIn: Make last DMA buffer be exactly the right length.
1 parent 7918714 commit e44fbca

File tree

1 file changed

+22
-4
lines changed
  • atmel-samd/common-hal/audiobusio

1 file changed

+22
-4
lines changed

atmel-samd/common-hal/audiobusio/PDMIn.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
334334
buffer = second_buffer;
335335
descriptor = &second_descriptor;
336336
}
337-
// Decimate and filter the last buffer
337+
// Decimate and filter the buffer that was just filled.
338338
uint32_t samples_gathered = descriptor->BTCNT.reg / words_per_sample;
339339
// Don't run off the end of output buffer. Process only as many as needed.
340340
uint32_t samples_to_process = min(remaining_samples_needed, samples_gathered);
@@ -352,10 +352,28 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
352352

353353
buffers_processed++;
354354

355-
// We might need fewer than an entire of samples, but we won't try to alter the
356-
// last DMA, which might already be in progress, so we'll just throw away some
357-
// samples at the end.
355+
// Compute how many more samples we need, and if the last buffer is the last
356+
// set of samples needed, adjust the DMA count to only fetch as necessary.
358357
remaining_samples_needed = output_buffer_length - values_output;
358+
if (remaining_samples_needed <= samples_per_buffer*2 &&
359+
remaining_samples_needed > samples_per_buffer) {
360+
// Adjust the DMA settings for the current buffer, which will be processed
361+
// after the other buffer, which is now receiving samples via DMA.
362+
// We don't adjust the DMA in progress, but the one after that.
363+
// Timeline:
364+
// 1. current buffer (already processed)
365+
// 2. alternate buffer (DMA in progress)
366+
// 3. current buffer (last set of samples needed)
367+
368+
// Set up to receive the last set of samples (don't include the alternate buffer, now in use).
369+
uint32_t samples_needed_for_last_buffer = remaining_samples_needed - samples_per_buffer;
370+
descriptor->BTCNT.reg = samples_needed_for_last_buffer * words_per_sample;
371+
descriptor->DSTADDR.reg = ((uint32_t) buffer)
372+
+ samples_needed_for_last_buffer * words_per_sample * sizeof(buffer[0]);
373+
374+
// Break chain to alternate buffer.
375+
descriptor->DESCADDR.reg = 0;
376+
}
359377
}
360378

361379
stop_dma(self);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy