Reputation: 1841
#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
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
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