1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
#include <avr/interrupt.h>
#if defined(__AVR_ATtiny2313__)
# define FLAGREG EIFR
# define MASKREG GIMSK
# define FLAGBIT _BV(PCIF)
# define PORTREG PINB
# define CTRLREG PCMSK
#endif
#if defined(__AVR_ATmega48__)
# define FLAGREG PCIFR
# define MASKREG PCICR
# define FLAGBIT _BV(PCIF1)
# define PORTREG PINC
# define CTRLREG PCMSK1
#endif
volatile unsigned char cnt_irq = 0;
volatile unsigned char hs_in = 0;
volatile unsigned char hs_out = 0;
volatile unsigned char hs_cmd = 0;
volatile unsigned char hs_data = 0;
#if defined(__AVR_ATtiny2313__)
ISR(PCINT_vect) {
#endif
#if defined(__AVR_ATmega48__)
ISR(PCINT1_vect) {
#endif
cnt_irq++;
}
int main() {
while(1) {
// do we have a new command?
if(hs_in != hs_out) {
switch(hs_cmd) {
default:
// noop
break;
case 1:
// sei or cli
if(hs_data != 0) {
cli();
MASKREG |= FLAGBIT;
sei();
} else {
cli();
MASKREG &= ~FLAGBIT;
}
break;
case 2:
// clear interrupt counter, this is a atomic op, so we don't need to
// disable interrupt
cnt_irq = 0;
break;
case 3:
// reset flag bit
FLAGREG |= FLAGBIT;
break;
case 4:
// set control register
CTRLREG = hs_data;
break;
case 5:
// get port input
hs_data = PORTREG;
break;
case 6:
// get flag register
hs_data = FLAGREG;
break;
case 7:
// get mask register
hs_data = MASKREG;
break;
}
// clear command
hs_cmd = 0;
// handshake
hs_out = hs_in;
}
} // this will never return
return 0;
}
|