SAME70 read external interrupt polarity in ISR

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

I'm currently working on a SAME70 board made by Atmel. I plugged on it an extention OLED1 board (Atmel too) on EXT1 port. My goal is to recover the information about interrupt type (falling or raising) when I'm pressing the button 3 on OLED1 board. I have a function which allows me to set the different registers related to an interrupts. But unfortunately the register which indicates the polarity (FLHSR) stay always at 0 whatever the state of the button. Below my code.

#include <asf.h>

void set_Interupt_Pin()
    uint32_t mask = 1 << 19;  /*bitmasking*/
    PIOA->PIO_IER = mask;    /*enable interruptions*/
    PIOA->PIO_AIMER = mask;  /*add new interruption*/
    PIOA->PIO_ESR = mask;     /*set interrupt source on edge*/
    PIOA->PIO_REHLSR = mask; /* set interrupt to rising edge*/
    PIOA->PIO_FELLSR= mask; /* set interrupt to falling edge*/
    NVIC_EnableIRQ(ID_PIOA);   /*set NVIC to get interruptions from PIOA*/
    NVIC_SetPriority(ID_PIOA, 4); /*priority 4*/

void PIOA_Handler(void)
    printf("FRLHSR: %x\n",PIOA->PIO_FRLHSR); /*state of polarity event */
    printf("ISR: %x\n",PIOA->PIO_ISR); 
    printf("ELSR: %x\n",PIOA->PIO_ELSR); 
    printf("AIMMR: %x\n",PIOA->PIO_AIMMR); 

int main(void)
    const usart_serial_options_t usart_serial_options = {
        .baudrate     = CONF_UART_BAUDRATE,
        .charlength   = CONF_UART_CHAR_LENGTH,
        .paritytype   = CONF_UART_PARITY,
        .stopbits     = CONF_UART_STOP_BITS
    stdio_serial_init(CONF_UART, &usart_serial_options);

You can see here the result of print when I press button (first part) and I release button (second part).


Last Edited: Fri. Aug 13, 2021 - 11:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From reading the datasheet:

* PIO_FRLHSR is only about the configuration you have set not about the actual detected level (this is why it reads as 0 always, it's what you last set). I expect you have to read the pin level to know what edge was triggered.

* To trigger on both positive and negative edge you should not set PIO_AIMER, this is for when you need a trigger on positive or negative edge (or level).

* You need the PIOA clock enabled (but maybe ASF does that):

PMC->PMC_PCER0 = (1 << ID_PIOA);

Note also it's probably extremely impractical to test this with a push button (because of the bouncing).