hexwab
hexwab

Reputation: 1841

ATmega32U4: enabling interrupts hangs

#include <avr/io.h>
#include <avr/interrupt.h>

void delay() {
    volatile uint16_t i;
    for (i=1e6; i; i--);
}

int main(void) {
    DDRB = 255;
    /* sei(); */
    while (1) {
        PORTB ^= 1;
        delay();
   }
}

The above program blinks an LED. With sei(); uncommented it doesn't. I haven't enabled any interrupt sources, the datasheet says they're all off by default, and while the bootloader (Caterina) does use TIMER1_COMPA it turns it off again before running my code.

It would seem it can't possibly be calling an undefined interrupt handler. But I'm perplexed why else it would not get as far as blinking.

What's going on here?

Upvotes: 2

Views: 726

Answers (2)

hexwab
hexwab

Reputation: 1841

Turns out the bootloader[1] left the USB controller enabled and generating interrupts.

Adding an empty ISR(USB_GEN_vect) fixed the hang but produced massive slowdown of the blinking, presumably due to the ISR not actually doing anything about the conditions that caused the interrupts in the first place, thus being called repeatedly. Adding USBCON = 0; before sei(); worked properly.

[1] Caterina, as mentioned. Code for the bootloader is at https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/bootloaders/caterina/

Upvotes: 3

Mat
Mat

Reputation: 126

If the LED remains On, it's probably the Watch Dog Timer interrupt. your micro is restarted before blinking happens. As I recall, it might be enabled/disabled using a fuse-bit.

Upvotes: 0

Related Questions