//ICC-AVR application builder : 2005-12-17 오전 12:24:41
// Target : M128
// Crystal: 16.000Mhz

#include <iom128v.h>
#include <macros.h>

void delay(int n);

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
 PORTE = 0x00;
 DDRE  = 0x01;
 PORTF = 0x00;
 DDRF  = 0x00;
 PORTG = 0x00;
 DDRG  = 0x00;
}

//UART0 시리얼 포트 초기화 루틴
// desired baud rate: 9600bps
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00;
 UCSR0C = 0x06;
 UBRR0L = 0x67; //set baud rate lo
 UBRR0H = 0x00; //set baud rate hi
 UCSR0B = 0x08;
}

//주변 장치 초기화 루틴
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 XDIV  = 0x00; //xtal divider
 XMCRA = 0x00; //external memory
 port_init();
 uart0_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

#define LIGHT_STATE ((PINE&0x10)==0x10)
#define RELAY_ON    (PORTE = PORTE | 0x01)
#define RELAY_OFF   (PORTE = PORTE & 0xfe)

#define VR_RESET    (DDRB = DDRB | 0x01)
#define VR_RECOG    (DDRB = DDRB | 0x02)
#define VR_TRANING  (DDRB = DDRB | 0x04)
#define VR_NORMAL   (DDRB = 0x00)


//
void main(void)
{
 int i=0;
 init_devices();
 //처음엔 음성 인식 모드로 보드를 전환시키게 된다.
 VR_Recog_Mode();
 RELAY_OFF;
 while(1){
    i++;
    printf(".");
    if((PINB&0x30) == 0x30){
        printf("\n\r%d testing...%x\n\r", i, PINB&0x30);
        if(PINB&0x40){
            // 첫번째 음성 인식 명령어가 인식되면, 전등을 끄게 된다.
            printf("OFF...\n\r");
            if(!LIGHT_STATE){
                printf("OFFOFFOFF\n\r");
                RELAY_ON;
                delay(100);
                RELAY_OFF;
            }
                
        }else{
            // 두번째 음성 인식 명령어가 인식되면, 전등을 켜게 된다.
            printf("ON...\n\r");
            if(LIGHT_STATE){
                printf("ONONON\n\r");
                RELAY_ON;
                delay(100);
                RELAY_OFF;
            }
        }
        while((PINB&0x30) == 0x30);
    }

    if(!(PIND & 0x02)){
        VR_Recog_Mode();
    }

    if(!(PIND & 0x01)){
        // 리셋 버튼 밑에 있는 버튼을 누르면 음성 녹음 모드로 음성인식키트를 전환시킨다.
        VR_Init_Mode();
        printf("\n\rVR training\n\r");
 
        while((PIND & 0x02));
        // 음성 녹음 모드를 종료한다.
        printf("VR training end\n\r");
        delay(1000);
        // 음성 인식 모드로 들어간다.
        VR_Recog_Mode();
    }
 }
    
}

// 음성 녹음 장치를 초기화 하는 루틴
// 아래 순서대로 초기화 해 주어야만 음성보드가 녹음장치를 시작하게 된다.
// 음성인식킷트의 복잡한 초기화 명령을 하나의 함수로 묶은 것이다.

void VR_Init_Mode(void)
{
        // 보이스 레코더 리셋키를 누르고
        VR_RESET;
        delay(1000);
        // Normal 상태로 돌리고,
        VR_NORMAL;
        delay(1000);
        // Recog 키와 Traning 키를 동시에 누르고 
        VR_RECOG;
        VR_TRANING;
        delay(1000);
        // Normal 상태로 돌리고
        VR_NORMAL;
        delay(1000);
        // Traning 키를 누른다.  
        VR_TRANING;
        delay(1000);
        // Normal 상태로 돌린다.
        VR_NORMAL;
}

// 음성 인식 장치를 초기화 하는 루틴
// 아래 순서대로 해 주면, 음성 보드는 음성 인식 모드로 들어가게 된다.
// 음성 인식 모드로 일단 들어가게 되면, 저장된 음성명령이 인식 될때까지 대기하게 된다.

void VR_Recog_Mode(void)
{
        VR_RESET;
        delay(1000);
        VR_NORMAL;
        delay(1000);
        VR_RECOG;
        delay(1000);
        VR_NORMAL;
}
