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

PDM hardware exception

So this is a small continuation of this ticket https://devzone.nordicsemi.com/f/nordic-q-a/50656/using-pdm-mic-on-nrf9160dk

The problem I'm having now is that when I run my program basically just using nrfx_pdm_start() I get a hardware exception error.

/*  
		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.h>
#include <stdint.h>
#include <gpio.h>

//#define PDM_BUF_ADDRESS 0x20000000 // buffer address in RAM
#define PDM_BUF_SIZE 1024 //length of buffer in 16 bit words

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 in 16 bit words\n", PDM_BUF_SIZE);
	//printk("PDM Starting Address: %x\n", PDM_BUF_ADDRESS);

	/*
	bool enabled = nrfx_pdm_enable_check();
	printk(enabled ? "true/n" : "false\n");
	*/

	pdm_init();
	printk("%x is the starting address\n", &pdm_buf);
	printk("%x is current value at %x\n", pdm_buf[0], &pdm_buf);
	printk("The PDM will start reading NOW...\n");
	nrfx_pdm_start();
	//nrfx_pdm_stop();
	
	printk("%x is current value at %x\n", pdm_buf[0], &pdm_buf);
}

This seemingly only happens when the start command executes.

Any help is appreciated, 

Thank you

P.S. Also, the datasheet seems to indicate that the nrfx_pdm_stop command is automatically carried out when the buffer is full, is that correct? 

Parents
  • Hi,

     

    Sorry for not seeing this before. The interrupt handler must be declared within the OSes options.

    If you add these lines, the program should run:

    ISR_DIRECT_DECLARE(pdm_isr_handler)
    {
    	nrfx_pdm_irq_handler();
    	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency
    			  */
    
    	return 1; /* We should check if scheduling decision should be made */
    }
    
    void main(void)
    {
    	IRQ_DIRECT_CONNECT(PDM_IRQn, 0,
    			   pdm_isr_handler, 0);
    	/* Rest of main */

     

    I'll add these observations to the internal task.

     

    P.S. Also, the datasheet seems to indicate that the nrfx_pdm_stop command is automatically carried out when the buffer is full, is that correct? 

    When the buffer end is reached (either reading or writing), it will give the event EVENTS_END. You can abort the process by sending the TASKS_STOP, which will finish the ongoing transfer transaction, then send the END event to the application.

    Kind regards,

    Håkon

Reply
  • Hi,

     

    Sorry for not seeing this before. The interrupt handler must be declared within the OSes options.

    If you add these lines, the program should run:

    ISR_DIRECT_DECLARE(pdm_isr_handler)
    {
    	nrfx_pdm_irq_handler();
    	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency
    			  */
    
    	return 1; /* We should check if scheduling decision should be made */
    }
    
    void main(void)
    {
    	IRQ_DIRECT_CONNECT(PDM_IRQn, 0,
    			   pdm_isr_handler, 0);
    	/* Rest of main */

     

    I'll add these observations to the internal task.

     

    P.S. Also, the datasheet seems to indicate that the nrfx_pdm_stop command is automatically carried out when the buffer is full, is that correct? 

    When the buffer end is reached (either reading or writing), it will give the event EVENTS_END. You can abort the process by sending the TASKS_STOP, which will finish the ongoing transfer transaction, then send the END event to the application.

    Kind regards,

    Håkon

Children
Related