//**************************************************************************
//インクルードファイル    1lcd_lib_XC32.c
//このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ
// 1lcd_lib.cをもとに、XC32コンパイラ対応等で変更したものです。
//**************************************************************************

///////////////////////////////////////////////
//  液晶表示器制御ライブラリ　for XC32コンパイラー
//  内蔵関数は以下
//　　lcd_init()    ----- 初期化
//    lcd_cmd(cmd)  ----- コマンド出力
//    lcd_data(chr) ----- １文字表示出力
//    lcd_clear()   ----- 全消去
//　　lcd_str(str*) -----　文字列表示	
//////////////////////////////////////////////

#include	"1lcd_lib_XC32.h"

void lcd_delay_us(volatile unsigned int usec)	//1μsec遅延関数
{
	volatile int count;

	count = (int)(lcd_Clock/20000000)*usec;

        do      //実測：　at　200MH (Clock=200000000)
        {       //delay_us(1000)→1000.4μsec、　delay_us(100)→100.6μsec、delay_us(10)→10.5μsec、delay_us(1)→1.5μsec
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

                count--;
        }while(count != 0);
        

}

void lcd_delay_ms(volatile unsigned int msec)	//1msec遅延関数
{
	volatile unsigned int i;
	
	for(i=0; i<msec; i++)
	lcd_delay_us(1000);
}


//////// データ出力サブ関数
void lcd_out(volatile char code, volatile char flag)
{
	if(code & 0b10000000)lcd_port_DB7 = 1;	//LCDのDB7への出力セット
	else lcd_port_DB7 = 0;
	if(code & 0b01000000)lcd_port_DB6 = 1;	//LCDのDB6への出力セット
	else lcd_port_DB6 = 0;
	if(code & 0b00100000)lcd_port_DB5 = 1;	//LCDのDB5への出力セット
	else lcd_port_DB5 = 0;
	if(code & 0b00010000)lcd_port_DB4 = 1;	//LCDのDB４への出力セット
	else lcd_port_DB4 = 0;

	if (flag == 0)
		lcd_rs = 1;			// 表示データの場合
	else
		lcd_rs = 0;			// コマンドデータの場合

        lcd_delay_us(3);		//3μsecウェイト
//	lcd_delay_us(1);		//1μsecウェイト
		
	lcd_stb = 1;			// strobe(E) ON　（Enable）
        lcd_delay_us(3);		//3μsecウェイト
//	lcd_delay_us(1);		// 1μsec ： strobe信号の幅

	lcd_stb = 0;			// reset strobe
}

//////// １文字表示関数
void lcd_data(volatile char asci)
{
	lcd_out(asci, 0);		// 上位４ビット出力
	lcd_out(asci<<4, 0);	// 下位４ビット出力
	lcd_delay_us(50);		//50μsecウェイト
}

/////// コマンド出力関数
void lcd_cmd(volatile char cmd)
{
	lcd_out(cmd, 1);		// 上位４ビット出力
	lcd_out(cmd<<4, 1);		// 下位４ビット出力
	if((cmd & 0x03) != 0)	// clear Homeの場合
	lcd_delay_ms(2);	//	2msec待ち
	else
	lcd_delay_us(50);	//50μsecウェイト	
}

/////// 全消去関数
void lcd_clear(void)
{
	lcd_cmd(0x01);			// 初期化コマンド出力
}

/////// 文字列出力関数
void lcd_str(char* str)      
{
	while(*str)				//文字列終端の '\0'を検出するまで
	{
		lcd_data(*str);		//　１文字表示
		str++;				//ポインタをインクリメント				
	}       
}


/////// 初期化関数
void lcd_init(void)
{
      //LCDポート: 出力モード設定
    lcd_port_DB7_ConfigOut();
    lcd_port_DB6_ConfigOut();  
    lcd_port_DB5_ConfigOut();
    lcd_port_DB4_ConfigOut();
    lcd_rs_ConfigOut();
    lcd_stb_ConfigOut();

    //LCDポートデジタルポート設定
    lcd_port_DB7_ConfigDigital();
    lcd_port_DB6_ConfigDigital();
    lcd_port_DB5_ConfigDigital();
    lcd_port_DB4_ConfigDigital();
    lcd_rs_ConfigDigital();
    lcd_stb_ConfigDigital();
    
	lcd_delay_ms(20);		//20msecウェイト
	lcd_out(0x30, 1);		// 8bit mode set
	lcd_delay_ms(5);		//5msecウェイト
	lcd_out(0x30, 1);		// 8bit mode set
	lcd_delay_ms(1);		//1msecウェイト
	lcd_out(0x30, 1);		// 8bit mode set
	lcd_delay_ms(1);		//1msecウェイト
	lcd_out(0x20, 1);		// 4bit mode set
	lcd_delay_ms(1);		//1msecウェイト
	lcd_cmd(0x2E);			// DL=0 4bit mode
	lcd_cmd(0x08);			// display off C=D=B=0
	lcd_cmd(0x0D);			// display on C=D=1 B=0
	lcd_cmd(0x06);			// entry I/D=1 S=0
	lcd_cmd(0x02);			// cursor home
}




