Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDMIn.record() infinite loop on SAMD21 #5458

Closed
dhalbert opened this issue Oct 12, 2021 · 2 comments · Fixed by #5484
Closed

PDMIn.record() infinite loop on SAMD21 #5458

dhalbert opened this issue Oct 12, 2021 · 2 comments · Fixed by #5484
Assignees
Milestone

Comments

@dhalbert
Copy link
Collaborator

dhalbert commented Oct 12, 2021

CircuitPython version

Adafruit CircuitPython 7.0.0 on 2021-09-20; Adafruit CircuitPlayground Express with samd21g18

Code/REPL

# This is a pruning of https://learn.adafruit.com/perk-up-ears/code 
# test.py

import array
import board
import audiobusio

NUM_SAMPLES = 90

mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
                       sample_rate=16000, bit_depth=16)


samples = array.array('H', [0] * NUM_SAMPLES)
mic.record(samples, len(samples))

Behavior

Adafruit CircuitPython 7.0.0 on 2021-09-20; Adafruit CircuitPlayground Express with samd21g18
>>> import test
[infinite loop - CIRCUITPY disappears]

Description

Also fails as code.py, but easier to control as test.py. Does not necessarily fail if this is not the first thing (e.g. does not crash after a ctrl-D when a previous version had the mic.record() commented out).

EDIT: determined this is an infinite loop, not a crash per se.

Additional information

Not tested on any other boards yet. Found by @ Meg in discord, 10:30pm and following (ET) 2021-10-11. Does not fail in 6.3.0.

@dhalbert dhalbert added this to the 7.x.x milestone Oct 12, 2021
@dhalbert dhalbert self-assigned this Oct 13, 2021
@dhalbert
Copy link
Collaborator Author

dhalbert commented Oct 13, 2021

I did a bisect on this, and it turns out to be

When PDMIn.record() happens, it now loops forever inside common_hal_audiobusio_pdmin_record_to_buffer().

@tannewt @DavePutz
common_hal_audiobusio_pdmin_record_to_buffer() uses the event system for handling incoming DMA I2S data. I do not know yet why #5100 broke this, but one or the other is making some assumption about the event system setup that is not shared by the other. If you have an idea, I'd be very interested.

@dhalbert
Copy link
Collaborator Author

I am on the track of something. Commenting out the !event_interrupt_active(event_channel) check loop below prevents the infinite loop. That test is probably being misled by the new use of the event system.

        // Wait for the next buffer to fill
        //uint32_t wait_counts = 0;
        #ifdef SAMD21
          #define MAX_WAIT_COUNTS 1000
        #endif
        #ifdef SAM_D5X_E5X
          #define MAX_WAIT_COUNTS 6000
        #endif
        // If wait_counts exceeds the max count, buffer has probably stopped filling;
        // DMA may have missed an I2S trigger event.
        // while (!event_interrupt_active(event_channel) && ++wait_counts < MAX_WAIT_COUNTS) {
        //     RUN_BACKGROUND_TASKS;
        // }

@dhalbert dhalbert changed the title PDMIn.record() crashes SAMD21 (at least) PDMIn.record() infinite loop on SAMD21 Oct 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant