zephyr: Add PDM microphone support
Description
There has been discussion about adding PDM microphone support to the ESP32 I2S driver (#14176 ).
Seeed Studio have written a basic PDM driver for Zephyr: https://github.com/Seeed-Studio/micropython-seeed-boards/blob/master/src/cmodules/modpdm/modpdm.c
This PDM class is not related to I2S (though of course some ports may use I2S hardware to support PDM microphones).
It currently implements a blocking read that returns a bytearray, but would be more useful with asyncio support (like machine.I2S).
Code Size
This can be optionally enabled with CONFIG_AUDIO, CONFIG_AUDIO_DMIC, and CONFIG_AUDIO_DMIC_NRFX_PDM (for the NRF parts), as well as enabling the PDM peripheral in the devicetree overlay file.
I'd be willing to bring their code over to test, but may need some help with adding the asyncio support.
Implementation
I intend to implement this feature and would submit a Pull Request if desirable
Code of Conduct
Yes, I agree
zephyr: Add machine.PDM class for digital microphone support.
Summary
This PR implements a new machine.PDM class for the Zephyr port that provides access
to PDM (Pulse Density Modulation) microphones through Zephyr's DMIC subsystem.
Key features:
- Blocking mode audio capture with configurable sample rates (8-48kHz)
- Support for 16-bit and 32-bit sample depths
- Mono and stereo channel configurations
- Ring buffer (default 8KB) to decouple hardware DMA from Python code
- Proper resource management with memory slab allocation
- Compatible API design following machine.I2S patterns
Implementation details:
- Port-independent interface in extmod/machine_pdm.c
- Zephyr-specific implementation in ports/zephyr/machine_pdm.c
- Uses Zephyr's DMIC API with polling (dmic_read)
- Ring buffer cleared on each blocking read to ensure fresh data
- Kconfig option
CONFIG_MICROPY_PY_MACHINE_PDMfor conditional compilation
Board support added for XIAO BLE nRF52840 Sense:
- Enable PDM peripheral and microphone power regulator in device tree
- Configure audio subsystem and DMIC driver
- Tested with MSM261D3526H1CPM PDM microphone
Documentation includes:
- Complete API reference with constructor, methods, and constants
- Configuration instructions (Kconfig and device tree)
- Working examples: basic capture, WAV file recording, stereo
- Troubleshooting guide based on actual testing
- Notes on microphone startup time (500ms settling) and DC offset
Known limitations:
- Currently supports blocking mode only
- Non-blocking (callback) and asyncio modes planned for future implementation
- Microphone requires 500ms startup settling time for clean audio
- DC offset is normal and should be removed in post-processing
Testing
- Tested on XIAO BLE nRF52840 Sense with successful audio capture at 16kHz.
- Have not tested stereo yet because there's only one PDM mic on the board.
Alternatives and Trade-offs
- Code is optional, and is only compiled in if the Kconfig option
CONFIG_MICROPY_PY_MACHINE_PDMis enabled.