SAM3X8C PIO interrupt problems (16+ interrupts)

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been using 16 IO pins on the processor as inputs to my application and I've been successfully using them in polled mode up to now.  I've added interrupt handlers for each of the 16 inputs.  Some are on PIOA and some on PIOB.  The code below just has two of the setups, but I have GPIO_IN1-GPIO_IN16 configured and working.  The interrupts work fine UNTIL I get above 7 interrupts.  The first 7 defined work fine, the rest don't fire (no compiler warnings or anything).  Now, if I cut and paste one of the non-working interrupt definitions in Init() to the top, that interrupt works and GPIO_IN07 no longer works.

Is there a limit to the number of PIO interrupts I can have?  Should I just have an interrupt handler for PIOA and one for PIOB and use the source to determine who caused the interrupt?

Thanks in advance!


void Init(void)
{
    pio_set_input(PIOB, ID_PIOB, GPIO_IN01);
    pio_handler_set(PIOB, ID_PIOB, GPIO_INP01, PIO_IT_EDGE, IN01_handler);
    pio_enable_interrupt(PIOB, GPIO_INP01);
    
    pio_set_input(PIOA, ID_PIOA, GPIO_IN02);
    pio_handler_set(PIOA, ID_PIOA, GPIO_INP02, PIO_IT_EDGE, IN02_handler);
    pio_enable_interrupt(PIOA, GPIO_INP02);

    ....

    pio_set_input(PIOB, ID_PIOB, GPIO_IN16);
    pio_handler_set(PIOB, ID_PIOB, GPIO_INP16, PIO_IT_EDGE, IN16_handler);
    pio_enable_interrupt(PIOB, GPIO_INP16);
    
    NVIC_EnableIRQ(PIOA_IRQn);
    NVIC_EnableIRQ(PIOB_IRQn);
}

void IN01_handler(uint32_t sourceid, uint32_t mask)
{
	printf("IN01");
	InputChanged = true;
}

void IN02_handler(uint32_t sourceid, uint32_t mask)
{
	printf("IN02");
	InputChanged = true;
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ceiboss wrote:
Should I just have an interrupt handler for PIOA and one for PIOB and use the source to determine who caused the interrupt?

 

I had a similar problem on my SAMD21J18A. There where some interrupt not working. Wiring them up to fire the same call back and checking the index worked for me. I would give it a try:

void setup_interupts(void){	
	pmc_enable_periph_clk(ID_PIOA);	

	pio_set_input(PIOA, SW1, PIO_PULLUP);
	pio_set_debounce_filter(PIOA,  SW1, 20);
	pio_handler_set(PIOA, ID_PIOA, SW1, PIO_IT_EDGE, pin_edge_handler);
	pio_enable_interrupt(PIOA, SW1);	

	pio_set_input(PIOA, SW0, PIO_PULLUP); // configured in init.c
	pio_handler_set(PIOA, ID_PIOA, SW0,  PIO_IT_EDGE, pin_edge_handler);
	pio_enable_interrupt(PIOA,  SW0);
	NVIC_EnableIRQ(PIOA_IRQn);
}

void pin_edge_handler(const uint32_t id, const uint32_t index)
{
	if ((id == ID_PIOA) && (index == SW1)){		
		if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, SW1) ){				
			printf("Button PA14 Pressed\n\r");
		}		
	}	else if((id == ID_PIOA) && (index == SW0)){

		printf("Button PA02 (On board Button was Pressed \n\r");
	}
}

 

"When all else fails, read the directions"