ATtiny424 nested interrupts by default?!?! - Page 1
Forum section: electronics / general

author: rs20
author_rank: Super Contributor
timestamp: October 11, 2023, 10:51:35 am
content: Hi,Page 36 of thedatasheet for the ATtiny424(a tinyAVR 2 device) says this about the Global Interrupt Enable Bit:QuoteWhereas, for the (first generation ATtiny) ATtiny48, page 15 ofdatasheetsays:QuoteSo my question is: do I really need to manually writecli();andsei();at the top and bottom (respectively) of all my interrupt handlers on an ATtiny424 to prevent nested interrupts from occurring? Is there any reason why this change isn't a massive deal? I can't really find it mentioned much anywhere?

author: magic
author_rank: Super Contributor
timestamp: October 11, 2023, 12:42:08 pm
content: WTF, I haven't used interrupts on these new generation ATtinys so dunno.But it would be a rather disruptive change with no obvious benefit, so I doubt they made it.FWIW, family 0/1 datasheets say this:Quotewhich is confusing as hell, I think it could mean that interrupts are re-enabled automatically and you don't need to do it yourself after each one.Then some moron may have "corrected" this text in family 2 datasheet.Or maybe I'm wrong and you really need to CLI in the first instruction of the ISR.And hopefully there is a guarantee that at least one instruction will execute before another ISR begins

author: cv007
author_rank: Frequent Contributor
timestamp: October 11, 2023, 08:40:33 pm
content: Read the CPUINT chapter in the datasheet.There is now 2 interrupt priorities on these newer avr0/1/2/dx devices (only 1 irq can be the higher priority). To make that work, they cannot automatically hardware disable the global irq enable when entering an isr as it would render the higher priority irq level useless. Instead you will find in the CPUINT peripheral a STATUS register that 'keeps track' of which interrupt level you are in, and when a reti instruction is executed the level will decrement (or simply the lvlex bit clears for the current level).irq_a fires (level0),hardware sets cpuint.status.lvl0ex bit, jumps to vector table for irq_airq_a isr runs (global irq bit still set), any level0 irq cannot interrupt this isrirq_c fires (level1), hardware sets cpuint.status.lvl1ex bit, jumps to vector table for irq_cirq_c runs (global irq bit still set), nothing can interrupt this isrirq_c isr does a reti, lvl1ex bit clears, returns back to irq_a (lvl0ex still set)irq_a does a reti, lvl0ex bit clears, returns back to main codeOne problem that does show up because of this- if you let the default bad interrupt handler do its normal thing (I think it still does this), which is to simply jump to 0 (bad idea in any case), the lvlex bit remains set because no reti has been seen and you end up in your app again with irq's effectively disabled. A better thing to do is to create your own __vector_default function (then called by __bad_interrupt) to handle any inadvertent irq and simply do a software reset (and whatever else you want to do).Not something normally done, but you also cannot re-enable your current level irq state inside an irq unless a reti is executed. One way to do this would be to call an asm 'function' that simply does a reti.

author: amyk
author_rank: Super Contributor
timestamp: October 12, 2023, 02:46:50 am
content: You presumably have the hardware, so test it yourself for best results. I always do that whenever what the datasheet says is questionable.

author: magic
author_rank: Super Contributor
timestamp: October 12, 2023, 04:46:01 am
content: In this case testing would give misleading results, showing the interrupt bit enabled in ISRs and leading you to think that you should disable it, which is apparently not the case most of the time (unless you enable a high priority interrupt and want to avoid being interrupted by it in a low priority ISR).