t6963.c

Code to drive a Toshiba T6963C based graphic LCD module (by Richard Taylor).




/********************************************

 * Filename: t6963.c                        *

 *                                          *

 * Description: Toshiba LCD Driver Functions*

 *                                          *

 * by Richard Taylor                        *

 *                                          *

 * Date: 09/02/2003                         *

 *******************************************/

/* includes */

#include <system.h>

#include "t6963.h"



/* Global Variables */



void interrupt( void )

{

    disable_interrupt( GIE );

}



main()

{

    unsigned char n, address_h, address_l, x, y;

    unsigned int address;



    /* Initialise the controller */

    lcd_initialise();

    /* Clear Graphic RAM */

    lcd_clear_graphics();

    /* Clear Text RAM */

    lcd_clear_text();



    /* Set Text Mode and Graphics Mode On */

    lcd_write_command(LCD_DISPLAY_MODES_GRAPHICS_ON | LCD_DISPLAY_MODES_TEXT_ON);



    /* Write some data to display */

    lcd_write_text('1', 1, 0);

    lcd_write_text('2', 2, 0);

    lcd_write_text('3', 3, 0);

    lcd_write_text('4', 4, 0);

    lcd_write_text('5', 5, 0);

    lcd_write_text('6', 6, 0);



    lcd_write_text('a', 0, 1);

    lcd_write_text('b', 0, 2);

    lcd_write_text('c', 0, 3);

    lcd_write_text('d', 0, 4);

    lcd_write_text('e', 0, 5);

    lcd_write_text('f', 0, 6);



    /* Set Address Pointer To GRAPHIC Home */

    lcd_write_data(LCD_GRAPHICS_HOME); /* LSB */

    lcd_write_data(LCD_GRAPHICS_HOME >> 8); /* MSB */

    lcd_write_command(LCD_ADDRESS_POINTER_SET);



    /* Plot a few points (Draw an X) */

    for (x=10; x<20; x++)

    {

        y = x;

        lcd_set_pixel(x, y);

        y = 30 - x;

        lcd_set_pixel(x, y);

    }



    for (x=8; x<57; x++)

    {

        lcd_set_pixel(x, 9);

    }

    for (y=8; y<57; y++)

    {

        lcd_set_pixel(9, y);

    }





    /* Display a knight-rider type line */

    while (1)

    {

        for (x=20; x<61; x++)

        {

            lcd_set_pixel(x, 63);

            lcd_set_pixel(x, 64);

            lcd_set_pixel(x, 65);

            delay_ms(100);

            lcd_clear_pixel(x, 63);

            lcd_clear_pixel(x, 64);

            lcd_clear_pixel(x, 65);

        }

        for (x=60; x>21; x--)

        {

            lcd_set_pixel(x, 64);

            delay_ms(200);

            lcd_clear_pixel(x, 64);

        }

    }

}





/********************************************

 * Function name: initialise                *

 * Description:   Initialise PIC and LCD    *

 *******************************************/

void lcd_initialise(void)

{

    /* Set Control Lines to outputs and High */

    LCD_CONTROL = LCD_CONTROL | LCD_WR | LCD_RD | LCD_CE | LCD_CD | LCD_RST;

    LCD_CONTROL_TRIS = LCD_CONTROL_TRIS & (~(LCD_WR | LCD_RD | LCD_CE | LCD_CD | LCD_RST));

    LCD_CONTROL = LCD_WR | LCD_RD | LCD_CE | LCD_CD | LCD_RST;



    /* Set PORTB to inputs */

    LCD_DATA_BUS_TRIS = ALL_INPUTS;



    /* Hold Reset Line for 1ms */

    clear_bit(LCD_CONTROL, LCD_RST_BIT);

    delay_s(2);

    set_bit(LCD_CONTROL, LCD_RST_BIT);



    /* Set Char Gen Up */

    lcd_write_command(LCD_CG_ROM_MODE_OR);



    /* Set Graphic Home Address */

    lcd_write_data(LCD_GRAPHICS_HOME);

    lcd_write_data(LCD_GRAPHICS_HOME >> 8);

    lcd_write_command(LCD_GRAPHIC_HOME_ADDRESS_SET);



    /* Set Graphic Area */

    lcd_write_data(LCD_GRAPHICS_AREA); /* Width of 20 Chars */

    lcd_write_data(0x00);

    lcd_write_command(LCD_GRAPHIC_AREA_SET);



    /* Set Text Home Address */

    lcd_write_data(LCD_TEXT_HOME);

    lcd_write_data(LCD_TEXT_HOME >> 8);

    lcd_write_command(LCD_TEXT_HOME_ADDRESS_SET);



    /* Set Text Area */

    lcd_write_data(LCD_TEXT_AREA); /* Width of 20 Chars */

    lcd_write_data(0x0);

    lcd_write_command(LCD_TEXT_AREA_SET);



}



/********************************************

 * Function name: lcd_write_data            *

 * Description:   Write Data to LCD         *

 *******************************************/

void lcd_write_data(unsigned char data)

{

    /* While BUSY1 and BUSY2 are not 1 */

    while ( (lcd_read_status() & (LCD_STATUS_BUSY1 | LCD_STATUS_BUSY2)) != (LCD_STATUS_BUSY1 | LCD_STATUS_BUSY2));



    /* Clear C/D# */

    clear_bit(LCD_CONTROL, LCD_CD_BIT);



    /* Set Data Lines to Output */

    LCD_DATA_BUS = data;

    LCD_DATA_BUS_TRIS = ALL_OUTPUTS;



    /* Clear CE and WR, set RD */

    clear_bit(LCD_CONTROL, LCD_CE_BIT);

    clear_bit(LCD_CONTROL, LCD_WR_BIT);



    nop();

    nop();



    /* Set CE and RD*/

    set_bit(LCD_CONTROL, LCD_CE_BIT);

    set_bit(LCD_CONTROL, LCD_WR_BIT);

    set_bit(LCD_CONTROL, LCD_CD_BIT);



    /* Set Data Lines to Input */

    LCD_DATA_BUS_TRIS = ALL_INPUTS;

}



/********************************************

 * Function name: lcd_read_data             *

 * Description:   Read Data From LCD        *

 *******************************************/

unsigned char lcd_read_data(void)

{

    unsigned char data;



    /* While BUSY1 and BUSY2 are not 1 */

    while ( (lcd_read_status() & (LCD_STATUS_BUSY1 | LCD_STATUS_BUSY2)) != (LCD_STATUS_BUSY1 | LCD_STATUS_BUSY2));



    /* Clear C/D# */

    clear_bit(LCD_CONTROL, LCD_CD_BIT);



    /* Set Data Lines to Input */

    LCD_DATA_BUS_TRIS = ALL_INPUTS;



    /* Clear CE and RD, set WR */

    clear_bit(LCD_CONTROL, LCD_CE_BIT);

    clear_bit(LCD_CONTROL, LCD_RD_BIT);



    nop();

    /* Read Data Bus */

    data = LCD_DATA_BUS;



    /* Set CE and RD*/

    set_bit(LCD_CONTROL, LCD_CE_BIT);

    set_bit(LCD_CONTROL, LCD_RD_BIT);

    set_bit(LCD_CONTROL, LCD_CD_BIT);



    return data;

}



/********************************************

 * Function name: lcd_write_command         *

 * Description:   Write Command to LCD      *

 *******************************************/

void lcd_write_command(unsigned char data)

{

    unsigned char status;



    /* While BUSY1 and BUSY2 are not 1 */

    while ( (lcd_read_status() & (LCD_STATUS_BUSY1 | LCD_STATUS_BUSY2)) != (LCD_STATUS_BUSY1 | LCD_STATUS_BUSY2));



    /* Set C/D# */

    set_bit(LCD_CONTROL, LCD_CD_BIT);



    /* Set Data Lines to Output */

    LCD_DATA_BUS = data;

    LCD_DATA_BUS_TRIS = ALL_OUTPUTS;



    /* Clear CE and WR, set RD */

    clear_bit(LCD_CONTROL, LCD_CE_BIT);

    clear_bit(LCD_CONTROL, LCD_WR_BIT);



    nop();

    nop();



    /* Set CE and RD*/

    set_bit(LCD_CONTROL, LCD_CE_BIT);

    set_bit(LCD_CONTROL, LCD_WR_BIT);

    set_bit(LCD_CONTROL, LCD_CD_BIT);



    /* Set Data Lines to Input */

    LCD_DATA_BUS_TRIS = ALL_INPUTS;

}



/********************************************

 * Function name: lcd_read_status           *

 * Description:   Read Status From LCD      *

 *******************************************/

unsigned char lcd_read_status(void)

{

    unsigned char data;



    /* Set C/D# */

    set_bit(LCD_CONTROL, LCD_CD_BIT);



    /* Set Data Lines to Input */

    LCD_DATA_BUS_TRIS = ALL_INPUTS;



    /* Clear CE and RD */

    clear_bit(LCD_CONTROL, LCD_CE_BIT);

    clear_bit(LCD_CONTROL, LCD_RD_BIT);



    nop();



    /* Read Data Bus */

    data = LCD_DATA_BUS;



    /* Set All Bits */

    set_bit(LCD_CONTROL, LCD_CE_BIT);

    set_bit(LCD_CONTROL, LCD_RD_BIT);

    set_bit(LCD_CONTROL, LCD_CD_BIT);



    return data;

}



/********************************************

 * Function name: lcd_clear_graphics        *

 * Description:   Wipe Graphics RAM         *

 *******************************************/

void lcd_clear_graphics(void)

{

    unsigned char address_l, address_h;

    unsigned int address, address_limit;

    /* Set Address Pointer */

    address = LCD_GRAPHICS_HOME;

    address_l = address & 0xff;

    address_h = address >> 8;

    lcd_write_data(address_l);

    lcd_write_data(address_h);

    lcd_write_command(LCD_ADDRESS_POINTER_SET);



    address_limit = (LCD_GRAPHICS_HOME + LCD_GRAPHICS_SIZE);



    while (address < address_limit)

    {

        lcd_write_data(0x00);

        lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

        address = address + 1;

    }



    if (LCD_NUMBER_OF_SCREENS == 0x02)

    {

        /* Set Address Pointer */

        address = LCD_GRAPHICS_HOME + 0x8000;

        address_l = address & 0xff;

        address_h = address >> 8;

        lcd_write_data(address_l);

        lcd_write_data(address_h);

        lcd_write_command(LCD_ADDRESS_POINTER_SET);



        address_limit = (LCD_GRAPHICS_HOME + LCD_GRAPHICS_SIZE +0x8000);

        while (address < address_limit)

        {

            lcd_write_data(0x00);

            lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

            address = address + 1;

        }



    }

}



/********************************************

 * Function name: lcd_clear_text            *

 * Description:   Wipe Text RAM             *

 *******************************************/

void lcd_clear_text(void)

{

    unsigned char address_l, address_h;

    unsigned int address, address_limit;

    /* Set Address Pointer */

    address = LCD_TEXT_HOME;

    address_l = address & 0xff;

    address_h = address >> 8;

    lcd_write_data(address_l);

    lcd_write_data(address_h);

    lcd_write_command(LCD_ADDRESS_POINTER_SET);



        address_limit =  (LCD_TEXT_HOME + LCD_TEXT_SIZE);

        while (address < address_limit)

    {

        lcd_write_data(0x00);

        lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

        address = address + 1;

    }



    if (LCD_NUMBER_OF_SCREENS == 0x02)

    {

        /* Set Address Pointer */

        address = LCD_TEXT_HOME + 0x8000;

        address_l = address & 0xff;

        address_h = address >> 8;

        lcd_write_data(address_l);

        lcd_write_data(address_h);

        lcd_write_command(LCD_ADDRESS_POINTER_SET);



        address_limit =  (LCD_TEXT_HOME + LCD_TEXT_SIZE + 0x8000);

        while (address < address_limit)

        {

            lcd_write_data(0x00);

            lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

            address = address + 1;

        }

    }

}



/********************************************

 * Function name: lcd_write_text            *

 * Description:   Write Character to X, Y   *

 *                0 <= X <= LCD Text Width  *

 *                0 <= Y <= LCD Text Height *

 *******************************************/

void lcd_write_text(unsigned char character, unsigned char x, unsigned char y)

{

    unsigned int address;



    address = (y * LCD_TEXT_AREA) + x + LCD_TEXT_HOME;

    if (y > 63 && LCD_NUMBER_OF_SCREENS == 2) /* If we are on the second screen and it exists */

    {

        address = address + 0x8000;

    }



    character = character - 0x20;   /* Adjust standard ASCII to T6963 ASCII */



    lcd_write_data(address & 0xff);

    lcd_write_data(address >> 0x08);

    lcd_write_command(LCD_ADDRESS_POINTER_SET);

    lcd_write_data(character);

    lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

}



/********************************************

 * Function name: lcd_set_pixel             *

 * Description:   Set a single Pixel on     *

 *                0 <= X <= LCD Width       *

 *                0 <= Y <= LCD Height      *

 *******************************************/

void lcd_set_pixel(unsigned char x, unsigned char y)

{

    unsigned char data;

    unsigned int address, shift;



    address = (y * LCD_GRAPHICS_AREA) + (x / 8) + LCD_GRAPHICS_HOME;



    if (y > 63 && LCD_NUMBER_OF_SCREENS == 2) /* If we are on the second screen and it exists */

    {

        y = y - 64;

        address = (y * LCD_GRAPHICS_AREA) + (x / 8) + LCD_GRAPHICS_HOME;

        address = address + 0x8000;

    }



    data = lcd_bit_to_byte(7 - (x % 8));



    lcd_write_data(address & 0xff);

    lcd_write_data(address >> 0x08);

    lcd_write_command(LCD_ADDRESS_POINTER_SET);



    /* Read existing display */

    lcd_write_command(LCD_DATA_READ_NO_INCREMENT);

    data = data | lcd_read_data();



    /* Write modified data */

    lcd_write_data(data);

    lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

}



/********************************************

 * Function name: lcd_clear_pixel           *

 * Description:   Clear a single Pixel      *

 *                0 <= X <= LCD Width       *

 *                0 <= Y <= LCD Height      *

 *******************************************/

void lcd_clear_pixel(unsigned char x, unsigned char y)

{

    unsigned char data;

    unsigned int address;



    address = (y * LCD_GRAPHICS_AREA) + (x / 8) + LCD_GRAPHICS_HOME;



    if (y > 63 && LCD_NUMBER_OF_SCREENS == 2) /* If we are on the second screen and it exists */

    {

        y = y - 64;

        address = (y * LCD_GRAPHICS_AREA) + (x / 8) + LCD_GRAPHICS_HOME;

        address = address + 0x8000;

    }



    data = lcd_bit_to_byte(7 - (x % 8));



    lcd_write_data(address & 0xff);

    lcd_write_data(address >> 0x08);

    lcd_write_command(LCD_ADDRESS_POINTER_SET);



    /* Read existing display */

    lcd_write_command(LCD_DATA_READ_NO_INCREMENT);

    data = (~data) & lcd_read_data();



    /* Write modified data */

    lcd_write_data(data);

    lcd_write_command(LCD_DATA_WRITE_AUTO_INCREMENT);

}



unsigned char lcd_bit_to_byte(unsigned char bit)

{

    switch (bit)

    {

        case 0:

            return 1;

            break;

        case 1:

            return 2;

            break;

        case 2:

            return 4;

            break;

        case 3:

            return 8;

            break;

        case 4:

            return 16;

            break;

        case 5:

            return 32;

            break;

        case 6:

            return 64;

            break;

        case 7:

            return 128;

            break;

        default:

            return 0;

            break;

    }

}






http://www.sourceboost.com/home.html

Copyright © 2002-2006 SourceBoost Technologies