/*
  iTunes Controller
  2006/4/29 by Yusuke Wada
*/

#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

#define outp(data,addr) addr=(data)
#define inp(addr) (addr)


/*関数宣言*/
static void uart_init(void);
static void overflow0_init(void);
volatile char rot_state;

int main(void)
{
  DDRB = 0x00; //PB全ピン入力モード
  DDRD = 0x40; //PD6を出力モード
  PORTB = 0xFF; //PORTBをプルアップ

  outp(0x00,PORTD);
  uart_init();
  overflow0_init();
  sei();                 /* enable interrupts */

  volatile char pushed;
  pushed = 0;
  
  for (;;) {

    if(bit_is_clear(PINB,0)){
      if(pushed != 1){
        outp('b',UDR);
        outp(0x40,PORTD);
        pushed = 1;
      }
    }
    else if(bit_is_clear(PINB,1)){
      if(pushed != 1){
        outp('p',UDR);
        outp(0x40,PORTD);
        pushed = 1;
      }
    }
    else if(bit_is_clear(PINB,2)){
      if(pushed != 1){
        outp('f',UDR);
        outp(0x40,PORTD);
        pushed = 1;
      }
    }else{
      pushed = 0;
      outp(0x00,PORTD);
    }
  }

}

/* initialize uart */
void uart_init(void)
/*  4Mhz CPU, 9600 baud, 8-bit, 1-stop, 0 parity  UBRR=25 */
{
  /* enable RxD/TxD and ints */
  outp((1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN),UCR);
  /* set baud rate */
  outp(25, UBRR);
}
/*initialize overflow0*/
void overflow0_init(void){
  TCCR0 = 1; //タイマ0の分周比直
  TIMSK=(1<<TOIE0);//タイマ0割り込み許可
  TCNT0 = 20; // 1ms毎に割り込み設定、すんげえ適当
}

/* タイマ/カウンタ1オーバーフロー割り込み
   ロータリーエンコーダー監視用
   special thanks to Sho Hashimoto */

SIGNAL(SIG_OVERFLOW0){
  TCNT1 = 20; // タイマ/カウンタ初期化、すんげえ適当
  
  char past_state; // 1回前の状態
  past_state = rot_state;
  if(bit_is_set(PINB,3)){
    if(bit_is_set(PINB,3)) // HH
      rot_state = 1;
    else // HL
      rot_state = 0;
  }
  else{
    if(bit_is_set(PINB,4)) // LH
      rot_state = 2;
    else // LL
      rot_state = 3;
  }
  
  if((rot_state+3+1)%3 == past_state){ // 右回り
    outp('u',UDR);
    outp(0x40,PORTD);
  }
  else if((rot_state+3-1)%3 == past_state){ // 左回り
    outp('d',UDR);
    outp(0x40,PORTD);
  }
}