we need to feed mono audio data into the nRF52 and we are now evaluating the possibility to use PDM. The nRF52 seems to have a useful PDM interface, and even though an example does not seem to exist in the SDK [what a pity!], there is a PDM driver. There also seem to be many PDM microphones available, like from Knowles or InvenSense.
All of these mics are sensitive to 20+ KHz, which we would like to make use of. We planned to have 48 KHz sampling rate and I wondered how and where I could set that in the PDM driver.
After some search, on the PDM Interface site of the Nordic Infocenter I found that the PDM features "16 kHz output sample rate, 16-bit samples". So does it mean that the sample rate cannot be changed? Is this a driver issue or is this a limitation of the PDM hardware used? If the latter is able to handle stereo signal at 16 KHz, I would at least expect it to handle mono signal at 32 KHz without overhead.
Can you please comment on that or propose a hack to change the PCM sampling rate? Thank you!
I am pretty sure that the sampling frequency cannot be changed from 16kHz. When mono is used you have to configure which edge mono is sampled, so it is not sampled at twice the speed, the only difference is the RAM allocation. I have to confirm this with the hardware engineers, but unfortunately most are on vacation so it may take some time.
Thank you, I guess I will look into using a I2S microphone for the time being.
since I am very displeased with the results of my I2S tests (as documented in this thread), I got back to the PDM interface. And it turned out that the sampling rate can pretty easily be increased - as opposed to our previous assumption.
I found that the PDM_PDMCLKCTRL (PDM clock generator control) register can also take undocumented values, as shown below.
DIV32: 0x08000000 -> CLK: 1.000 MHz -> SR: 15625 Hz
DIV31: 0x08400000 -> CLK: 1.032 MHz -> SR: 16125 Hz
DIV30: 0x08800000 -> CLK: 1.067 MHz -> SR: 16667 Hz
Found to be working:
DIV25: 0x0A000000 -> CLK: 1.280 MHz -> SR: 20000 Hz
DIV16: 0x10000000 -> CLK: 2.000 MHz -> SR: 31250 Hz
DIV12: 0x15000000 -> CLK: 2.667 MHz -> SR: 41667 Hz
DIV10: 0x19000000 -> CLK: 3.200 MHz -> SR: 50000 Hz
DIV08: 0x20000000 -> CLK: 4.000 MHz -> SR: 62500 Hz
First I checked the clock signal with an oscilloscope and found it to be stable all the way. Then I attached a Knowles SPH0641LM4H-1 PDM microphone and streamed the PDM data out through UART to finally analyze it on a PC.
I found that at all above listed sampling rates the data is perfect and without distortion or corruption. The spectra of the recorded signals also seem perfect (at least up to 28 KHz, which is okay, since the documented maximum sampling rate of the Knowles microphone tops anyway at 50 ksps).
I incorporated the above listed clock rates into my version of nrf_pdm.h, and also made some changes to nrf_drv_pdm.h and nrf_drv_pdm.c, mostly to data types (why passing uint32_t variables, when we talk about fixed 16-bit samples; uint16_t is much more self-explanatory). See my changes in the attached sources.
And finally, an important question to the hardware developers at Nordic: may I expect any problems with another hardware parts of the nRF52832 when driving the PDM at undocumentedly high rates?
You are correct, the PDM peripheral is designed to work with higher frequencies. The reason this is not stated in the datasheet is because it has not been throughly tested on our side. For this reason we cannot guarantee that it will work with higher frequencies, especially across varying temperatures and voltages.
Hope this helps,
thanks for the reply. It helps a lot. We will do some stress testing at our side and then see how we proceed.