Interrupts #929
Replies: 3 comments 5 replies
-
Interrupts are different on the modern AVRs. Better. First off, power.h does nothing here. I've gone through the code of that line by line and determined that every active line is #ifdef'ed out - there are no PRR's here. All peripherals unless stated otherwise are inactive during power down sleep. In standby sleep, most peripherals can be forced on with RUNSTBY but are otherwise off, so they don't need to be explicitly turned off Only exception is on the 2-series parts with the new ADC, due to an erratum, you have to turn off the ADC manually and configure LOWLAT before anything it effects. Our ADCPowerOptions api extension for turning LOWLAT on and of re-cycles all the other options when you change that on effected parts. Not necessary on 0 or 1-series parts (though we do still have that function so that there's a unified way to enable and disable the ADC and set wehther it runs in standby - 2 series has 2 additional options, LOWLAT and the one that controls if the PGA is left on. Secondly, you just use Wire.h not TinyWireM. TinyWireM (and you don't even use if for them with my core because we include universal Wire.h over on ATTinyCore) is for old crappy classics with the Useless Serial Interface. We have real I2C so we use Wire (and the version of wire we ship with has been improved significantly - it has more accurate baud rate generaion, uses far less flash than the stock modern avr one, and can work in multimaster modes or as slave with 2 addresses or wildcard bits in the address, and it can sleep successfully while acting as slave. The WDT can only be used to reset, to get the periodic interrupt, you need to use the RTC/PIT; I am working on a library for this. It's an urgent priority, but that's relatively low priority because 2.6.7 is ultra urgent priority, and and i've got half a dozen other superurgent priorities and sleep related tasks for the common wake every XX seconds type tasks and while will make millis approximately correct when you wake up. Port interrupts are enabled by setting the Input Sense Control (ISC) bits in PINnCTRL appropriately (there's low level, change, rising and falling. Rising and falling can wake the chip only on pins 2 and 6 of a port (and all pins can wake on change and low level), and while you can use attachInterrupt, it's as evil as ever (despite a heroic and ultimately unsuccessful effort to make it less so) and you're better off doing it manually with your own ISR. the things you need to know are that there's one interrupt per port PORTx_PORT_vect, It's controlled per pin by the PORTx.PINnCTRL registers' ISC bitfields (that register is Invert, InLevel (where supported), rsvd, rsvd, Pullup enable, ISC2, ISC1, ISC0) 0b000 is normal pin operation The interrupt MUST clear the PORTx.INTFLAG bit, which is done by writing a 1 to it (it's one of those backwards flag bits that are unchanged when written 0 and 0'ed when written 1). If you only have one kind of interrupt coming in through a port, and the others are disabled, you can neglect handling them, which helps reduce code size and complexity significantly, and it's an ISR so those are extra important (well, execution time is what matters, but that's a function of code size and complexity pretty much). As always try not to call functions that won't be inlined in ISRs, use digitalWriteFast not normal digitalWrite, and so on (we have fast version of all the I/O functions, see Ref_Digital.md) (Which will impose a 40ish clock cycle penalty from the function call to a non-inlined function plus the 100+ clocks that monster uses because it has to turn off pwm). digitalWriteFast on constant pin is 1 clock cycle and 1 instruction. The VPORTs are also insanely useful here (each port has VPORTx.DIR, OUT, IN, and INTFLAGS) - these are just like the normal ones only faster: Setting or clearing a single bit (like one intflag or flipping 1 pin) takes just 1 clock cycle (cbi sbi- these were 2 clock instructions on classic AVR) when done through the VPORTs, and such access is atomic. The bare minimum interrupt overhead is 5 clocks in + body + 4 clocks out for a naked ISR, most ISRs should be clothed (naked ones must be written in asm, alter no working registers and perform no mathematical or comparison operation). The prologue and epiliog automatically added to non-naked ISRs adds like 15 clocks to the process. more if lots of temporary variable are used (because it has to save and restore every workign register you use - this is done automatically and reti automatically generated unless you're naked), this can be markedly worse than the minimum. There's no equivalent of the enable mask. You're expected to use the PINnCFG registers |
Beta Was this translation helpful? Give feedback.
-
Thanks for the explanation! However, how come the wire.h cannot be used on the 406, while I can compile on the 806 ? Any ideas what could be wrong? Arduino: 1.8.13 (Mac OS X), Board: "ATtiny3226/3216/1626/1616/1606/826/816/806/426/416/406, ATtiny406, 20 MHz internal, 1.8V (5 MHz or less), Disabled/Disabled, EEPROM retained, Enabled (default timer), UPDI (no reset pin), 8ms, Master or Slave (saves flash and RAM), Default (doesn't print floats, 1.4k flash use), On all pins, with new implementation., Disabled (recommended), No delay before window "opens"" Error:
|
Beta Was this translation helpful? Give feedback.
-
The consumption is sorted and my consumption in sleep mode, pwrdown is around 120uA along with sensor ... My Arduino dropdown menu settings are as follows: The interrupt is used for the sensor, to wake up the uC, while the WDT is used as "software reset", anyway, I am wondering, should not I have as well the RESET on the BOD while the processor is not in sleep... Thanks for any comments, suggestions ... |
Beta Was this translation helpful? Give feedback.
-
Hello All,
I am looking to use the interrupt via this library and at tiny 3216.
I have used interrupt on AT Tiny45,85 before to wake up the processor via the interrupt pin on a sensor...
posting the #includes and some code that works.
Before I delve into using it on at3216 wondering, if the " avr " code, etc, should as well work on this tiny ?
For example, are the vectors the same, actually where can those be found?
example of working code.
Beta Was this translation helpful? Give feedback.
All reactions