/***********************************************************************/
/*                                                                     */
/*  FILE        :test_Forloop.c   by T.AZAMI                           */
/*  DATE        :10/4 2007                                             */
/*  DESCRIPTION :Main Program                                          */
/*  CPU TYPE    :OAKS8 (R8C/Tiny R5F2114)                              */
/*                                                                     */
/*  For Loop の時間測定テストプログラム　                              */
/*                                                                     */
/***********************************************************************/
                  

#include	<sfr_r811.h>
#define		CLOCK	20000
#include	"lcd.h"

#define KEY1	p0_7	// 設定 DOWN
#define KEY2	p0_6	// 設定 UP
#define KEY3	p0_5	// 計測スタート

#define LED1	p0_4	// Forループ中 ON
#define LED2	p0_3	// 設定時点灯、動作確認用

#define KEY_ON	0
#define KEY_OFF	1

#define LED_ON 	0
#define LED_OFF	1

#define ON		0
#define OFF		1

volatile char Msg0[] = "For Loop Time X \0";	// 表示文字列1行目
volatile char Msg2[] = "TXCount         \0";
volatile char Msg1[] = "n=1000        uS\0";	// 表示文字列2行目

volatile char F_time = 50;	// クロック周期  20Mhz - 50ns   12.8Mhz -78 ns

//--------------------------------------------------------------
//   キー入力サブルーチン　戻り値はSW番号(1〜3)
//--------------------------------------------------------------
unsigned char KEY_input(void)
{
	unsigned int flag = 1;
	unsigned int Key_data = 0;
	
	while ( flag ){
		Delay_ms ( 100 );			// Delay_ms関数はLCD.h中のものを利用する
		if ( KEY1 == ON ){
			flag = 0;
			Key_data = 1;
		} else if ( KEY2 == ON ){
			flag = 0;
			Key_data = 2;
		} else if ( KEY3 == ON ){
			flag = 0;
			Key_data = 3;
		} else {
			flag = 1;
			Key_data = 0;
		}
	}

	return Key_data;
}

//--------------------------------------------------------------
//   数値から文字列に変換(Char型）
//--------------------------------------------------------------
void Itostring(int digit, unsigned long data, char *buffer)
{
	char i;	
	buffer += digit;						//文字列の最後
	for(i=digit; i>0; i--)					//最下位桁から上位へ
	{	
		buffer--;							//ポインター１
		*buffer = (data % 10) + '0';		//その桁数値を文字にして格納
		data = data / 10;					//桁-1
	}
}

//--------------------------------------------------------------
//   数値から文字列に変換(Char型）ゼロサプレス処理済み
//--------------------------------------------------------------
void Itostring_zs(int digit, unsigned long data, char *buffer)
{
	char i;
	char f = 0;	
	Itostring( digit, data, buffer );

	for(i=1; i<digit; i++){					//最初からの桁がゼロの場合空白に置き換える
		if ((f == 0) && (*buffer == '0')){
			*buffer = ' ';
		}else{
			f = 1;							//ゼロ以外の数値に来たらフラグを立てて処理しない
		}
		buffer++;
	}
}

//--------------------------------------------------------------
//　メインルーチン
//--------------------------------------------------------------

void main( void ) 
{ 
	unsigned char Key_flag;
	unsigned char Loop_flag;
	unsigned int  n, i, j;
	unsigned long cnt;
	
	// クロックをメインクロックに切り替える
	prc0 = 1;					// プロテクト解除…PM0,PM1レジスタへの書き込み許可
	cm1 = 0x08;					// システムクロック制御レジスタ…Xin Xout使用、分周なし
	cm0 = 0x08;					// システムクロック制御レジスタ…クロック発振開始、非1/8分周選択
	asm("NOP");			
	asm("NOP");					// クロック発振待ち
	asm("NOP");
	asm("NOP");
	ocd2 = 0;					// メインクロック選択
	prc0 = 0;					// プロテクトオン
	
	// LCDポート設定
	pd1 = 0xff;					// LCD出力ポート切替
	prc2 = 1;					// P0出力切り替え時の度にプロテクトビット2を1にしてから
	pd0_3 = 1;					// LED出力ポート切替
	prc2 = 1;					// P0出力切り替え時の度にプロテクトビット2を1にしてから
	pd0_4 = 1;					// LED出力ポート切替
	
	LCD_init( 16 );				//　LCD初期化
	LCD_cursol( 1 );			//　カーソルモード設定
	
	// タイマＸ設定
	txmr = 0b00000000;			// タイマXモードレジスタ
	prex = 0xFF;
	tx   = 0xFF;
	tcss = 0b00000000;			// カウントソース設定レジスタ f1

	LED1 = OFF;
	LED2 = ON;
	
	LCD_lineprint( 1, 1, Msg0 );
	LCD_lineprint( 1, 2, Msg1 );
	
	Key_flag = 0;
	n=100;	
	while (1){
		
		Key_flag = KEY_input();
		LED1 = OFF;
		switch( Key_flag ){
			case 1:						// SW1で設定値n-1
				if( n>0 ){
					n = n - 1;
					Itostring_zs( 4, n, Msg1+2 );
					LCD_locate( 1, 2 );
					LCD_print( Msg1 );	
				}
				break;			
			case 2:						// SW1で設定値n+1
				if( n<0xFFFF ){
					n = n + 1;
					Itostring_zs( 4, n, Msg1+2 );
					LCD_locate( 1, 2 );
					LCD_print( Msg1 );	
				}
				break;
			case 3:
										// 計測スタート
				LED1 = ON;
				LED2 = OFF;
				
				prex = 0xFF;
				tx   = 0xFF;
				txs  = 1;				// カウンタ　スタート
		
				for( i=0; i<n; i++ );
		
				txs  = 0;				// カウンタ停止

				LED1 = OFF;
				LED2 = OFF;

				i = prex;
				i = 0xff-i;
				//Itostring_zs(8,i,Msg0);
				j = tx;
				j = 0xff-j;
				//Itostring_zs(8,j,Msg0 + 8);
				
				cnt = 0;
				cnt = j * 0xff + i;

				Itostring_zs( 8, cnt, Msg2 + 8 );
				LCD_lineprint( 1, 1, Msg2 );

				cnt = cnt * F_time / 1000;					// 経過時間表示
				Itostring_zs( 7, cnt, Msg1 + 7 );
				LCD_lineprint( 1, 2, Msg1 );	
				
				Key_flag = 1;							// 設定した数値の1000倍の速度でLED点滅
				while( Key_flag ){
					LED2 = ~LED2;
					for( j=0; j<1000; j++){
						for( i=0; i<n; i++ );
					}
					if( KEY1 == ON | KEY2 == ON){
						Key_flag = 0;
					}
				}
				LED1 = ON;
				LED2 = OFF;
				break;
		}

	}
}

