1
\$\begingroup\$

For a quite while, I've been using an avr ATmega324PA controller and Atmel studio to write the programs. we wrote a TCP bootloader. It works fine without any interrupt. Later we did add an external inetrrupt to that program and now controller always restarts when jumping to the ISR. Here is the code

void main()
{
  init_interrupt();
  init_uart();
  while(1);
}

void init_interrupt()
{
  /* PortA3 as input for external interrupt*/
 DDRB|=(0<<2);
  /*Pulll up disable*/
 PORTB &=~ (1<<PORTB2);
  /*Interrupt_vector change enable*/
 MCUCR|=(1<<IVCE);
  /*Interrupt vector change to boot section*/
 MCUCR|=(1<<IVSEL);
  /*Interrupt_vector change enable*/
 MCUCR&=~(1<<IVSEL);
 _delay_ms(5000);
  /* Enable external interrupt-2*/
 EIMSK |= (1<<INT2);
  /* Enable rising edge of the input signal as interrupt*/
 EICRA |= (1<<ISC21)|(1<<ISC20);
  /* Enable global interrupt*/
 sei();
}

ISR(INT2_vect)
{
    uart_send("Print on interrupt");
}

Here i am trying to change the interrupt vector to boot section.

NOTE: BOOTRST fuse is already set

EDITED: After changing the MCUCR value as shown below, i sent it through UART instead of '01', the output is displayed as "A0 2E 57 C9 D1 95 91 FF"

    MCUCR|=(1<<IVCE);

Must be a problem with the MCUCR register

\$\endgroup\$
  • 1
    \$\begingroup\$ Are you sure you're not jumping to an interrupt vector which is undefined in your code, causing the processor to reset? \$\endgroup\$ – David Jul 10 '14 at 6:45
  • \$\begingroup\$ As u see i have defined INT2_vect routine and enabled the external interrupt settings in init_interrupt().. This same interrupt without IVSEL settings, works fine with application code. But with boot code, it resets \$\endgroup\$ – gzix Jul 10 '14 at 7:02
  • 1
    \$\begingroup\$ Does your bootloader use interrupts? I've personally avoided them in bootloaders but I think there are a couple of register bits you need to relocate the interrupts to the bootloader section. Maybe they are left in the wrong state by the bootloader. \$\endgroup\$ – PeterJ Jul 10 '14 at 11:26
2
\$\begingroup\$

Atlast this is how to make work the interrupts in bootloader, U should set the Interrupt Vector Change Enable(IVCE) bit as below

   MCUCR|=(1<<IVCE); // or GICR|=(1<<IVCE) in some controllers

And within four cycles u have to set the IVSEL and unset the IVCE bit.

   MCUCR=0x02; // or GICR=0x02;  IVSEL=1, IVCE=0 at same time

What went wrong in the above code is below

     /*Interrupt_vector change enable*/
    MCUCR|=(1<<IVCE);
    /*Interrupt vector change to boot section*/
    MCUCR|=(1<<IVSEL);
    /*Interrupt_vector change enable*/
    MCUCR&=~(1<<IVSEL);

The former method might finish within four cycles i think. However i can now use the TCP bootloader with interrupts to load the application code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.