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

nRFX based PDM to PCM implementation (I2S example)

Hello,

I am currently interfacing my nRF52840 DK with i2S based MP34DT05 sensor. I am using nrfx i2s driver's for interfacing with sensor. I am using master clk of 2MHz, LCLK 16KHZ. 

My sensor output PDM data. In my project I am recording audio samples on left channel, so I am currently getting 2*16bit of left data per 32bits as shown in nrf docs. I have got 16bit recorded samples in buffer, but to how to convert this pdm data in pcm format. 

Normally we need to divide the PDM data with a decimation factor, but in I2S we already are dividing the bit sampling rate with ratio value. So is the output from the I2S itself is decimated PCM ?  

Or can anyone give a example of how to convert the PDM to PCM data. Any sort of help is dually appreciated. 

Parents
No Data
Reply
  • Hello,

    Followed your suggestions a bit and came up with this code, it successfully builds at least. But i haven't used a structure in FIFO queues while getting data for printing.

    My updated handler and function to print data given below. Should i add anything else ?

    //Memory slab
    struct k_mem_slab audio_slab;
    K_MEM_SLAB_DEFINE(audio_slab, 3200, 5, 4);
    
    //FIFO to hold pointers to memory slab
    struct k_fifo my_fifo;
    K_FIFO_DEFINE(my_fifo);
    
    
    char *block_ptr;
    
    void nrfx_pdm_event_handler(nrfx_pdm_evt_t const * p_evt)
    {
        if(p_evt->buffer_requested)
        {
          if(k_mem_slab_alloc(&audio_slab, &block_ptr, K_NO_WAIT)==0){
              memset(block_ptr, 0, 400);
          }
          nrfx_pdm_buffer_set(&block_ptr,3200);
     
        }
        if(p_evt->buffer_released != 0)
        {
          k_fifo_put(&my_fifo,&block_ptr);
          write_data = true;
        }
    }
    
    
    
    //In While loop
    void Microphone_Print_Sample(int16_t samples)
    {
        uint16_t *rx_data;
        rx_data = k_fifo_get(&my_fifo, K_FOREVER);
        
        for(int i=0; i<samples;i++)
        {
          printk("%4x, ", *(rx_data + i) );
          printk("\r\n");
        }
        k_mem_slab_free(&audio_slab, &block_ptr);
    }

    Referred Docs: https://docs.zephyrproject.org/1.9.0/kernel/memory/slabs.html

    https://docs.zephyrproject.org/1.9.0/kernel/data_passing/fifos.html

    The UART baud rate might be an issue here. The default is 115200 baud, while your audio is 16-bit * 16 kHz = 256000. To test if this is the problem, you can try setting the board baud rate to 1000000 instead of 115200.

    Also i am using USB CDC to print out the data, so does baud rate matter ? And i also read that USB CDC have good data transmission rate. So why does my printk takes so much time? Can this be the issue ?

Children
No Data
Related