Author Topic: ATtiny424 nested interrupts by default?!?!  (Read 1109 times)

0 Members and 1 Guest are viewing this topic.

Offline rs20Topic starter

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
ATtiny424 nested interrupts by default?!?!
« on: October 11, 2023, 10:51:35 am »
Hi,

Page 36 of the datasheet for the ATtiny424 (a tinyAVR 2 device) says this about the Global Interrupt Enable Bit:

Quote
Bit 7 – I Global Interrupt Enable Bit
Writing a ‘1’ to this bit enables interrupts on the device.
Writing a ‘0’ to this bit disables interrupts on the device, independent of the individual interrupt enable settings of the
peripherals.
This bit is not cleared by hardware while entering an Interrupt Service Routine (ISR) or set when the RETI instruction
is executed.

This bit can be set and cleared by software with the SEI and CLI instructions.
Changing the I bit through the I/O register results in a one-cycle Wait state on the access.


Whereas, for the (first generation ATtiny) ATtiny48, page 15 of datasheet says:

Quote
• Bit 7 – I: Global Interrupt Enable
The Global Interrupt Enable bit must be set for the interrupts to be enabled. The individual interrupt enable control is then performed in separate control registers. If the Global Interrupt Enable
Register is cleared, none of the interrupts are enabled independent of the individual interrupt
enable settings. The I-bit is cleared by hardware after an interrupt has occurred, and is set by
the RETI instruction to enable subsequent interrupts.
The I-bit can also be set and cleared by
the application with the SEI and CLI instructions, as described in the instruction set reference.

So my question is: do I really need to manually write cli(); and sei(); 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?
« Last Edit: October 11, 2023, 01:46:30 pm by rs20 »
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6779
  • Country: pl
Re: ATtiny424 nested interrupts by default?!?!
« Reply #1 on: October 11, 2023, 12:42:08 pm »
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:
Quote
This bit is not cleared by hardware after an interrupt has occurred.
which 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 :scared:
 

Online cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: ATtiny424 nested interrupts by default?!?!
« Reply #2 on: October 11, 2023, 08:40:33 pm »
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_a
irq_a isr runs (global irq bit still set), any level0 irq cannot interrupt this isr
irq_c fires (level1), hardware sets cpuint.status.lvl1ex bit, jumps to vector table for irq_c
irq_c runs (global irq bit still set), nothing can interrupt this isr
irq_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 code

One 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.
 
The following users thanked this post: rs20, magic, meshtron

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8276
Re: ATtiny424 nested interrupts by default?!?!
« Reply #3 on: October 12, 2023, 02:46:50 am »
You presumably have the hardware, so test it yourself for best results. I always do that whenever what the datasheet says is questionable.
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6779
  • Country: pl
Re: ATtiny424 nested interrupts by default?!?!
« Reply #4 on: October 12, 2023, 04:46:01 am »
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).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf