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

Using PDM Mic on nRF9160DK

I was wondering if there were any good examples of how to get a PDM device (in this case a microphone) working on the nRF9160DK. I've read parts of the datasheet and I've been able to find the nrfx_pdm driver in the SDK but am unaware what pins to use to get it to read data and how to use the easy-dma feature.

Any pointers in the right direction are appreciated. Thank you

Parents
  • Hi,

    There is no PDM example that I am aware of. However, the nrfx PDM driver has decent API documentation, so you can use it to get a pointer on how to use it.

    Regarding pin configuration, any two of the GPIO pins can be used. EasyDMA is the only way to get data, so it is handled for you. You just have to provide a buffer (pointer and size) using the nrfx_pdm_buffer_set() function.

  • I tried using nrfx_pdm.h however it does not seem to be configured to the nrf9160 as the nrf9160.h does not have NRF_PDM define but DOES have NRF_PDM_NS and NRF_PDM_S defined.

    I did a search and replace to replace NRF_PDM w/ NRF_PDM_NS in the nrf_pdm.h and saved it as nrf_pdm_ns.h

    That seems to be all well and good until I tried to build and gives me some errors

    #include <nrf9160.h>
    #include <zephyr.h>
    #include <misc/printk.h>
    #include <string.h>
    #include <stdlib.h>
    #include <nrfx_pdm_ns.h>
    
    
    
    
    #include <gpio.h>
    
    #define PDM_BUF_ADDRESS 0x20000000 // buffer address in RAM
    #define PDM_BUF_SIZE 256 //size in 32 bit words --> 40 bytes
    
    int16_t pdm_buf[PDM_BUF_SIZE];
    
    
    void nrfx_pdm_event_handler(nrfx_pdm_evt_t const *const p_evt)
    {
    	if (p_evt->buffer_requested) {
    		nrfx_pdm_buffer_set(pdm_buf, PDM_BUF_SIZE);						<-----HERE!!!
    	}
    	if (p_evt->buffer_released != 0) {
    		printk("Out: %.2x %2x\r\n", (uint16_t)pdm_buf[0],
    		       (uint16_t)pdm_buf[1]);
    	}
    }
    
    static void pdm_init(void)
    {
    	nrfx_pdm_config_t pdm_config = NRFX_PDM_DEFAULT_CONFIG(10, 11); /*configures CLK to pin 10 and Din to pin 11*/
    	nrfx_pdm_init(&pdm_config, nrfx_pdm_event_handler);						<------AND HERE!!
    }
    
    void main(void)
    {
    	printk("Starting PDM program!\n");
    	printk("PDM Buffer size: %d\n", (PDM_BUF_SIZE * 4));
    	printk("PDM Starting Address: %x\n", PDM_BUF_ADDRESS);
    
    	pdm_init();
    }

    once I try to build SES gives me these errors

    despite that my nrfx_pdm_ns.h file includes the prototypes (I believe).

    Did I do something wrong or am I missing something?

    Thanks for your help

  • yeah, that's what I was afraid of. Thanks, I'll try and track down the problem w/ warnings like you suggested.

    Thank you

  • okay, so I tried adding 

    #ifndef NRFX_PDM_ENABLED
    #warning NRFX_PDM_ENABLED is undefined
    #else
    #if !NRFX_PDM_ENABLED
    #warning NRFX_PDM_ENABLED is defined but set to 0
    #endif
    #endif

    to nrfx_pdm_ns.h, nrf_pdm_ns.h both to no results

    however, once I added it to nrfx.h I get this warning

    so I then proceeded to add this to both nrfx_glue.h and nrfx_glue.c

    #ifndef NRFX_PDM_ENABLED
    #define NRFX_PDM_ENABLED 1
    #endif

    But even after adding that, I still get the same exact errors and the same exact warnings

  • So I changed up my code to test if the PDM was enabled using 

    nrfx_pdm_enable_check()

    shockingly it did not give me an undefined reference error, however when I tried to run the code it did give me this error

    here is my edited code

    /*  
    		C Program to run a pulse density modulation (PDM) Microphone on the nRF9160 Dev Kit using the Nordic SDK
    */
    
    #include <nrf9160.h>
    #include <zephyr.h>
    #include <misc/printk.h>
    #include <string.h>
    #include <stdlib.h>
    #include <nrfx_pdm_ns.h>
    #include <nrfx_pdm.h>
    
    #include <gpio.h>
    
    
    #define PDM_BUF_ADDRESS 0x20000000 // buffer address in RAM
    #define PDM_BUF_SIZE 256 //size in 32 bit words --> 1KB
    
    int16_t pdm_buf[PDM_BUF_SIZE];
    
    /*
    void nrfx_pdm_event_handler(nrfx_pdm_evt_t const *const p_evt)
    {
    	if (p_evt->buffer_requested) {
    		//nrfx_pdm_buffer_set(pdm_buf, PDM_BUF_SIZE);
    	}
    	if (p_evt->buffer_released != 0) {
    		printk("Out: %.2x %2x\r\n", (uint16_t)pdm_buf[0],
    		       (uint16_t)pdm_buf[1]);
    	}
    }
    */ 
    
    //static void pdm_init(void)
    //{
    //	nrfx_pdm_config_t pdm_config = NRFX_PDM_DEFAULT_CONFIG(10, 11); /*configures CLK to pin 10 and Din to pin 11*/
    //	//nrfx_pdm_init(&pdm_config, nrfx_pdm_event_handler);
    //}
    
    void main(void)
    {
    	printk("Starting PDM program!\n");
    	//printk("PDM Buffer size: %d\n", (PDM_BUF_SIZE * 4));
    	//printk("PDM Starting Address: %x\n", PDM_BUF_ADDRESS);
    
            bool enabled = nrfx_pdm_enable_check();
            printk(enabled ? "true/n" : "false\n");
    
    	//pdm_init();
    }

    I am very confused

  • Hi,

    This seems to be because of the Secure Partition Manager (SPM) is not configured to make the PDM peripheral non-secure. You can fix it by adding PDM to the periph_cfg list in spm.c. You can add the following line in the list:

    PERIPH("NRF_PDM", NRF_PDM_S, 1),

  • Hi Einar,

    Would that work to make it non-secure? Most the other ones I can see have an NS at the end whereas this has PDM_S at the end. Is that correct?

Reply Children
Related