This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Single PDM microphone at higher PCM sampling rate

Hello,

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!

NewtoM

Parents
  • Hi Ole,

    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.

    Documented settings:

    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?

    Thanks,

    NewtoM

  • Hi NewtoM,

    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,

    Ole

Reply Children
  • Hi Ole,

    I've seen a few more PDM frequencies added to the nRF5 SDK v16.0.0, which is good. Back in the day I used an oscilloscope to measure PDM clock frequencies and document the register setting for the given divisor. I still wonder, though, what is the closed equation for the relation between the register value and the PDM clock speed (or clock divider)? Can you provide me that?

    Thanks,
    Tamas

  • 32000000 / (DIV * 64) = Sampling Rate

    To get the PDM frequency:

    32000000 / DIV

  • The question is, how the register settings relate to the possible DIVs. E.g.


    #define DIGITAL_AUDIO_SAMPLING_RATE_15625 (0x08000000UL)    // (32 MHz / 32)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_16129 (0x08400000UL)    // (32 MHz / 31)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_16667 (0x08800000UL)    // (32 MHz / 30)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_20000 (0x0A000000UL)    // (32 MHz / 25)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_31250 (0x10000000UL)    // (32 MHz / 16)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_33333 (0x11000000UL)    // (32 MHz / 15)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_45455 (0x16000000UL)    // (32 MHz / 11)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_50000 (0x18000000UL)    // (32 MHz / 10)  / 64
    #define DIGITAL_AUDIO_SAMPLING_RATE_62500 (0x20000000UL)    // (32 MHz / 8)   / 64

    So, say, if I wanted 4000 Hz sampling rate (i.e. 256000 Hz PDM frequency), what would be the register value? 0x... ? And why?

    Thanks,
    Tamas

Related