@@ -213,11 +213,15 @@ static void setup_dma(audiobusio_pdmin_obj_t* self, uint32_t length,
213
213
}
214
214
dma_descriptor_create (audio_dma .descriptor , & descriptor_config );
215
215
216
+ // Do we need more values than will fit in the first buffer?
217
+ // If so, set up a second buffer chained to be filled after the first buffer.
216
218
if (length * words_per_sample > words_per_buffer ) {
217
219
block_transfer_count = words_per_buffer ;
218
220
descriptor_config .next_descriptor_address = ((uint32_t )audio_dma .descriptor );
219
221
if (length * words_per_sample < 2 * words_per_buffer ) {
220
- block_transfer_count = 2 * words_per_buffer - length * words_per_sample ;
222
+ // Length needed is more than one buffer but less than two.
223
+ // Subtract off the size of the first buffer, and what remains is the count we need.
224
+ block_transfer_count = length * words_per_sample - words_per_buffer ;
221
225
descriptor_config .next_descriptor_address = 0 ;
222
226
}
223
227
descriptor_config .block_transfer_count = block_transfer_count ;
@@ -309,18 +313,21 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
309
313
uint32_t remaining_samples_needed = output_buffer_length ;
310
314
while (values_output < output_buffer_length ) {
311
315
// Wait for the next buffer to fill
312
- while (tc_get_count_value (MP_STATE_VM (audiodma_block_counter )) == buffers_processed ) {
316
+ uint32_t block_counter ;
317
+ while ((block_counter = tc_get_count_value (MP_STATE_VM (audiodma_block_counter ))) == buffers_processed ) {
313
318
#ifdef MICROPY_VM_HOOK_LOOP
314
319
MICROPY_VM_HOOK_LOOP
315
320
#endif
316
321
}
317
- if (tc_get_count_value (MP_STATE_VM (audiodma_block_counter )) != (buffers_processed + 1 )) {
322
+ if (block_counter != (buffers_processed + 1 )) {
323
+ // Looks like we aren't keeping up. We shouldn't skip a buffer.
318
324
break ;
319
325
}
320
326
321
327
// The mic is running all the time, so we don't need to wait the usual 10msec or 100msec
322
328
// for it to start up.
323
329
330
+ // Flip back and forth between processing the first and second buffers.
324
331
uint32_t * buffer = first_buffer ;
325
332
DmacDescriptor * descriptor = audio_dma .descriptor ;
326
333
if (buffers_processed % 2 == 1 ) {
@@ -342,15 +349,13 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
342
349
}
343
350
values_output ++ ;
344
351
}
352
+
345
353
buffers_processed ++ ;
346
354
347
- // See if we need to transfer less than a full buffer for the remaining needed samples.
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.
348
358
remaining_samples_needed = output_buffer_length - values_output ;
349
- if (remaining_samples_needed > 0 && remaining_samples_needed < samples_per_buffer ) {
350
- descriptor -> BTCNT .reg = remaining_samples_needed ;
351
- descriptor -> DSTADDR .reg = ((uint32_t ) buffer ) + remaining_samples_needed * words_per_sample ;
352
- descriptor -> DESCADDR .reg = 0 ;
353
- }
354
359
}
355
360
356
361
stop_dma (self );
0 commit comments