//
//
//
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/sleep.h>
#include <avr/wdt.h>


typedef unsigned char 	  BYTE;
typedef unsigned short 	  WORD;


BYTE MODESWState = 0;


void WDT_off(void)
{

	MCUSR &= ~(1<<WDRF);	 /* ウォッチドッグ リセット フラグ(WDRF)解除 */
	WDTCSR |= (1<<WDCE)|(1<<WDE);	 /* WDCEとWDEに論理1書き込み */
	WDTCSR = 0x00;	 /* ウォッチドッグ禁止 */

}





void u100delay(WORD msec)
{
	register WORD i;
	for(i = 0 ; i < msec  ; i++){
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
		asm volatile("NOP");
//		asm volatile("NOP");
//		asm volatile("NOP");
	}
}


void mdelay(WORD msec)
{
	register WORD i;
	for(i = 0 ; i < msec  ; i++){
		u100delay(2);
		u100delay(2);
		u100delay(2);
		u100delay(2);
		u100delay(2);
	}
}


void m100delay(WORD msec)
{
	register WORD i;
	for(i = 0 ; i < msec  ; i++){
		mdelay(100);
	}
}



void sdelay(WORD sec)
{
	register WORD i;
	for(i = 0 ; i < sec  ; i++){
		m100delay(10);
	}
}


void HW_setup(void)
{
	DDRD = 0x03;	//portd 入力出力設定
	PORTD = 0x00;	//portd 入力 プルアップ

	DDRB = 0x00;	//portb 入力
	PORTB = 0x00;	//portb 入力

	DDRA = 0x00;	//porta 入力
	PORTA = 0x00;	//portA 入力 プルアップ

	MCUCR &= ~(1<<ISC00);	//INT0の割り込み発生条件をLOW検知でトリガで固定
	MCUCR &= ~(1<<ISC01);

	MCUCR &= ~(1<<ISC10);	//INT1の割り込み発生条件をLOW検知でトリガで固定
	MCUCR &= ~(1<<ISC11);

	ACSR |= (1<<ACD);		//アナログ比較器禁止

	wdt_enable(WDTO_8S);
	wdt_reset();
}



enum
{
	MODESW_LED_FLASH01=0,
	MODESW_LED_FLASH02,
	MODESW_LOWPOWER,
	MODESW_IDOL,
};




SIGNAL(SIG_INTERRUPT0)				//MODESW_LED_FLASH01
{

	//cli();			//全割り込み禁止

	MODESWState = MODESW_LED_FLASH01;

	wdt_enable(WDTO_8S);
	wdt_reset();
}




SIGNAL(SIG_INTERRUPT1)				//MODESW_LED_FLASH02
{
	//cli();			//全割り込み禁止

	MODESWState = MODESW_LED_FLASH02;

	wdt_enable(WDTO_8S);
	wdt_reset();
}


#define LED01_SIG	0
#define LED02_SIG	1


int main(void)
{


	HW_setup();

	PORTD |= (1<<LED01_SIG);			//消灯
	PORTD |= (1<<LED02_SIG);			//消灯



	PORTD &= ~(1<<LED01_SIG);			//点灯
	PORTD &= ~(1<<LED02_SIG);			//点灯
	sdelay(1);
	PORTD |= (1<<LED01_SIG);			//消灯
	PORTD |= (1<<LED02_SIG);			//消灯


	MODESWState = MODESW_LOWPOWER;

	while(1){

		switch(MODESWState) {
			case MODESW_LED_FLASH01:

				PORTD &= ~(1<<LED01_SIG);			//点灯
				sdelay(1);
				PORTD |= (1<<LED01_SIG);			//消灯

				MODESWState = MODESW_LOWPOWER;	
				break;
			case MODESW_LED_FLASH02:

				PORTD &= ~(1<<LED02_SIG);			//点灯
				sdelay(1);
				PORTD |= (1<<LED02_SIG);			//消灯

				MODESWState = MODESW_LOWPOWER;	
				break;
			case MODESW_LOWPOWER:
				MODESWState = MODESW_IDOL;
				GIMSK |= (1<<INT0);			//Interrupt 0 enable
				GIMSK |= (1<<INT1);			//Interrupt 1 enable
				//GIMSK |= (1<<PCIE);			//
				wdt_reset();

				WDT_off();
				set_sleep_mode(SLEEP_MODE_PWR_DOWN);
				sei();		//全割り込み許可
				sleep_mode();
				break;
			default:
				asm volatile("NOP");
				break;
		}
	}
}