/****************************************************************************/ /* PROJECT: All based on ATtinyX5, ATtinyX4, ATmega328P */ /* MODULE: PinChange */ /* VERSION: 1.0 */ /* DATE: 30/01/2011 */ /* TARGET: ATtinyX5, ATtinyX4, ATmega328P */ /* COMPILER: WinAvr (avr-gcc) */ /* IDE: AVR Studio 4 */ /* PROGRAMER: AVR-JTAG-ICE MKII */ /* AUTHOR: P.LOUSSOUARN (P.Loussouarn: http://p.loussouarn.free.fr) */ /****************************************************************************/ #include #include /************************************************************************* MACROS *************************************************************************/ #define PIN_CHANGE_HANDLER_MAX_NB 3 /* ISR max number Pin Change ISR can handle */ /************************************************************************* GLOBAL VARIABLES *************************************************************************/ struct PinChangeStruct { void (*Isr[PIN_CHANGE_HANDLER_MAX_NB])(void); uint8_t LoadedIsrNb; uint8_t Event; uint8_t PinPrev; uint8_t PinCur; }; struct PinChangePortStruct { PinChangeStruct Port[PIN_CHG_PORT_NB]; }; static volatile struct PinChangePortStruct PinChange; /************************************************************************* INTERRUPT SUB-ROUTINE *************************************************************************/ #define DECLARE_PIN_CHANGE_ISR(VirtualPortIdx) \ ISR(PCINT##VirtualPortIdx##_vect) \ { \ uint8_t Idx; \ PinChange.Port[VirtualPortIdx].PinCur=(PC_PIN##VirtualPortIdx)&(PC_PCMSK##VirtualPortIdx); \ PinChange.Port[VirtualPortIdx].Event=PinChange.Port[VirtualPortIdx].PinPrev^PinChange.Port[VirtualPortIdx].PinCur; \ PinChange.Port[VirtualPortIdx].PinPrev=PinChange.Port[VirtualPortIdx].PinCur; \ for(Idx=0;Idx