/************************************************/
/* Demo Program For ET-BASE PIC40/46K22(ICSP)   */
/* MCU Control : PIC18F46K22                    */
/*             : Run 64MHz(Internal 16MHz+PLL)  */ 
/* Compiler    : PIC-CCS Version 4.120          */
/* Function    : Demo GLCD MTB-368(122x32 Pixel)*/
/************************************************/
// GLCD Used MPU:80xx Mode Interface       
// Pin1(GND)       = GND
// Pin2(VDD)       = +5V
// Pin3(VO)        = NC
// Pin4(A0)        = RB0(A0)
// Pin5(CS1)       = RB1(CS1#)
// Pin6(CS2)       = RB2(CS2#)
// Pin7(CL)        = RB3(CL)
// Pin8(RD#,E)     = RB4(RD#)
// Pin9(WR#,R/W)   = RB5(WR#)
// Pin10(DB0)      = RD0(D0)
// Pin11(DB1)      = RD1(D1)
// Pin12(DB2)      = RD2(D2)
// Pin13(DB3)      = RD3(D3)
// Pin14(DB4)      = RD4(D4)
// Pin15(DB5)      = RD5(D5)
// Pin16(DB6)      = RD6(D6)
// Pin17(DB7)      = RD7(D7)
// Pin18(RES)      = GND(Bus MPU:80xx Mode)
// Pin19(BL-A)     = +5V
// Pin20(BL-K)     = GND

#include <18F46K22.h>
#include <stdlib.h>

// Fuses: PIC18F46K22(CCS Compiler)
//////// Fuses: LP,XT,HSH,HSM,ECH,ECH_IO,RC,RC_IO,INTRC_IO,INTRC,ECM,ECM_IO
//////// Fuses: ECL,ECL_IO,NOPLLEN,PLLEN,PRIMARY_SW,PRIMARY_ON,NOFCMEN,FCMEN
//////// Fuses: NOIESO,IESO,PUT,NOPUT,NOBROWNOUT,BROWNOUT_SW,BROWNOUT_NOSL
//////// Fuses: BROWNOUT,BORV45,BORV42,BORV27,BORV20,NOWDT,WDT_NOSLEEP
//////// Fuses: WDT_SW,WDT,WDT1,WDT2,WDT4,WDT8,WDT16,WDT32,WDT64,WDT128
//////// Fuses: WDT256,WDT512,WDT1024,WDT2048,WDT4096,WDT8192,WDT16384
//////// Fuses: WDT32768,CCP2B3,CCP2C1,NOPBADEN,PBADEN,CCP3E0,CCP3B5
//////// Fuses: NOHFOFST,HFOFST,TIMER3B5,TIMER3C0,CCP2C0,CCP2D2,NOMCLR,MCLR
//////// Fuses: NOSTVREN,STVREN,NOLVP,LVP,NOXINST,XINST,DEBUG,NODEBUG
//////// Fuses: PROTECT,NOPROTECT,CPB,NOCPB,CPD,NOCPD,WRT,NOWRT,WRTC,NOWRTC
//////// Fuses: WRTB,NOWRTB,WRTD,NOWRTD,EBTR,NOEBTR,EBTRB,NOEBTRB

//Select Jumper RA6,RA7(XTAL/GPIO) = GPIO
#fuses INTRC_IO,NOWDT,NOPROTECT,NODEBUG,PLLEN                                 //Ineternal 16MHz + PLL(4) = 64MHz 
#use delay(clock=64000000)

//GLCD 122 x 32 Interface
#define GLCD_A0_PIN              PIN_B0                                       // 1=Data,0=Instruction                            
#define GLCD_CS1_PIN             PIN_B1                                       // Left Screen Controller
#define GLCD_CS2_PIN             PIN_B2                                       // Right Screen Controller
#define GLCD_CL_PIN              PIN_B3                                       // Input Clock        
#define GLCD_RD_PIN              PIN_B4                                       // 1=Standby,0=Read
#define GLCD_WR_PIN              PIN_B5                                       // 1=Standby,0=Write 

#define GLCD_DATA0_PIN           PIN_D0 
#define GLCD_DATA1_PIN           PIN_D1  
#define GLCD_DATA2_PIN           PIN_D2   
#define GLCD_DATA3_PIN           PIN_D3  
#define GLCD_DATA4_PIN           PIN_D4 
#define GLCD_DATA5_PIN           PIN_D5  
#define GLCD_DATA6_PIN           PIN_D6   
#define GLCD_DATA7_PIN           PIN_D7 

#define glcd_output_dir_a0()     output_drive(GLCD_A0_PIN)
#define glcd_output_a0(x)        output_bit(GLCD_A0_PIN,x)
#define glcd_output_dir_cs1()    output_drive(GLCD_CS1_PIN)
#define glcd_output_cs1(x)       output_bit(GLCD_CS1_PIN,x)
#define glcd_output_dir_cs2()    output_drive(GLCD_CS2_PIN)
#define glcd_output_cs2(x)       output_bit(GLCD_CS2_PIN,x)
#define glcd_output_dir_cl()     output_drive(GLCD_CL_PIN)
#define glcd_output_cl(x)        output_bit(GLCD_CL_PIN,x)
#define glcd_output_dir_rd()     output_drive(GLCD_RD_PIN)
#define glcd_output_rd(x)        output_bit(GLCD_RD_PIN,x)
#define glcd_output_dir_wr()     output_drive(GLCD_WR_PIN)
#define glcd_output_wr(x)        output_bit(GLCD_WR_PIN,x)

#define glcd_output_dir_data0()  output_drive(GLCD_DATA0_PIN)
#define glcd_input_dir_data0()   output_float(GLCD_DATA0_PIN)
#define glcd_output_data0(x)     output_bit(GLCD_DATA0_PIN,x)
#define glcd_input_data0()       input_state(GLCD_DATA0_PIN)
#define glcd_output_dir_data1()  output_drive(GLCD_DATA1_PIN)
#define glcd_input_dir_data1()   output_float(GLCD_DATA1_PIN)
#define glcd_output_data1(x)     output_bit(GLCD_DATA1_PIN,x)
#define glcd_input_data1()       input_state(GLCD_DATA1_PIN)
#define glcd_output_dir_data2()  output_drive(GLCD_DATA2_PIN)
#define glcd_input_dir_data2()   output_float(GLCD_DATA2_PIN)
#define glcd_output_data2(x)     output_bit(GLCD_DATA2_PIN,x)
#define glcd_input_data2()       input_state(GLCD_DATA2_PIN)
#define glcd_output_dir_data3()  output_drive(GLCD_DATA3_PIN)
#define glcd_input_dir_data3()   output_float(GLCD_DATA3_PIN)
#define glcd_output_data3(x)     output_bit(GLCD_DATA3_PIN,x)
#define glcd_input_data3()       input_state(GLCD_DATA3_PIN)
#define glcd_output_dir_data4()  output_drive(GLCD_DATA4_PIN)
#define glcd_input_dir_data4()   output_float(GLCD_DATA4_PIN)
#define glcd_output_data4(x)     output_bit(GLCD_DATA4_PIN,x)
#define glcd_input_data4()       input_state(GLCD_DATA4_PIN)
#define glcd_output_dir_data5()  output_drive(GLCD_DATA5_PIN)
#define glcd_input_dir_data5()   output_float(GLCD_DATA5_PIN)
#define glcd_output_data5(x)     output_bit(GLCD_DATA5_PIN,x)
#define glcd_input_data5()       input_state(GLCD_DATA5_PIN)
#define glcd_output_dir_data6()  output_drive(GLCD_DATA6_PIN)
#define glcd_input_dir_data6()   output_float(GLCD_DATA6_PIN)
#define glcd_output_data6(x)     output_bit(GLCD_DATA6_PIN,x)
#define glcd_input_data6()       input_state(GLCD_DATA6_PIN)
#define glcd_output_dir_data7()  output_drive(GLCD_DATA7_PIN)
#define glcd_input_dir_data7()   output_float(GLCD_DATA7_PIN)
#define glcd_output_data7(x)     output_bit(GLCD_DATA7_PIN,x)
#define glcd_input_data7()       input_state(GLCD_DATA7_PIN)

#define GLCD_CS1                 0                                            // Left Display Controller
#define GLCD_CS2                 1                                            // Right Display Controller
#define GLCD_WIDTH               122                                          // Column[0..121]

//GLCD 122x32 Command
#define CMD_DISPLAY_MODE         0xAE                                         // 0xAE[+0..1]
#define DISPLAY_OFF              0
#define DISPLAY_ON               1
#define CMD_DISPLAY_START_LINE   0xC0                                         // 0xC0+[0..31]
#define LINE_START               0
#define LIN_END                  31
#define CMD_SET_PAGE_ADDRESS     0xB8                                         // 0xB8+[0..3]
#define PAGE0                    0
#define PAGE1                    1
#define PAGE2                    2
#define PAGE3                    3
#define CMD_SET_COLUMN_ADDRESS   0x00                                         // 0x00+[0..79]    
#define COLUMN0                  0
#define CMD_SELECT_ADC_MODE      0xA0                                         // 0xA0+[0..1]
#define CW_MODE                  0   
#define CCW_MODE                 1
#define CMD_SELECT_DRIVE_MODE    0xA4                                         // 0xA4+[0..1]
#define NORMAL_DRIVE             0                                            // Normal Drive(Static Drive OFF)
#define STATIC_DRIVE             1                                            // Static Drive(Static Drive ON)
#define CMD_SELECT_DUTY_MODE     0xA8                                         // 0xA8+[0..1]
#define RATIO_1_OF_16            0                                            // 1/16
#define RATIO_1_OF_32            1                                            // 1/32
#define CMD_ON_READ_MODIFY       0xE0                                         // 0xE0
#define CMD_OFF_READ_MODIFY      0xEE                                         // 0xEE
#define CMD_SOFT_RESET           0xE2                                         // 0xE2

//Status
#define BUSY                     0x80                                         // D7(1=Busy,0=Ready)
#define ADC                      0x40                                         // D6(1=CW,0=CCW)
#define ON_OFF                   0x20                                         // D5(1=OFF,0=ON)
#define RESET                    0x10                                         // D4(1=Reset Operate,0=Normal Operate)

/************************************/
/* Font Code Size 5:Byte/Font Table */
/************************************/
const unsigned char font_5x7_low[51][5] = 
{
  0x00, 0x00, 0x00, 0x00, 0x00,   // sp  
  0x00, 0x00, 0x2f, 0x00, 0x00,   // !  
  0x00, 0x07, 0x00, 0x07, 0x00,   // "  
  0x14, 0x7f, 0x14, 0x7f, 0x14,   // #  
  0x24, 0x2a, 0x7f, 0x2a, 0x12,   // $  
  0x62, 0x64, 0x08, 0x13, 0x23,   // %  
  0x36, 0x49, 0x55, 0x22, 0x50,   // &  
  0x00, 0x05, 0x03, 0x00, 0x00,   // ’  
  0x00, 0x1c, 0x22, 0x41, 0x00,   // (  
  0x00, 0x41, 0x22, 0x1c, 0x00,   // )  
 
  0x14, 0x08, 0x3E, 0x08, 0x14,   // *  
  0x08, 0x08, 0x3E, 0x08, 0x08,   // +  
  0x00, 0x00, 0xA0, 0x60, 0x00,   // ,  
  0x08, 0x08, 0x08, 0x08, 0x08,   // -  
  0x00, 0x60, 0x60, 0x00, 0x00,   // .  
  0x20, 0x10, 0x08, 0x04, 0x02,   // /  
  0x3E, 0x51, 0x49, 0x45, 0x3E,   // 0  
  0x00, 0x42, 0x7F, 0x40, 0x00,   // 1   
  0x42, 0x61, 0x51, 0x49, 0x46,   // 2  
  0x21, 0x41, 0x45, 0x4B, 0x31,   // 3  
 
  0x18, 0x14, 0x12, 0x7F, 0x10,   // 4  
  0x27, 0x45, 0x45, 0x45, 0x39,   // 5  
  0x3C, 0x4A, 0x49, 0x49, 0x30,   // 6  
  0x01, 0x71, 0x09, 0x05, 0x03,   // 7  
  0x36, 0x49, 0x49, 0x49, 0x36,   // 8  
  0x06, 0x49, 0x49, 0x29, 0x1E,   // 9  
  0x00, 0x36, 0x36, 0x00, 0x00,   // :  
  0x00, 0x56, 0x36, 0x00, 0x00,   // ;  
  0x08, 0x14, 0x22, 0x41, 0x00,   // <  
  0x14, 0x14, 0x14, 0x14, 0x14,   // =  
 
  0x00, 0x41, 0x22, 0x14, 0x08,   // >  
  0x02, 0x01, 0x51, 0x09, 0x06,   // ?  
  0x32, 0x49, 0x59, 0x51, 0x3E,   // @  
  0x7C, 0x12, 0x11, 0x12, 0x7C,   // A  
  0x7F, 0x49, 0x49, 0x49, 0x36,   // B  
  0x3E, 0x41, 0x41, 0x41, 0x22,   // C  
  0x7F, 0x41, 0x41, 0x22, 0x1C,   // D  
  0x7F, 0x49, 0x49, 0x49, 0x41,   // E  
  0x7F, 0x09, 0x09, 0x09, 0x01,   // F  
  0x3E, 0x41, 0x49, 0x49, 0x7A,   // G  
 
  0x7F, 0x08, 0x08, 0x08, 0x7F,   // H  
  0x00, 0x41, 0x7F, 0x41, 0x00,   // I  
  0x20, 0x40, 0x41, 0x3F, 0x01,   // J  
  0x7F, 0x08, 0x14, 0x22, 0x41,   // K  
  0x7F, 0x40, 0x40, 0x40, 0x40,   // L  
  0x7F, 0x02, 0x0C, 0x02, 0x7F,   // M  
  0x7F, 0x04, 0x08, 0x10, 0x7F,   // N  
  0x3E, 0x41, 0x41, 0x41, 0x3E,   // O  
  0x7F, 0x09, 0x09, 0x09, 0x06,   // P  
  0x3E, 0x41, 0x51, 0x21, 0x5E,   // Q  
 
  0x7F, 0x09, 0x19, 0x29, 0x46};  // R  
  
const unsigned char font_5x7_high[44][5] = 
{
  0x46, 0x49, 0x49, 0x49, 0x31,   // S  
  0x01, 0x01, 0x7F, 0x01, 0x01,   // T  
  0x3F, 0x40, 0x40, 0x40, 0x3F,   // U  
  0x1F, 0x20, 0x40, 0x20, 0x1F,   // V  
  0x3F, 0x40, 0x38, 0x40, 0x3F,   // W  
  0x63, 0x14, 0x08, 0x14, 0x63,   // X  
  0x07, 0x08, 0x70, 0x08, 0x07,   // Y  
  0x61, 0x51, 0x49, 0x45, 0x43,   // Z  
  0x00, 0x7F, 0x41, 0x41, 0x00,   // [  
 
  0x55, 0x2A, 0x55, 0x2A, 0x55,   // 55  
  0x00, 0x41, 0x41, 0x7F, 0x00,   // ]  
  0x04, 0x02, 0x01, 0x02, 0x04,   // ^  
  0x40, 0x40, 0x40, 0x40, 0x40,   // _  
  0x00, 0x01, 0x02, 0x04, 0x00,   // ’  
  0x20, 0x54, 0x54, 0x54, 0x78,   // a  
  0x7F, 0x48, 0x44, 0x44, 0x38,   // b  
  0x38, 0x44, 0x44, 0x44, 0x20,   // c  
  0x38, 0x44, 0x44, 0x48, 0x7F,   // d  
  0x38, 0x54, 0x54, 0x54, 0x18,   // e  
  
  0x08, 0x7E, 0x09, 0x01, 0x02,   // f  
  0x18, 0xA4, 0xA4, 0xA4, 0x7C,   // g  
  0x7F, 0x08, 0x04, 0x04, 0x78,   // h  
  0x00, 0x44, 0x7D, 0x40, 0x00,   // i  
  0x40, 0x80, 0x84, 0x7D, 0x00,   // j  
  0x7F, 0x10, 0x28, 0x44, 0x00,   // k  
  0x00, 0x41, 0x7F, 0x40, 0x00,   // l  
  0x7C, 0x04, 0x18, 0x04, 0x78,   // m  
  0x7C, 0x08, 0x04, 0x04, 0x78,   // n  
  0x38, 0x44, 0x44, 0x44, 0x38,   // o  
 
  0xFC, 0x24, 0x24, 0x24, 0x18,   // p  
  0x18, 0x24, 0x24, 0x18, 0xFC,   // q  
  0x7C, 0x08, 0x04, 0x04, 0x08,   // r  
  0x48, 0x54, 0x54, 0x54, 0x20,   // s  
  0x04, 0x3F, 0x44, 0x40, 0x20,   // t  
  0x3C, 0x40, 0x40, 0x20, 0x7C,   // u  
  0x1C, 0x20, 0x40, 0x20, 0x1C,   // v  
  0x3C, 0x40, 0x30, 0x40, 0x3C,   // w  
  0x44, 0x28, 0x10, 0x28, 0x44,   // x  
  0x1C, 0xA0, 0xA0, 0xA0, 0x7C,   // y  
 
  0x44, 0x64, 0x54, 0x4C, 0x44,   // z  
  0x00, 0x08, 0x36, 0x41, 0x00,   // {  
  0x00, 0x00, 0x7F, 0x00, 0x00,   // |  
  0x00, 0x41, 0x36, 0x08, 0x00,   // }  
  0x08, 0x10, 0x08, 0x04, 0x08    // ~  
};

//Picture Bit Map 122x32 Pixel                       
const unsigned char picture1[122] = 
{
  0x00,0x00,0x00,0xC0,0xF0,0xF8,0xF8,0xFC,0x7C,0x7C,
  0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x7C,
  0x7C,0x7C,0x7C,0x7C,0xFC,0xFC,0xFC,0xFC,0xFC,0x7C,
  0x7C,0x7C,0x7C,0x7C,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,
  0xFC,0xFC,0xFC,0xFC,0xFC,0x7C,0x7C,0x7C,0x7C,0x00,
  0x00,0x00,0x00,0xFC,0xFC,0xFC,0xBC,0xBC,0xBC,0x8C,
  0x00,0xFC,0xFC,0x00,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,
  0x60,0xE0,0xF0,0xF0,0x90,0xB0,0xB0,0x00,0x38,0xFC,
  0xFC,0xB8,0x00,0xF0,0xF0,0xF0,0x30,0x00,0xF0,0xF0,
  0x90,0xF0,0xF0,0xF0,0x00,0xF0,0xF0,0x30,0xF0,0xF0,
  0xF0,0x00,0xFC,0xFC,0x00,0x60,0xF0,0xF0,0x90,0xB0,
  0xB0,0x00,0xA0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,
  0x00,0x00};

const unsigned char picture2[122] = 
{
  0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xE0,
  0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0x00,0x00,
  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x60,0x71,0xF1,0xF1,0xF1,0x71,0x61,
  0x80,0xC1,0xC1,0xC0,0xC0,0x81,0x01,0x81,0xC1,0xC1,
  0xC0,0xC0,0x81,0x01,0xE1,0xF1,0xC0,0xC0,0xC0,0x81,
  0x01,0xC1,0xC0,0xC1,0xC1,0xC0,0x80,0x00,0x80,0xC1,
  0xC1,0xC1,0xC1,0x80,0x00,0xF1,0xF1,0x00,0x80,0xC1,
  0xC1,0xC0,0xC1,0x81,0x00,0x80,0xC0,0xC1,0xC1,0xC1,
  0xC0,0x00,0xC0,0xC1,0x81,0x01,0xC1,0xC0,0x00,0x00,
  0x00,0x00};

const unsigned char picture3[122] = 
{
  0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x03,
  0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,
  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x80,0x80,0x87,0x87,0x87,0x80,0x80,
  0x07,0x07,0x0F,0x0F,0x07,0x07,0x01,0x07,0x07,0x0E,
  0x0C,0x06,0x06,0x00,0x07,0x07,0x00,0x07,0x07,0x07,
  0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x07,
  0x0C,0x07,0x07,0x03,0x00,0x07,0x07,0x00,0x03,0x07,
  0x07,0x0C,0x07,0x07,0x01,0x0B,0x1F,0x1F,0x1E,0x1F,
  0x1F,0x00,0x10,0x1B,0x1F,0x1F,0x0F,0x01,0x00,0x00,
  0x00,0x00};

const unsigned char picture4[122] = 
{
  0x00,0x00,0x00,0x03,0x0F,0x1F,0x1F,0x3F,0x3E,0x3E,
  0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x00,0x00,
  0x00,0x00,0x00,0x00,0x3F,0x3F,0x3F,0x3F,0x3F,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x3F,0x3F,0x3F,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x01,0x01,0x3F,0x3F,0x3F,0x01,0x01,
  0x1C,0x3E,0x3E,0x3E,0x3E,0x3E,0x00,0x3E,0x3E,0x3E,
  0x3E,0x3E,0x3E,0x00,0x3E,0x3E,0x3E,0x1E,0x3E,0x3E,
  0x06,0x3E,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00
};

/****************************/
/* Timer2 Interrupt Service */
/*   (2KHz Generate Clock)  */
/****************************/
#INT_TIMER2
void TMR2_ISR(void)
{   
  output_toggle(GLCD_CL_PIN);        
}

/* pototype  section */
void glcd_init(void);
void glcd_send_data(unsigned char dev,unsigned char lcd_dat);
void glcd_send_command(unsigned char dev,unsigned char lcd_cmd);
unsigned char glcd_read_data(unsigned char dev);
unsigned char glcd_read_command(unsigned char dev);
void glcd_fill_screen(unsigned char ch);
void glcd_print_text(unsigned char x,unsigned char y,char *text);
void glcd_show_bmp(void);

/****************/
/* Main Program */
/****************/
void main() 
{
  char text [21];                                                             // GLCD Display Text
  
  setup_oscillator(OSC_16MHZ|OSC_PLL_ON);                                     // Sets the Internal Oscillator to 64MHz (PLL Enabled)  
  glcd_init();                                                                // Initial GLCD

  //Initial & Enable Interrupt
  setup_timer_2(T2_DIV_BY_4,124,4);                                           // Timer2 32MHz/2KHz Interrupt 
  enable_interrupts(INT_TIMER2);
  enable_interrupts(GLOBAL); 
  
  while(true)
  {
    glcd_fill_screen(0x00);                                                   // Clear Left Screen Display
    glcd_show_bmp();  
    delay_ms(2500);
    
    glcd_fill_screen(0x00);                                                   // Clear Left Screen Display
    sprintf(text,"THIS IS STRING LINE1");    
    glcd_print_text(0,0,text);                                                // x,y,string      
    sprintf(text,"THIS IS STRING LINE2");    
    glcd_print_text(0,1,text);                                                // x,y,string
    sprintf(text,"THIS IS STRING LINE3");    
    glcd_print_text(0,2,text);                                                // x,y,string
    sprintf(text,"THIS IS STRING LINE4");    
    glcd_print_text(0,3,text);                                                // x,y,string
    delay_ms(2500);

    glcd_fill_screen(0xFF);                                                   // Clear Left Screen Display
    delay_ms(2500);

    glcd_fill_screen(0x00);                                                   // Clear Left Screen Display
    sprintf(text,"MCU:PIC(PIC18F46K22)");    
    glcd_print_text(0,0,text);                                                // x,y,string      
    sprintf(text,"GLCD:MTB-368(122x32)");    
    glcd_print_text(0,1,text);                                                // x,y,string
    sprintf(text,"Size : 122x32 Pixel ");    
    glcd_print_text(0,2,text);                                                // x,y,string
    sprintf(text,"BY......ETT CO.,LTD.");    
    glcd_print_text(0,3,text);                                                // x,y,string
    delay_ms(2500);    
  }  
}

/*****************************/
/* Initial GLCD 122x32 Pixel */
/*   MPU(80) Interface Mode  */
/*****************************/
void glcd_init(void) 
{    
  glcd_output_dir_data0();                                                    // Data = Output
  glcd_output_dir_data1();
  glcd_output_dir_data2();
  glcd_output_dir_data3();
  glcd_output_dir_data4();                                         
  glcd_output_dir_data5();
  glcd_output_dir_data6();
  glcd_output_dir_data7();
  glcd_output_dir_a0();                                                       // Control = Output
  glcd_output_dir_cs1();
  glcd_output_dir_cs2();
  glcd_output_dir_cl();
  glcd_output_dir_rd();
  glcd_output_dir_wr();
  glcd_output_rd(1);                                                          // Standby Read
  glcd_output_wr(1);                                                          // Standby Write
  glcd_output_cs1(1);
  glcd_output_cs2(1);       
  glcd_output_data0(0);
  glcd_output_data1(0);
  glcd_output_data2(0);
  glcd_output_data3(0);
  glcd_output_data4(0);
  glcd_output_data5(0);
  glcd_output_data6(0);
  glcd_output_data7(0);
    
  //Start Initial GLCD & Clear Display 
  glcd_send_command(GLCD_CS1,CMD_SOFT_RESET);                                 // Soft Reset GLCD Controller
  while((glcd_read_command(GLCD_CS1) & RESET) == RESET);                      // Wait Reset(D4) = 0
  glcd_send_command(GLCD_CS2,CMD_SOFT_RESET);                                 // Soft_Reset GLCD Controller
  while((glcd_read_command(GLCD_CS2) & RESET) == RESET);                      // Wait Reset(D4) = 0
  
  glcd_send_command(GLCD_CS1,CMD_DISPLAY_MODE+DISPLAY_ON);                    // Turn-ON Display(ON,OFF)
  glcd_send_command(GLCD_CS2,CMD_DISPLAY_MODE+DISPLAY_ON);                    // Turn-ON Display(ON,OFF)  
  
  glcd_send_command(GLCD_CS1,CMD_DISPLAY_START_LINE+LINE_START);              // Display Satrt Line(0..31)
  glcd_send_command(GLCD_CS2,CMD_DISPLAY_START_LINE+LINE_START);              // Display Satrt Line(0..31)
  
  glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+PAGE0);                     // Set Page Address(0..3)
  glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+PAGE0);                     // Set Page Address(0..3)
  
  glcd_send_command(GLCD_CS1,CMD_SET_COLUMN_ADDRESS+COLUMN0);                 // Set Column Address(0..79)
  glcd_send_command(GLCD_CS2,CMD_SET_COLUMN_ADDRESS+COLUMN0);                 // Set Column Address(0..79)
  
  glcd_send_command(GLCD_CS1,CMD_SELECT_ADC_MODE+CW_MODE);                    // Select ADC Mode(CW,CCW)
  glcd_send_command(GLCD_CS2,CMD_SELECT_ADC_MODE+CW_MODE);                    // Select ADC Mode(CW,CCW)
  
  glcd_send_command(GLCD_CS1,CMD_SELECT_DRIVE_MODE+NORMAL_DRIVE);             // Select Drive Operation(Nornal,Static)
  glcd_send_command(GLCD_CS2,CMD_SELECT_DRIVE_MODE+NORMAL_DRIVE);             // Select Drive Operation(Normal,Static)
  
  glcd_send_command(GLCD_CS1,CMD_SELECT_DUTY_MODE+RATIO_1_OF_32);             // Set Column Address(0)
  glcd_send_command(GLCD_CS2,CMD_SELECT_DUTY_MODE+RATIO_1_OF_32);             // Set Column Address(0)
  
  glcd_send_command(GLCD_CS1,CMD_OFF_READ_MODIFY);                            // Select Normal Data Display
  glcd_send_command(GLCD_CS2,CMD_OFF_READ_MODIFY);                            // Select Normal Data Display
  
  glcd_fill_screen(0x00);                                                     // Clear Left Screen Display    
}

/**************************/
/* Write GLCD 122x32 Data */
/* MPU(80) Interface Mode */
/**************************/
void glcd_send_data(unsigned char dev,unsigned char lcd_dat) 
{ 
  while((glcd_read_command(dev) & 0x80) == 0x80);                             // Wait Busy(D7) = 0
  
  glcd_output_a0(1);                                                          // Select Data
  glcd_output_rd(1);                                                          // Standby Read
  glcd_output_wr(1);                                                          // Standby Write                                               
  delay_cycles(1);       
  glcd_output_data7(((lcd_dat & 0x80)>>7));                                   // Data 
  glcd_output_data6(((lcd_dat & 0x40)>>6));
  glcd_output_data5(((lcd_dat & 0x20)>>5));
  glcd_output_data4(((lcd_dat & 0x10)>>4));
  glcd_output_data3(((lcd_dat & 0x08)>>3));                        
  glcd_output_data2(((lcd_dat & 0x04)>>2));
  glcd_output_data1(((lcd_dat & 0x02)>>1));
  glcd_output_data0((lcd_dat & 0x01));      
  delay_cycles(1);   
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(0);                                                       // Active CS1  
  }
  else
  {
    glcd_output_cs2(0);                                                       // Active CS2 
  }
  
  glcd_output_wr(0);                                                          // Write Bus
  delay_us(2);                                                                // Enable Pulse Delay  
  glcd_output_wr(1);                                                          // Standby Write
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(1);                                                       // Disable CS1
  }
  else
  {
    glcd_output_cs2(1);                                                       // Disable CS2
  }
  
}

/**************************/
/* Write GLCD Instruction */
/* MPU(80) Interface Mode */
/**************************/
void glcd_send_command(unsigned char dev,unsigned char lcd_cmd) 
{
  while((glcd_read_command(dev) & 0x80) == 0x80);                             // Wait Busy(D7) = 0
  
  glcd_output_a0(0);                                                          // Select Instruction  
  glcd_output_rd(1);                                                          // Standby Read
  glcd_output_wr(1);                                                          // Standby Write  
  delay_cycles(1);        
  glcd_output_data7(((lcd_cmd & 0x80)>>7));                        
  glcd_output_data6(((lcd_cmd & 0x40)>>6));
  glcd_output_data5(((lcd_cmd & 0x20)>>5));
  glcd_output_data4(((lcd_cmd & 0x10)>>4));
  glcd_output_data3(((lcd_cmd & 0x08)>>3));                       
  glcd_output_data2(((lcd_cmd & 0x04)>>2));
  glcd_output_data1(((lcd_cmd & 0x02)>>1));
  glcd_output_data0((lcd_cmd & 0x01));   
  delay_cycles(1);
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(0);                                                       // Active CS1
  }
  else
  {
    glcd_output_cs2(0);                                                       // Active CS2
  }
  
  glcd_output_wr(0);                                                          // Write Bus
  delay_us(2);                                                                // Enable Pulse Delay  
  glcd_output_wr(1);                                                          // Standby Write
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(1);                                                       // Disable CS1    
  }
  else
  {
    glcd_output_cs2(1);                                                       // Disable CS2   
  }
  
}

/**************************/
/* Read GLCD 122x32 Data  */
/* MPU(80) Interface Mode */
/**************************/
unsigned char glcd_read_data(unsigned char dev)  
{
  BYTE dat_read = 0x00;
  
  glcd_output_a0(1);                                                          // Select Data
  glcd_output_rd(1);                                                          // Standby Read
  glcd_output_wr(1);                                                          // Standby Write                                               
  glcd_input_dir_data0();                                                     // Data = Input(Read Bus)
  glcd_input_dir_data1();
  glcd_input_dir_data2();
  glcd_input_dir_data3();    
  glcd_input_dir_data4();                                       
  glcd_input_dir_data5();
  glcd_input_dir_data6();
  glcd_input_dir_data7(); 
  delay_cycles(1);   
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(0);                                                       // Active CS1  
  }
  else
  {
    glcd_output_cs2(0);                                                       // Active CS2 
  }
  
  glcd_output_rd(0);                                                          // Read Bus
  delay_us(1);                                                                // Enable Pulse Delay  
  dat_read |= input(GLCD_DATA7_PIN) << 7;                                     // Data D7
  dat_read |= input(GLCD_DATA6_PIN) << 6;                                     // Data D6
  dat_read |= input(GLCD_DATA5_PIN) << 5;                                     // Data D5
  dat_read |= input(GLCD_DATA4_PIN) << 4;                                     // Data D4  
  dat_read |= input(GLCD_DATA3_PIN) << 3;                                     // Data D3
  dat_read |= input(GLCD_DATA2_PIN) << 2;                                     // Data D2
  dat_read |= input(GLCD_DATA1_PIN) << 1;                                     // Data D1
  dat_read |= input(GLCD_DATA0_PIN);                                          // Data D0  
  delay_us(1);
  glcd_output_rd(1);                                                          // Standby Read
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(1);                                                       // Disable CS1
  }
  else
  {
    glcd_output_cs2(1);                                                       // Disable CS2
  }
  
  glcd_output_dir_data0();                                                    // Data = Output(Write Bus)
  glcd_output_dir_data1();
  glcd_output_dir_data2();
  glcd_output_dir_data3();
  glcd_output_dir_data4();                                        
  glcd_output_dir_data5();
  glcd_output_dir_data6();
  glcd_output_dir_data7();
     
  return(dat_read);
}

/*************************/
/* Read GLCD Instruction */
/* MPU(80)Interface Mode */
/*************************/
unsigned char glcd_read_command(unsigned char dev) 
{  
  BYTE cmd_read = 0x00;
  
  glcd_output_a0(0);                                                          // Select Instruction 
  glcd_output_rd(1);                                                          // Standby Read
  glcd_output_wr(1);                                                          // Standby Write                                               
  glcd_input_dir_data0();                                                     // Data = Input(Read Bus)
  glcd_input_dir_data1();
  glcd_input_dir_data2();
  glcd_input_dir_data3();    
  glcd_input_dir_data4();                                      
  glcd_input_dir_data5();
  glcd_input_dir_data6();
  glcd_input_dir_data7();   
  delay_cycles(1);   
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(0);                                                       // Active CS1  
  }
  else
  {
    glcd_output_cs2(0);                                                       // Active CS2 
  }
  
  glcd_output_rd(0);                                                          // Read Bus
  delay_us(1);                                                                // Enable Pulse Delay       
  cmd_read |= input(GLCD_DATA7_PIN) << 7;                                     // Data D7
  cmd_read |= input(GLCD_DATA6_PIN) << 6;                                     // Data D6
  cmd_read |= input(GLCD_DATA5_PIN) << 5;                                     // Data D5
  cmd_read |= input(GLCD_DATA4_PIN) << 4;                                     // Data D4  
  cmd_read |= input(GLCD_DATA3_PIN) << 3;                                     // Data D3
  cmd_read |= input(GLCD_DATA2_PIN) << 2;                                     // Data D2
  cmd_read |= input(GLCD_DATA1_PIN) << 1;                                     // Data D1
  cmd_read |= input(GLCD_DATA0_PIN);                                          // Data D0  
  delay_us(1);
  glcd_output_rd(1);                                                          // Standby Read
  
  if(dev == GLCD_CS1)
  {
    glcd_output_cs1(1);                                                       // Disable CS1
  }
  else
  {
    glcd_output_cs2(1);                                                       // Disable CS2
  }
  
  glcd_output_dir_data0();                                                    // Data = Output(Write Bus)
  glcd_output_dir_data1();
  glcd_output_dir_data2();
  glcd_output_dir_data3();
  glcd_output_dir_data4();                                     
  glcd_output_dir_data5();
  glcd_output_dir_data6();
  glcd_output_dir_data7();
     
  return(cmd_read);
}

/****************************/
/* Fill Screen 122x32 Pixel */
/*  MPU(80) Interface Mode  */
/****************************/
void glcd_fill_screen(unsigned char ch)
{
  unsigned char page,column;
    
  for(page = 0; page < 4; page++)                                             // 4 Page Display
  {
    glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+page);                    // Set Page   Address[0..3]
    glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+page);                    // Set Page   Address[0..3]
    glcd_send_command(GLCD_CS1,0);                                            // Set Column Address(0)--->[00..79]
    glcd_send_command(GLCD_CS2,0);                                            // Set Column Address(0)--->[00..79]
    
    for(column = 0; column < 61; column++)                                    // 61 Column / Page
    {      
      glcd_send_data(GLCD_CS1,ch);                                            // Field Column
      glcd_send_data(GLCD_CS2,ch);                                            // Field Column
    }    
  }
  
  //Set Start Address Page(0),Column(0)
  glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+PAGE0);                     // Set Page(0xB8+[0..3]  
  glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+PAGE0);                     // Set Page(0xB8+[0..3] 
  glcd_send_command(GLCD_CS1,0);                                              // Set Column Address(0)--->[00..79] 
  glcd_send_command(GLCD_CS2,0);                                              // Set Column Address(0)--->[00..79]
}

void glcd_print_text(unsigned char x,unsigned char y,char *text)
{  
  unsigned char   text_ptr,column;
  unsigned char   pixelData[5];                                               // Stores character data
  
  if(x <= 60)
  {
    glcd_send_command(GLCD_CS1,CMD_SET_COLUMN_ADDRESS+x);                     // Set x Cursor Controller[1]
    glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+y);                       // Set Y Cursor Controller[1]

    glcd_send_command(GLCD_CS2,CMD_SET_COLUMN_ADDRESS+0);                     // Set x Cursor Controller[2]    
    glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+y);                       // Set Y Cursor Controller[2]
  }
  else
  {
    glcd_send_command(GLCD_CS2,(CMD_SET_COLUMN_ADDRESS+x)-60);                // Set x Cursor Controller[2]
    glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+y);                       // Set Y Cursor Controller[2]
  }
 
  while(*text != 0)
  {
    text_ptr = *text;
    
    
    if(text_ptr < 'S')    
    {
      //5 Pixel(Column) Font Data
      memcpy(pixelData, font_5x7_low[text_ptr-' '], 5);      
      for(column = 0; column<5; column++)
      {
        if(x <= 60)
        {
          glcd_send_data(GLCD_CS1,pixelData[column]);                         // 00..60 = Controller[1]         
        }
        else if((x > 60)&&( x < 122))
        {
          glcd_send_data(GLCD_CS2,pixelData[column]);                         // 61..121 = Controller[2]
        }
        x++;                                                                  // Next Column
      }
    }
    else
    {
      //5 Pixel(Column) Font Data
      memcpy(pixelData, font_5x7_high[text_ptr-'S'], 5);      
      for(column = 0;column<5; column++)
      {
        if(x <= 60)
        {
          glcd_send_data(GLCD_CS1,pixelData[column]);                         // 00..60 = Controller[1]         
        }
        else if((x > 60)&&( x < 122))
        {
          glcd_send_data(GLCD_CS2,pixelData[column]);                         // 61..121 = Controller[2]
        }
        x++;                                                                  // Next Column
      }
    }
       
    //1 Pixel(Column) Font Space    
    if(x <= 60)
    {
      glcd_send_data(GLCD_CS1,0);                                             // 00..60 = Controller[1]
    }
    else if((x > 60)&&( x < 122))
    {
      glcd_send_data(GLCD_CS2,0);                                             // 61..121 = Controller[2]
    }
    x++;                                                                      // Next Column
      
    text++;                                                                   // Next Font
  }
}

/***************************/
/* Show Graphic Bitmap BMP */
/*  MPU(80) Interface Mode */
/***************************/
void glcd_show_bmp(void)
{
  unsigned char column;
 
  //Page[0]
  //Column[0..60] Write to Controller[1]
  glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+PAGE0);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS1,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS1,picture1[column]);
  }  
  //Column[61..121] Write to Controller[2]
  glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+PAGE0);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS2,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS2,picture1[column+61]);
  }
     
  //Page[1]
  //Column[0..60] Write to Controller[1]
  glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+PAGE1);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS1,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS1,picture2[column]);
  }  
  //Column[61..121] Write to Controller[2]
  glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+PAGE1);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS2,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS2,picture2[column+61]);
  }  
  
  //Page[2]
  //Column[0..60] Write to Controller[1]
  glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+PAGE2);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS1,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS1,picture3[column]);
  }  
  //Column[61..121] Write to Controller[2]
  glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+PAGE2);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS2,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS2,picture3[column+61]);
  }
  
  //Page[3]
  //Column[0..60] Write to Controller[1]
  glcd_send_command(GLCD_CS1,CMD_SET_PAGE_ADDRESS+PAGE3);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS1,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS1,picture4[column]);
  }  
  //Column[61..121] Write to Controller[2]
  glcd_send_command(GLCD_CS2,CMD_SET_PAGE_ADDRESS+PAGE3);                     // Set Page   Address[0..3]    
  glcd_send_command(GLCD_CS2,0);                                              // Set Column Address(0)
  for(column = 0; column < 61; column++)                                      // 61 Column / Page
  {    
    glcd_send_data(GLCD_CS2,picture4[column+61]);
  }    
}


