Gus,
After some hundred lines of code the 240x64 based on t6963c, TEXT and GRAPHICS is working.
But the speed to refresh the screen is to slow. My project depend from this.
Each byte write needs the follow sequence:
private void WriteData(char data)
{
//AguardaStatus(3);
d[0] = (byte)data;
LCD_DataBus.Write(d, 0, 1);
LCD_CD.Write(LO);
LCD_RD.Write(HI);
LCD_WR.Write(LO);
LCD_EN.Write(LO);
LCD_EN.Write(HI);
}
The write and read signal from ParallelPort pulses to LOW when one write/read operation is realized. To my use i need that the read or write signal stay on low while the lcd enable signal (LCD_EN)is changed from low to hi.
Have a way to change this behavior ?
To work arround this detail, i create my own read and write pins. Buts this consumes more time per byte.
Some ideia to increase the data write speed ?
Here is the code writted to the t6963c 240x64 pixels:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
namespace SysSoft_Display
{
class LCD
{
// Constants
/* definição de Constantes */
private const byte BYTES_LINHA_GRAFICA = 40;
private const byte BYTES_LINHA_TEXTO = 40;
private const ushort INICIO_AREA_GRAFICA = 0x0000;
private const ushort INICIO_AREA_TEXTO = (8192 - ((128 / 8) * BYTES_LINHA_TEXTO));
private const byte SET_CURSOR_POINTER = 0x21;
private const byte SET_OFFSET_REGISTER = 0x22;
private const byte SET_ADDRESS_POINTER = 0x24;
private const byte SET_TEXT_HOME_ADDRESS = 0x40;
private const byte SET_TEXT_AREA = 0x41;
private const byte SET_GRAPHIC_HOME_ADDRESS = 0x42;
private const byte SET_GRAPHIC_AREA = 0x43;
private const byte SET_MODE = 0x80;
private const byte OR_MODE = 0x00;
private const byte EXOR_MODE = 0x01;
private const byte AND_MODE = 0x03;
private const byte ATTRIBUTE_MODE = 0x04;
private const byte INTERNAL_CG_ROM = 0x00;
private const byte EXTERNAL_CG_RAM = 0x80;
private const byte SET_DISPLAY_MODE = 0x90;
private const byte BLINK_ON = 0x01;
private const byte CURSOR_ON = 0x02;
private const byte TEXT_ON = 0x04;
private const byte GRAPHIC_ON = 0x08;
private const byte AUTO_WRITE_MODE = 0xB0;
private const byte AUTO_READ_MODE = 0xB1;
private const byte AUTO_DISABLE_MODE = 0xB2;
private const byte DATA_WRITE_INC = 0xC0;
private const byte DATA_READ_INC = 0xC1;
private const byte DATA_WRITE_DEC = 0xC2;
private const byte DATA_READ_DEC = 0xC3;
private const byte DATA_WRITE = 0xC4;
private const byte DATA_READ = 0xC5;
private const bool HI = true;
private const bool LO = false;
// Fields
private OutputPort LCD_EN;
private OutputPort LCD_RD;
private OutputPort LCD_WR;
private OutputPort LCD_CD;
private OutputPort LCD_RST;
private Cpu.Pin[] DataBus;
private ParallelPort LCD_DataBus;
private byte[] d;
private ushort[] LINHA_LCDG;
private byte[] TELA_ABERTURA;
// Methods
public void Init()
{
d = new byte[1];
LINHA_LCDG = new ushort[16] {
0x1D80, 0x1DA8, 0x1DD0, 0x1DF8,
0x1E20, 0X1E48, 0X1E70, 0x1E98,
0x1EC0, 0x1EE8, 0x1F10, 0x1F38,
0x1F60, 0x1F88, 0x1FB0, 0x1FD8 };
TELA_ABERTURA = new byte[5120] {
/*000*/ 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, 0x00,
/*124*/ 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, 0x00,
/*125*/ 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, 0x00,
/*126*/ 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, 0x00,
/*127*/ 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, 0x00 };
/* CG_ROM - OR entre TEXTO e GRÁFICO */
WriteComand(SET_MODE | OR_MODE | INTERNAL_CG_ROM);
/* Início da Área Gráfica */
WriteData((char)0x00); /* 0x0000 L */
WriteData((char)0x00); /* H */
WriteComand(SET_GRAPHIC_HOME_ADDRESS); /* 0x42 */
/* Número de bytes por linha gráfica */
WriteData((char)BYTES_LINHA_GRAFICA); /* 40 L*/
WriteData((char)0x00); /* H */
WriteComand(SET_GRAPHIC_AREA); /* 0x43 */
/* Início da Área Texto */
/* RAM - linhas linhas de texto */
/* 8192 - ( 128 / 8) * 40 */
/* 8192 - 640 = 7552 */
/* 0x1D80 */
WriteData((char)0x80);
WriteData((char)0x1D);
WriteComand(SET_TEXT_HOME_ADDRESS); /* 0x42 */
/* Número de bytes por linha texto */
WriteData((char)BYTES_LINHA_TEXTO); /* 40 L*/
WriteData((char)0x00); /* H */
WriteComand(SET_TEXT_AREA); /* 0x41 */
/* CG_ROM - OR entre TEXTO e GRÁFICO */
WriteComand(SET_MODE | EXOR_MODE | INTERNAL_CG_ROM); /* 0x80 */
/* Habilita Texto e Gráfico juntos */
WriteComand(SET_DISPLAY_MODE | TEXT_ON | GRAPHIC_ON); /* 0x9C */
}
// --------------------------------------------------------------------- //
public void BuildIO()
{
LCD_EN = new OutputPort((Cpu.Pin)USBizi.Pin.IO69, true);
LCD_RD = new OutputPort((Cpu.Pin)USBizi.Pin.IO68, true);
LCD_WR = new OutputPort((Cpu.Pin)USBizi.Pin.IO67, true);
LCD_CD = new OutputPort((Cpu.Pin)USBizi.Pin.IO66, true);
LCD_RST = new OutputPort((Cpu.Pin)USBizi.Pin.IO7, false);
DataBus = new Cpu.Pin[8] {
(Cpu.Pin)USBizi.Pin.IO51,
(Cpu.Pin)USBizi.Pin.IO52,
(Cpu.Pin)USBizi.Pin.IO53,
(Cpu.Pin)USBizi.Pin.IO54,
(Cpu.Pin)USBizi.Pin.IO55,
(Cpu.Pin)USBizi.Pin.IO56,
(Cpu.Pin)USBizi.Pin.IO57,
(Cpu.Pin)USBizi.Pin.IO58,
};
LCD_DataBus = new ParallelPort(DataBus, (Cpu.Pin)USBizi.Pin.IO9, (Cpu.Pin)USBizi.Pin.IO60);
}
// --------------------------------------------------------------------- //
public void Reset()
{
LCD_RST.Write(LO);
Delay();
LCD_RST.Write(HI);
Delay();
Delay();
Delay();
}
// --------------------------------------------------------------------- //
private void Delay()
{
byte x;
for (x = 0; x < 2; x++) ;
}
// --------------------------------------------------------------------- //
private void AguardaStatus(byte status)
{
byte result = 0;
/* */
do
{
LCD_CD.Write(HI);
LCD_RD.Write(LO);
LCD_WR.Write(HI);
LCD_EN.Write(LO);
LCD_DataBus.Read(d, 0, 1);
LCD_EN.Write(HI);
if ((d[0] & status) == status)
result = 1;
else
result = 0;
} while (result == 0);
}
// --------------------------------------------------------------------- //
private void WriteData(char data)
{
//AguardaStatus(3);
d[0] = (byte)data;
LCD_DataBus.Write(d, 0, 1);
LCD_CD.Write(LO);
LCD_RD.Write(HI);
LCD_WR.Write(LO);
LCD_EN.Write(LO);
LCD_EN.Write(HI);
}
// --------------------------------------------------------------------- //
private void WriteComand(byte command)
{
//AguardaStatus(3);
d[0] = command;
LCD_DataBus.Write(d, 0, 1);
LCD_CD.Write(HI);
LCD_RD.Write(HI);
LCD_WR.Write(LO);
LCD_EN.Write(LO);
LCD_EN.Write(HI);
}
// --------------------------------------------------------------------- //
private void Address_Pointer(ushort end)
{
AguardaStatus(3);
WriteData((char)(end & 0x00FF));
WriteData((char)(end >> 8));
WriteComand(SET_ADDRESS_POINTER);
}
// --------------------------------------------------------------------- //
private void WriteAutoD(char value)
{
AguardaStatus(3);
WriteData(value);
}
// --------------------------------------------------------------------- //
public void ClearGrafico()
{
ushort x;
/* */
Address_Pointer(INICIO_AREA_GRAFICA);
WriteComand(AUTO_WRITE_MODE);
for (x = 0; x < 2560 /*5120*/; x++)
WriteAutoD((char)0x00);
WriteComand(AUTO_DISABLE_MODE);
}
// --------------------------------------------------------------------- //
public void ClearTexto()
{
ushort x;
/* */
Address_Pointer(INICIO_AREA_TEXTO);
WriteComand(AUTO_WRITE_MODE);
for (x = 0; x < 320 /*640*/; x++)
WriteAutoD((char)0x00);
WriteComand(AUTO_DISABLE_MODE);
}
// --------------------------------------------------------------------- //
public void SetRowCol(byte row, byte col)
{
Address_Pointer((ushort)(LINHA_LCDG[row] + col));
}
// --------------------------------------------------------------------- //
public void PutChar(char c)
{
c -= (char)0x20;
WriteData(c);
WriteComand(DATA_WRITE_INC);
}
// --------------------------------------------------------------------- //
public void PutString(string s)
{
int i;
/* */
for (i = 0; i < s.Length; i++)
PutChar(s.ToCharArray(i, 1)[0]);
}
// --------------------------------------------------------------------- //
public void DrawBitmap()
{
int j;
/* */
Address_Pointer(0x0000);
WriteComand(AUTO_WRITE_MODE);
for (j=0; j<2560; j++)
WriteAutoD((char)TELA_ABERTURA[j]);
WriteComand(AUTO_DISABLE_MODE);
}
// --------------------------------------------------------------------- //
}
}
#define DEPURACAO
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
using SysSoft_Display;
namespace MFConsoleApplication1
{
public class Program
{
static LCD display;
static ushort x = 0;
public static void Main()
{
display = new LCD();
/* */
#if DEPURACAO
Debug.Print("OI");
#endif
display.BuildIO();
display.Reset();
display.Init();
display.ClearGrafico();
display.ClearTexto();
display.DrawBitmap();
display.ClearGrafico();
display.ClearTexto();
display.SetRowCol(4, 20);
display.PutChar((char)'A');
display.SetRowCol(0, 0);
display.PutString("Orbisonic");
while (true)
{
#if DEPURACAO
Debug.Print(x.ToString());
x++;
#endif
}
}
}
}