/************************************/
/*port2 LED A 0-4*/
/*port1 LED k 0-7*/
/*出力は反転されるので注意*/
/*LED側でNOTが入っている*/
/*60fpsは出そう(16ms)*/
/************************************/
#include <3048f.h>

/************************************/
/*led配列のBuffer*/
int buff[7][5];

void timer_set(void){
	ITU0.TCR.BYTE = 0x23;   /*GRA 2MHz 0010.0011*/
	ITU0.GRA      = 0x07d0; /*GRA 2000に設定 */
	ITU.TSTR.BIT.STR0 = 0;  /*カウント停止状態 */
	return;
}

/* 正確にsec秒はかるところ（実際はsec*1msをやっている）*/
void wait(int sec){
	int j;
	ITU.TSTR.BIT.STR0 = 1;   /*カウント開始 */
    for(j=0;j<sec;j++){
		do{
		}while(ITU0.TSR.BIT.IMFA==0); /*=1で1msです！*/
		ITU0.TSR.BIT.IMFA = 0; /*初期化　*/
	}
	ITU.TSTR.BIT.STR0 = 0; /*カウント終了*/
	return;
}
/*ロギケン*/
const int led[7][20] = {
	{1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,0,0},
	{1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,0,0,1,0,0},
	{1,0,0,0,1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0},	
	{1,0,0,0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,1},	
	{1,0,0,0,1,1,1,1,0,0,1,0,0,1,0,0,0,0,0,1},	
	{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0},
	{1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0}
};

/*Bufferの初期化*/
void buff_0(int i){
	int x,y;
	for(y=4;y>=i;y--){
		for(x=0;x<7;x++){
			buff[x][y] = 0;
		}
	}
}

/*Bufferにled配列を列単位で代入*/
void buff_change(int j,int i){ 
	int k;
	for(k=0;k<7;k++){
		buff[k][j]  = led[k][i];
	}
}

void buff_dec(int i){
	P1.DR.BIT.B0 = buff[0][i]; 
	P1.DR.BIT.B1 = buff[1][i]; 
	P1.DR.BIT.B2 = buff[2][i]; 
	P1.DR.BIT.B3 = buff[3][i]; 
	P1.DR.BIT.B4 = buff[4][i]; 
	P1.DR.BIT.B5 = buff[5][i]; 
	P1.DR.BIT.B6 = buff[6][i]; 
}	

/*Bufferを表示10ms*/
void buff_show(){
	P2.DR.BIT.B0 = 0;
		buff_dec(0);
		wait(2);
		P2.DR.BIT.B0 = 1;
	P2.DR.BIT.B1 = 0;
		buff_dec(1);
		wait(2);
		P2.DR.BIT.B1 = 1;
	P2.DR.BIT.B2 = 0;
		buff_dec(2);
		wait(2);
		P2.DR.BIT.B2 = 1;
	P2.DR.BIT.B3 = 0;
		buff_dec(3);
		wait(2);
		P2.DR.BIT.B3 = 1;
	P2.DR.BIT.B4 = 0;
		buff_dec(4);
		wait(2);
		P2.DR.BIT.B4 = 1;
}
/*実際に出力*/
void led_dec(int i){
	P1.DR.BIT.B0 = led[0][i]; 
	P1.DR.BIT.B1 = led[1][i]; 
	P1.DR.BIT.B2 = led[2][i]; 
	P1.DR.BIT.B3 = led[3][i]; 
	P1.DR.BIT.B4 = led[4][i]; 
	P1.DR.BIT.B5 = led[5][i]; 
	P1.DR.BIT.B6 = led[6][i]; 
}	

/*ledを実際に表示させる*/
void led_show(int i){
	P2.DR.BIT.B0 = 0;
		led_dec(i);
		wait(2);
		P2.DR.BIT.B0 = 1;
	P2.DR.BIT.B1 = 0;
		led_dec(i+1);
		wait(2);
		P2.DR.BIT.B1 = 1;
	P2.DR.BIT.B2 = 0;
		led_dec(i+2);
		wait(2);
		P2.DR.BIT.B2 = 1;
	P2.DR.BIT.B3 = 0;
		led_dec(i+3);
		wait(2);
		P2.DR.BIT.B3 = 1;
	P2.DR.BIT.B4 = 0;
		led_dec(i+4);
		wait(2);
		P2.DR.BIT.B4 = 1;
}

/***main*****************************/
main(){
	
	int time,i,j,k;
		
	P2.DDR      = 0xff; /*port2入力 */
	P2.PCR.BYTE = 0x00; /*port2プルアップoff */
	P1.DDR      = 0xff; /*port1出力 */

	/*タイマー作動*/
	timer_set();
	
	/*初期設定*/
	P1.DR.BYTE=0xff;
	P2.DR.BYTE=0x00;
		
	while(1){
		/*19=横の長さ-1 5=LEDの横の長さ i=何文字目か(5の倍数で)*/
		for(i=0;i<20;i=i+5){
			for(j=0;j<5;j++){
				for(k=4;k>=j;k--){
					time=0;
					buff_0(j);
					buff_change(k,i+j);
					
					while(1){
						buff_show();
						time++;
						if(time>10){break;}
					}
				}
			}
				
				
			time=0;
			while(1){
				led_show(i);
				time++;
				/*100 10ms=1000ms*/
				if(time>100){break;}
			}
		}
	}
}

