1

I have an ATTiny 1626 on a PCB which I program by using SerialUPDI. I want to increase the value of a variable in an interrupt service routine, triggered by a button press. The problem is, that the ISR does not get called at all.

My Setup

My Code is:

// Global:
volatile short operation_mode = 1;      // Track operation mode

void setup() {
    cli();
    PORTA.PIN2CTRL |= PORT_PULLUPEN_bm;     // Enable pin A2 pull-up resistor
    PORTA.PIN2CTRL |= PORT_ISC_FALLING_gc;  // Enable pin A2 falling edge interrupts
    PORTA.DIRSET &= ~PIN2_bm;               // Set pin A2 as INPUT  -> Internal pull-up required for async button interrupt
    sei();
}

void loop() {
    ADC0_CTRLA |= ADC_ENABLE_bm; // Turn on ADC
    delay(10);
    // [...]
    ADC0_CTRLA &= ~ADC_ENABLE_bm;       // Turn off ADC
    set_sleep_mode(SLEEP_MODE_STANDBY); // Set standby sleep mode
    sleep_enable();                     // Enable sleeping
    sleep_cpu();                        // Sleep until woken up by ISR
}

// The ISR:
ISR(PORTA_PORT_vect) {
  if ((PORTA.INTFLAGS & PIN2_bm) == 0) {
    operation_mode = (operation_mode + 1) % 3;
  }
  PORTA.INTFLAGS |= PIN2_bm;  // Clear interrupt flag
}

I wonder if there is something wrong with my code or if my setup is flawed. Maybe a capacitor, which has too much capacitance causes the falling edge to be less steep and makes the uC not detect it? I am a bit out of ideas, help is highly appreciated!

Felix Mark
  • 11
  • 3
  • `if ((PORTA.INTFLAGS & PIN2_bm) == 0) {...` - you're checking that an interrupt *hasn't* occurred on this pin before incrementing `operation_mode`. – jasonharper Jan 13 '23 at 21:26
  • `PORTA.DIRSET &= ~PIN2_bm` is a nonsense. Use `PORTA.DIRCLR = PIN2_bm` or `PORTA.DIR &= ~PIN2_bm`. The `PORTA.INTFLAGS |= PIN2_bm;` seems wrong too - it'll probably clear all other flags too because you read them, set PIN2 flag and then assigng it into INTFLAGS. And of course if you get into the ISR, you'll check it's not caused by PIN2 (as mentioned in previous comment) – KIIV Jan 13 '23 at 21:55
  • Oh okay, I see! Thank you, I will test it and let you know if this fixes the problem. I got confused by "Bits 7:0 – INT[7:0] Pin Interrupt Flag Pin interrupt flag n is cleared by writing a ‘1’ to it." in the datasheet, since I assumed, that it must be 0 if it is set, so I can write a 1 in there to clear it. – Felix Mark Jan 13 '23 at 22:51
  • @FelixMark Yes, Interrupt flags are indicated by 1 and must be cleared by writing 1 while 0 doesn't do anything - so you don't have to use read-modify-write operations and you can use write only operations. Same as registers ending with SET/CLR (DIRSET/DIRCLR/OUTSET/OUTCLR) – KIIV Jan 14 '23 at 16:29

0 Answers0