Atmega0 level 1 interrupt does not work

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

The latest version of the atmeg0 errata (2/8/19) states that the level 1 interrupt may fail and jump instead to the reset vector.  No other information is given.  I have raised a support request with Microchip but the response from them is to cut and paste the datasheets and errata.  Furthermore, no workaround is available from Microchip.  Has any one else seen this problem?  We have products that use the atmega4809 and rely totally on a prioritized interrupt structure.  One possible work around would be to have the MCU check the various interrupt status bits immediately after reset and jump to the relevant interrupt handler if any are active.  Any better ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Seems Microchip/Atmel only have the one suggested workaround:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, but "don't use this function" isn't really a workaround.  Our application can only work if we use a level 1 interrupt for time critical functions and level 0 for all the rest.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try this-

#include <xc.h>

//first to run from reset, is an isr so registers preserved
//if not in level1 irq, jump to init0_alt which continues normal startup
//(name has to start with __vector for signal attribute)
__attribute__((signal, section(".init0"), used)) void __vector_LVL1EX(){
    if( (*(volatile uint8_t*)(0x111) & (1<<1)) == 0 ){ //STATUS.LVL1EX
        asm("jmp init0_alt"); //do normal startup
    }
    //the rest of level 1 isr code goes here
}

//just need something to jump to, after init0, and before .init2 where
//normal startup continues (eor r1,r1, etc.)
__attribute__((section(".init1"), naked, used)) void init0_alt(){}

//now get the normal level 1 isr vector aliased to __vector_LVL1EX
__attribute__((alias("__vector_LVL1EX"))) void PORTA_PORT_vect();

int main(void) {
    for(;;){}
}

Your level 1 isr now lives in .init0, it checks if LVL1EX is set- if not set jump to normal startup, if set continue to run the isr code.

The normal vector name is aliased to the substitute, so will be in the vector table twice- at the normal vector location and at reset.

 

The assembly looks ok, and I don't think I'm missing anything, but its possible.

 

This is using xc8, which may act differently than the atmel/gcc-avr version- you may have to change the alias to-

__attribute__((naked, used)) void PORTA_PORT_vect(){
    asm("jmp __vectorLVL1EX");
}

 

Last Edited: Mon. Aug 5, 2019 - 09:24 PM