#ifndef __avr_h #define __avr_h /* Interrupt Vectors */ #define RESET __vector_0 #define IRQ0 __vector_1 #define IRQ1 __vector_2 #define T1CAPT __vector_3 #define T1COMPA __vector_4 #define T1COMPB __vector_5 #define T1OVF __vector_6 #define TIMER0 __vector_7 #define SPISTC __vector_8 #define UARTRX __vector_9 #define UARTUDRE __vector_10 #define UARTTX __vector_11 #define ANA_COMP __vector_12 #define SIGNAL __attribute__ ((signal)) class AVR8 { public: typedef volatile unsigned char Reg8; typedef volatile unsigned short Reg16; typedef volatile unsigned char IOReg8; Reg8 r0; Reg8 r1; Reg8 r2; Reg8 r3; Reg8 r4; Reg8 r5; Reg8 r6; Reg8 r7; Reg8 r8; Reg8 r9; Reg8 r10; Reg8 r11; Reg8 r12; Reg8 r13; Reg8 r14; Reg8 r15; Reg8 r16; Reg8 r17; Reg8 r18; Reg8 r19; Reg8 r20; Reg8 r21; Reg8 r22; Reg8 r23; Reg8 r24; Reg8 r25; union { struct{Reg8 r26; Reg8 r27;}; Reg16 x; }; union { struct{Reg8 r28; Reg8 r29;}; Reg16 y; }; union { struct{Reg8 r30; Reg8 r31;}; Reg16 z; }; }; class AT90S: public AVR8 { public: static const unsigned short RAM_SIZE = 0x0200; public: IOReg8 reserved_00; // [0x20] IOReg8 reserved_01; // [0x21] IOReg8 reserved_02; // [0x22] IOReg8 reserved_03; // [0x23] IOReg8 reserved_04; // [0x24] IOReg8 reserved_05; // [0x25] IOReg8 reserved_06; // [0x26] IOReg8 reserved_07; // [0x27] IOReg8 acsr; // [0x28] IOReg8 ubrr; // [0x29] IOReg8 ucr; // [0x2A] IOReg8 usr; // [0x2B] IOReg8 udr; // [0x2C] IOReg8 spcr; // [0x2D] IOReg8 spsr; // [0x2E] IOReg8 spdr; // [0x2F] IOReg8 ind; // [0x30] IOReg8 ddrd; // [0x31] IOReg8 portd; // [0x32] IOReg8 inc; // [0x33] IOReg8 ddrc; // [0x34] IOReg8 portc; // [0x35] IOReg8 inb; // [0x36] IOReg8 ddrb; // [0x37] IOReg8 portb; // [0x38] IOReg8 ina; // [0x39] IOReg8 ddra; // [0x3A] I/O port A direction (1->out, 0->in) IOReg8 porta; // [0x3B] I/O port A data IOReg8 eecr; // [0x3C] IOReg8 eedr; // [0x3D] IOReg8 eearl; // [0x3E] IOReg8 eearh; // [0x3F] IOReg8 reserved_20; // [0x40] IOReg8 wstcr; // [0x41] IOReg8 reserved_22; // [0x42] IOReg8 reserved_23; // [0x43] IOReg8 icr1l; // [0x44] IOReg8 icr1h; // [0x45] IOReg8 reserved_26; // [0x46] IOReg8 reserved_27; // [0x47] IOReg8 ocr1bl; // [0x48] IOReg8 ocr1bh; // [0x49] IOReg8 ocr1al; // [0x4A] IOReg8 ocr1ah; // [0x4B] IOReg8 tcnt1l; // [0x4C] IOReg8 tcnt1h; // [0x4D] IOReg8 tccr1b; // [0x4E] IOReg8 tccr1a; // [0x4F] IOReg8 reserved_30; // [0x50] IOReg8 reserved_31; // [0x51] IOReg8 tcnt0; // [0x52] IOReg8 tccr0; // [0x53] IOReg8 reserved_34; // [0x54] IOReg8 mcucr; // [0x55] IOReg8 reserved_36; // [0x56] IOReg8 reserved_37; // [0x57] IOReg8 tifr; // [0x58] IOReg8 timsk; // [0x59] IOReg8 gifr; // [0x5A] IOReg8 gimsk; // [0x5B] IOReg8 reserved_3c; // [0x5C] IOReg8 spl; // [0x5D] IOReg8 sph; // [0x5E] IOReg8 sreg; // [0x5F] char ram[RAM_SIZE]; }; #endif class Handler { private: AT90S* avr; unsigned int timer; unsigned char pressedButtons; public: void Handler::listenIRQ0() { /* *sreg |= 0x80 */ avr->sreg |= 0x80; /* *gimsk |= 0xC0 */ avr->gimsk |= 0xC0; /* *mcucr |= 0x0C */ avr->mcucr |= 0x0C; } void handleIRQ0() { // se pressionou: if (avr->mcucr == 0x02) { stopCount(); pressedButtons = checkButtons(); startCount(); /* troca para interrupção em rampa de descida. */ avr->mcucr = 0x03; } else { // se soltou: if (timer > 0) { ledsOff(); } /* troca para interrupção em rampa de subida. */ avr->mcucr = 0x02; } } void handleTIMER0() { if (sameButtons()) { if (timer > 0) { timer--; } else { stopCount(); ledsOn(); } } else { stopCount(); } } void Handler::stopCount() { stopListeningTIMER0(); } void Handler::listenTIMER0() { /* Ativa o contador. *timsk = 0x02 */ avr->tccr0 = 0x05; avr->timsk = 0x02; } void Handler::stopListeningTIMER0() { /* Desativa o contador. *timsk = 0x00 */ avr->timsk = 0x00; } void Handler::startCount() { timer = 61; // 4 segundos listenTIMER0(); } bool Handler::sameButtons() { return checkButtons() == pressedButtons; } unsigned char Handler::checkButtons() { return avr->ind; } void Handler::ledsOn() { avr->portb = 0x00; } void Handler::ledsOff() { avr->portb = 0xff; } }; extern "C" { #define IRQ0 __vector_1 #define IRQ1 __vector_2 #define SIGNAL __attribute__ ((signal)) #define TIMER0 __vector_7 Handler h; void IRQ0() { h.handleIRQ0(); } void TIMER0() { h.handleTIMER0(); } int main() { AT90S* avr; avr = reinterpret_cast(0); /* *leddir = 0xff */ avr->ddrb = 0xff; h.ledsOff(); h.listenIRQ0(); while(true) { } return 0; } }