/********************************************
* 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;
}
}
Copyright © 2002-2006 SourceBoost Technologies