Subversion Repositories group.electronics

Rev

Rev 11 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <stdint.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

#define F_CPU 12000000
#include <util/delay.h>

#define DEPRESS_TIME    1

#define sbi(sfr, bit)   ((sfr) |= _BV(bit))             // Set bit 
#define cbi(sfr, bit)   ((sfr) &= ~(_BV(bit)))          // Clear bit
#define xbi(sfr, bit)   ((sfr) ^= _BV(bit))             // Flip bit
#define rbi(sfr, bit)   (((sfr) >> (bit)) & 0x01)

volatile uint8_t pcIntCurr = 0;
volatile uint8_t pcIntLast = 0;
volatile uint8_t pcIntMask = 0;

void doInt();

int main() {
        cbi(DDRB, PCINT2);
        cbi(DDRB, PCINT3);
        PORTB |= (( 1 << PCINT2 ) | ( 1 << PCINT3 )); //turn on pullups
        PCMSK |= (( 1 << PCINT2 ) | ( 1 << PCINT3 )); //enable encoder pins interrupt sources
        sei();
        GIMSK |= ( 1 << PCIE ); //enable pin change interupts

        DDRD |= ( 1 << PD4 );
        DDRD |= ( 1 << PD5 );
        DDRD |= ( 1 << PD6 );

        sbi(PORTD, PD6);
        _delay_ms(1000);
        cbi(PORTD, PD6);

        for (;;) {

                if (pcIntMask)
                        doInt();
        }
}

void doInt() {
  xbi(PORTD, PD6);

  if (rbi(pcIntCurr, PCINT2) == 0 && rbi(pcIntCurr, PCINT3) == 0 && rbi(pcIntMask, PCINT2) ) {
        cbi(PORTD, PD5);        // Clear oppposite direction

        sbi(PORTD, PD4);        // Depress current direction for DEPRESS time
        _delay_ms(DEPRESS_TIME);
        cbi(PORTD, PD4);        
  } else if (rbi(pcIntCurr, PCINT3) == 0 && rbi(pcIntCurr, PCINT2) == 0 && rbi(pcIntMask, PCINT3) ) {
        cbi(PORTD, PD4);

        sbi(PORTD, PD5);
        _delay_ms(DEPRESS_TIME);
        cbi(PORTD, PD5);
  }

  pcIntMask = 0;
}


ISR(PCINT_vect)
{
  pcIntCurr = PINB;
  pcIntMask = pcIntCurr ^ pcIntLast;
  pcIntLast = pcIntCurr;
}