GLCD s1d13700 test code

Discuss the Integrated Development Environment (IDE)

Moderators: David Barker, Jerry Messina

lothar
Posts: 14
Joined: Wed Apr 25, 2007 4:10 pm
Location: Hull

GLCD s1d13700 test code

Post by lothar » Wed Apr 25, 2007 4:19 pm

Hello,

I am new to this IDE and would appreciate some help to get my GLCD working, at present I have a circuit connected but cannot get anything onto the screen. If possible could someone post a code snippet to prove my circuit. If someone has a circuit for the glcd than that would be fantastic to cross ref. I realise i am asking alot for a newbee but if you dont ask you dont get :D

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Wed Apr 25, 2007 7:55 pm

I know steve did extensive work on S1D13700 support. I belive he tested on a Crystalfontz display and one from RS, although I don't know the model. Perhaps you could give a little more information about the display. For example, make, model, mode (6800 or 8080). How have you connected the device?

lothar
Posts: 14
Joined: Wed Apr 25, 2007 4:10 pm
Location: Hull

Post by lothar » Wed Apr 25, 2007 9:32 pm

Hi David,

I have a Displaytech S240320H 3.9"QVGA Graphic LCD 320x240 resolution. I have the unit connected to an 18F452 as per the connections in the S1D13700 module. In terms of the mode the datasheet is very loose on information and so I do not know the mode of operation.

Again any help would be very appreciated as I have not dabled with graphical LCD's before.

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Wed Apr 25, 2007 10:18 pm

If this is the correct datasheet

http://www.displaytech-us.com/pdf/newpd ... es-v10.pdf

then it looks like in runs in 8080 mode. I am unable to test here, but I think the following should work

Code: Select all

device = 18F452 // choose your device
clock = 20      // choose your clock

// configure GLCD...
#option GLCD_MODEL = S1D13700    // set model
#option GLCD_A0 = PORTB.2        // A0 pin
#option GLCD_WR = PORTB.1        // WR pin
#option GLCD_RD = PORTB.0        // RD pin 
#option GLCD_DATA = PORTD        // data port
#option GLCD_CS = PORTB.3        // chip select
#option GLCD_RES = PORTB.5       // reset pin

// import modules...
include "glcd.bas"
include "arial.bas"
include "graphics.bas"

// clear screen and set font - driver defaults 
// to layer 1 at startup - according to S1D13700 help
// file, bsClear provides fastest font rendering...
Cls(1)
SetFont(Arial)
Brush.Style = bsClear

// display some text...
WriteAt(50,50,"Hello World")
Just make sure you physical pin connections match the #options. If you have connected things differently, then just change the #option to match.

I sure Steven will be able to shed more light on this topic when he gets time...

User avatar
Steven
BETA Tester
Posts: 406
Joined: Tue Oct 03, 2006 8:32 pm
Location: Cumbria, UK

Post by Steven » Wed Apr 25, 2007 11:55 pm

I have the same display I think, from RS, but since I have not done the PCB for connecting it up, have not fired this one up yet. Dave's test code should work fine. Let me know if it doesn't give anything or if it gives odd results and I'll do what I can to help.

Regards,

Steven

lothar
Posts: 14
Joined: Wed Apr 25, 2007 4:10 pm
Location: Hull

Post by lothar » Thu Apr 26, 2007 2:03 pm

Thanks Guys,

I have tried the code and connected it as per the code. I do not ave anything on the screen. Maybe I am missing something with the screen itself? Maybe it is running in another operational mode. Circuit wise I have it connected to a PIC18F452 with a 4MHz resonator.

Any thoughts welcome.

Thanks again

Lothar

Francis
Registered User
Registered User
Posts: 314
Joined: Sun Mar 25, 2007 9:40 am
Location: Devon

Post by Francis » Thu Apr 26, 2007 5:46 pm

I'm not over-impressed with Data Sheet and I've never used one of those GLCDs, but have you got the contrast control connected properly?

(I can't see from Data Sheet how you would connect it assuming one is required of course)

lothar
Posts: 14
Joined: Wed Apr 25, 2007 4:10 pm
Location: Hull

Post by lothar » Thu Apr 26, 2007 8:40 pm

the datasheet is very poor. for the contrast I have used jumper 3 shorted to enable the internal bridge for Vee and Vout. It measures approx 16Vdc which I am not convinced by. Everything else seems fine so I guess it is one of those niggling annoying faults.

On thing that was shown in a ciruit I found was the connections to the LCD were via pull up resistors. I do not have these resistors and wondered if they were required for the code snippet to work?

Again thanks for the support.

MattH
Registered User
Registered User
Posts: 51
Joined: Mon Jan 01, 2007 8:03 pm
Location: Allentown, PA

Post by MattH » Thu Apr 26, 2007 10:37 pm

I don't think jumpering VEE with Vo is a good idea.
I would try something like this:

+5V
____
|
\
/ <----10k--- Vo
\
|
___
Vee

lothar
Posts: 14
Joined: Wed Apr 25, 2007 4:10 pm
Location: Hull

Post by lothar » Fri Apr 27, 2007 8:44 am

Hi Matt,

I desoldered the jumper link and added a POT to control the contrast. Still no joy though.

regards

Lothar

Francis
Registered User
Registered User
Posts: 314
Joined: Sun Mar 25, 2007 9:40 am
Location: Devon

Post by Francis » Fri Apr 27, 2007 9:24 am

Are you getting ANY visible effects with your contrast contol pot?
You should see at least a slight darkening of screen at one extreme of pot.
If not there is something wrong I would hve thought?

I'm only mentioning the Contrast setting as I spent hours with a Proton programme a year ago. It didn't appear to work until Les pointed out I'd messed up my contrast ... and bingo.

On a Winstar GLCD 240x128 which requires typically about 18V for the LCD driver, the Vee pin gives about -15V to -16V (wrt Vss/Ground).
Where Vlcd is 23V max (Vdd-Vo).
And you've wired it as Matth showed with the pot. wiper to Vo? And you've used a 10K to 20K pot?

Personally, as I really am unimpressed with the Data Sheet, I'd drop Displaytech an email asking A) what voltage should Vee be? and, B) Precisely how to connect contrast and what value potentiometer.

MattH
Registered User
Registered User
Posts: 51
Joined: Mon Jan 01, 2007 8:03 pm
Location: Allentown, PA

Post by MattH » Fri Apr 27, 2007 11:09 am

The datasheet says to set the display for mode:68000.
Add this line

Code: Select all

#option GLCD_MODE = 6800         // GLCD interface mode - 6800 or 8080
to your code and see if it works. Also as Francis mentioned, turning the pot
from one extreme to the other should change the contrast from black to nothing.
If that doesn't work I would suggest to return the display.

User avatar
Steven
BETA Tester
Posts: 406
Joined: Tue Oct 03, 2006 8:32 pm
Location: Cumbria, UK

Post by Steven » Fri May 11, 2007 11:09 pm

I have just connected up my display from RS and have it working. I have a 1k pot connected between Vout and 0V, with the wiper connected to VEE. I'd use a higher value (e.g. 10k) if I had one, but the 1k is OK at the moment. The display does flicker a lot and the maximum available contrast is not brilliant, so I'm not convinced I have it completely correct, but it does display an image correctly. When I get it working a little better I'll post a photo of it.

Have you had any more success, or did you abandon it in the end?

Regards,

Steve

User avatar
Steven
BETA Tester
Posts: 406
Joined: Tue Oct 03, 2006 8:32 pm
Location: Cumbria, UK

Post by Steven » Sat May 12, 2007 7:51 am

OK, more progress now. I changed the pot to a 100k one (probably too big, but works OK). The display still flickered quite badly, so I've adjusted the value of the TC/R line in the 'system set' section of the Initialize command for the S1D13700 library. You should be able to calculate the correct value for this, but it's a complex calculation so I did it by trial and error! I've now added a #option to the library to make altering this for different displays easier. The value I used in the end was $2B. I'm still a little disappointed in the contrast of the display, but maybe I can still get more out of it.
Below is a photo of the display.

Image

Regards,

Steven

User avatar
Steven
BETA Tester
Posts: 406
Joined: Tue Oct 03, 2006 8:32 pm
Location: Cumbria, UK

Post by Steven » Sat May 12, 2007 8:05 am

I've checked Dave's code above. My display is set for 6800 mode, hence I've altered the code given by Dave to the following:

Code: Select all

Device = 18F4620 // choose your device 
Clock = 20       // choose your clock 

// configure GLCD... 
#option GLCD_MODEL = S1D13700    // set model 
#option GLCD_MODE = 6800
#option GLCD_TCR = $2B
#option GLCD_A0 = PORTB.2        // A0 pin 
#option GLCD_RW = PORTB.1        // WR pin 
#option GLCD_EN = PORTB.0        // RD pin 
#option GLCD_DATA = PORTD        // data port 
#option GLCD_CS = PORTB.3        // chip select 
#option GLCD_RES = PORTB.5       // reset pin 

// import modules... 
Include "glcd.bas" 
Include "arial.bas" 
Include "graphics.bas" 

// clear screen and set font - driver defaults 
// to layer 1 at startup - according to S1D13700 help 
// file, bsClear provides fastest font rendering... 
Cls(1) 
SetFont(Arial) 
Brush.Style = bsClear 

// display some text... 
WriteAt(50,50,"Hello World")
This works fine.

You will also need to replace the S1D13700 library code with the following (make a backup of the old library file first..!):

Code: Select all

{
********************************************************************************
*  Name    : S1D13700.BAS                                                      *
*  Author  : S Wright                                                          *
*  Notice  : Copyright (c) 2007 J Smith, S Wright                              *
*          : All Rights Reserved                                               *
*  Date    : 27/01/2007                                                        *
*  Version : 1.0                                                               *
*  Notes   : Library for a 320 x 240 graphic LCD with S1D13700 controller      *
*          : working in 6800 or 8080 mode                                      *
********************************************************************************
}
Module S1D13700

// import the graphics module...
#define GLCD_PIXEL_08
#define GLCD_COLOR_01
#define GLCD_XY_16
Include "Graphics.bas"   
Include "System.bas"   
Include "Utils.bas"

// default module options - user options can override these values...
#option GLCD_MODE = 8080         // GLCD interface mode - 6800 or 8080
#option GLCD_DATA = PORTD        // data port
#option GLCD_EN = PORTB.0        // EN pin - 6800 mode
#option GLCD_RD = PORTB.0        // RD pin - 8080 mode
#option GLCD_RW = PORTB.1        // RW pin - 6800 mode
#option GLCD_WR = PORTB.1        // WR pin - 8080 mode
#option GLCD_A0 = PORTB.2        // A0 pin
#option GLCD_CS = PORTB.3        // chip select
#option GLCD_RES = PORTB.5       // reset pin
#option GLCD_TCR = $42           // TC/R setting for display 'system set' instruction
#option GLCD_ASPECT_RATIO = 100  // aspect ratio, smaller number will squeeze y for GLCD circles and box
#option GLCD_INIT_DELAY = 100    // initialisation delay (ms)

#if Not (GLCD_MODE in (6800, 8080))
   #error GLCD_MODE, "Invalid option. GLCD mode not recognized."
#endif

// validate data port...
#if IsOption(GLCD_DATA) 
   #if Not IsValidPort(GLCD_DATA)
      #error GLCD_DATA, "Invalid option. DATA must be a valid port name."
   #endif
   #ifdef GLCD_DATA@ Then
      #error GLCD_DATA@, "Invalid option. DATA port cannot be a single bit value."
   #endif
#endif

// validate EN pin...
#if IsOption(GLCD_EN) And Not IsValidPortPin(GLCD_EN) 
   #error GLCD_EN, "Invalid option. EN must be a valid port pin."
#endif

// validate RD pin...
#if IsOption(GLCD_RD) And Not IsValidPortPin(GLCD_RD) 
   #error GLCD_RD, "Invalid option. RD must be a valid port pin."
#endif

// validate RW pin...
#if IsOption(GLCD_RW) And Not IsValidPortPin(GLCD_RW) 
   #error GLCD_RW, "Invalid option. RW must be a valid port pin."
#endif

// validate WR pin...
#if IsOption(GLCD_WR) And Not IsValidPortPin(GLCD_WR) 
   #error GLCD_WR, "Invalid option. WR must be a valid port pin."
#endif

// validate A0 pin...
#if IsOption(GLCD_A0) And Not IsValidPortPin(GLCD_A0) 
   #error GLCD_A0, "Invalid option. A0 must be a valid port pin."
#endif

// validate CS pin...
#if IsOption(GLCD_CS) And Not IsValidPortPin(GLCD_CS) 
   #error GLCD_CS, "Invalid option. CS must be a valid port pin."
#endif

// validate RES pin...
#if IsOption(GLCD_RES) And Not IsValidPortPin(GLCD_RES) 
   #error GLCD_RES, "Invalid option. RES must be a valid port pin."
#endif

// validate TCR setting...
#if IsOption(GLCD_TCR)
   #if Not (GLCD_TCR in ($00 to $FF))
      #error GLCD_TCR, "Invalid option. TC/R must be between $00 and $FF."
   #endif
#endif 

// validate initialisation delay...
#if IsOption(GLCD_INIT_DELAY)
   #if Not (GLCD_INIT_DELAY in (0 to 1000))
      #error GLCD_INIT_DELAY, "Invalid option. GLCD initialize delay must be between 0 and 1000 (ms)."
   #endif
#endif 

// now create Data TRIS...
#option _GLCD_DATA_TRIS = GetTRIS(GLCD_DATA)

// GLCD width and height...
Public Const
   GLCDWidth = 320,
   GLCDHeight = 240

// x, y position structure...   
Public Structure TPositionS1D13700
   x As TXY
   y As Byte
End Structure
   
// x, y position...
Public Dim
   Pos As TPositionS1D13700

// S1D13700 commands...   
Const
   cmdSystem = $40,          // general system settings
   cmdSleep = $53,           // enter into standy mode
   cmdDisplayOff = $58,      // turn the display off
   cmdDisplayOn = $59,       // turn the display on
   cmdScroll = $44,          // setup text and graphics address regions
   cmdCsrForm = $5D,         // set cursor size
   cmdCsrDirRight = $4C,     // cursor moves right after write to display memory
   cmdCsrDirLeft = $4D,      // cursor moves left after write to display memory
   cmdCsrDirUp = $4E,        // cursor moves up after write to display memory
   cmdCsrDirDown = $4F,      // cursor moves down after write to display memory
   cmdCGRAMAddress = $5C,    // configure character generator RAM address
   cmdHDotScroll = $5A,      // set horizontal scroll rate
   cmdOverlay = $5B,         // configure how layers overlay
   cmdSetCsrAddress = $46,   // set the cursor address
   cmdGetCsrAddress = $47,   // read the cursor address
   cmdDisplayWrite = $42,    // write to display memory
   cmdDisplayRead = $43,     // read from display memory
   GLCDTCR = GLCD_TCR,     
   GLCDDelay = GLCD_INIT_DELAY     

// port and pin settings, these are brought into
// the program by using the above options...
Dim        
   Data As GLCD_DATA,           // data in (PORT) 
   TRISData As _GLCD_DATA_TRIS, // data TRIS
   EN As GLCD_EN.GLCD_EN@,      // EN pin - enable (serves as a strobe) - 6800 mode
   RD As GLCD_RD.GLCD_RD@,      // RD pin - read when L - 8080 mode
   RW As GLCD_RW.GLCD_RW@,      // RW pin - read or write (0 = write, 1 = read) - 6800 mode
   WR As GLCD_WR.GLCD_WR@,      // WR pin - write when L - 8080 mode
   A0 As GLCD_A0.GLCD_A0@,      // A0 pin - sets data destination: 1 = command, 0 = data
   CS As GLCD_CS.GLCD_CS@,      // chip select - 0 = selected, 1 = disabled
   RES As GLCD_RES.GLCD_RES@    // RES pin - normally RES = 1 but pull to 0 for initialization

Dim
   Layers As Byte,              // layers 1 - 3 on/off
   Layer1 As Layers.Booleans(2),
   Layer2 As Layers.Booleans(4),
   Layer3 As Layers.Booleans(6),
   CurrentLayer As Byte,        // current drawing layer
   CurrentLayerMemPos As Word
{
********************************************************************************
* Name    : SetData (PRIVATE)                                                  *
* Purpose : Write a data byte to GLCD                                          *
********************************************************************************
}     
Sub SetData(pData As Byte)                
#if GLCD_MODE = 6800
   A0 = 0               // access display RAM data
   RW = 0               // write mode
   TRISData = $00       // set data bus to output
   Data = pData         // write to the bus
   CS = 0
   EN = 1               // write to GLCD
   DelayUS(1)
   EN = 0
   CS = 1
   DelayUS(1)           // prevent further write/read immediately
#elseif GLCD_MODE = 8080                   
   A0 = 0               // setup for data write
   RD = 1               // RD high for writing
   TRISData = $00       // set data bus to output
   Data = pData         // write to the bus
   CS = 0
   WR = 0               // write low starts write sequence
   DelayUS(1)           // keep WR low to allow command to register
   WR = 1               // de-assert write
   CS = 1
   DelayUS(1)           // prevent further write/read immediately
#endif
End Sub
{
********************************************************************************
* Name    : GetData (PRIVATE)                                                  *
* Purpose : Read byte from GLCD                                                *
********************************************************************************
}     
Function GetData() As Byte
#if GLCD_MODE = 6800
   A0 = 1               // access display RAM data
   RW = 1               // read mode
   TRISData = $FF       // set data bus to input
   CS = 0
   EN = 1               // read from GLCD
   DelayUS(2)
   Result = Data        // read from the bus
   EN = 0
   CS = 1
   DelayUS(1)           // prevent further write/read immediately
#elseif GLCD_MODE = 8080                  
   A0 = 1               // setup for data read
   WR = 1               // WR high for reading
   TRISData = $FF       // set data bus to input
   CS = 0
   RD = 0               // read low starts read sequence
   DelayUS(2)           // keep RD low to allow data to be read
   Result = Data        // read from the bus
   RD = 1               // de-assert read
   CS = 1
   DelayUS(1)           // prevent further write/read immediately
#endif
End Function  
{
********************************************************************************
* Name    : Command (PRIVATE)                                                  *
* Purpose : Write a command byte to GLCD                                       *
********************************************************************************
}     
Sub Command(pCommand As Byte)                 
#if GLCD_MODE = 6800
   A0 = 1               // instruction mode
   RW = 0               // write mode
   TRISData = $00       // set data bus to output
   Data = pCommand      // write to the bus
   CS = 0
   EN = 1               // write to GLCD
   DelayUS(1)
   EN = 0
   CS = 1
   DelayUS(1)           // prevent further write/read immediately
#elseif GLCD_MODE = 8080                        
   A0 = 1               // setup for command
   RD = 1               // RD high for writing
   TRISData = $00       // set data bus to output
   Data = pCommand      // write to the bus
   CS = 0
   WR = 0               // write low starts write sequence
   DelayUS(1)           // keep WR low to allow command to register
   WR = 1               // de-assert write
   CS = 1
   DelayUS(1)           // prevent further write/read immediately
#endif
End Sub
{
********************************************************************************
* Name    : CsrMemPosition                                                     *
* Purpose : Positions cursor in graphics memory                                *
********************************************************************************
} 
Sub CsrMemPosition(pMemStart As Word)
   Command(cmdSetCsrAddress)  // command - next two bytes are low & high bytes of memory start
   SetData(pMemStart.Byte0)   // low byte
   SetData(pMemStart.Byte1)   // high byte
End Sub
{
********************************************************************************
* Name    : SetPosition (PRIVATE)                                              *
* Purpose : Set GLCD x and y positions                                         *
********************************************************************************
}     
Sub SetPosition()
   Dim MemPos As Word
   MemPos = CurrentLayerMemPos + Pos.x + (40 * Pos.y)   // find position in graphics memory (40 bytes across 320 pixel screen)
   CsrMemPosition(MemPos)
End Sub
{
********************************************************************************
* Name    : WriteByte                                                          *
* Purpose : Write a byte                                                       *
********************************************************************************
} 
Public Sub WriteByte(pValue As Byte)              
   SetPosition
   Command(cmdDisplayWrite)
   SetData(pValue)
End Sub 
{
********************************************************************************
* Name    : ReadByte                                                           *
* Purpose : Read a byte                                                        *
********************************************************************************
} 
Public Function ReadByte() As Byte                
   SetPosition
   Command(cmdDisplayRead)
   ReadByte = GetData  
End Function
{
********************************************************************************
* Name    : SetPixel                                                           *
* Purpose : Set pixel at pixel location x,y                                    *
********************************************************************************
} 
Public Sub SetPixel(pX, pY As TXY)          
   Dim XBit As Byte
   Dim Pixel As Byte
   Dim LastPosX As TXY
   
   If (pX < GLCDWidth) And (pY < GLCDHeight) Then

      LastPosX = Pos.x
      XBit = %10000000 >> (pX Mod 8)
      Pos.y = pY
      Pos.x = pX / 8
   
      SetPosition
      Command(cmdDisplayRead)
      Pixel = GetData  

           
      // pen is white...
      If Pen.Color = 0 Then
         If Pen.Mode = pmCopy Then
            XBit = Not XBit
            Pixel = Pixel And XBit
         EndIf
   
      // pen is black...
      Else

         // pen copy or merge...
         If Pen.Mode <> pmXOR Then
            Pixel = Pixel Or XBit
         // pen XOR
         Else
            If (Pixel And XBit) = 0 Then
               Pixel = Pixel Or XBit
            Else
               XBit = Not XBit
               Pixel = Pixel And XBit
            EndIf      
         EndIf
      EndIf

      SetPosition
      Command(cmdDisplayWrite)
      SetData(Pixel)
      
      Pos.x = LastPosX
   EndIf
End Sub
{
********************************************************************************
* Name    : GetPixel                                                           *
* Purpose : Return pixel colour at pixel position x, y                         *
********************************************************************************
}
Public Function GetPixel(pX, pY As TXY) As TColor             
   Dim Pixel As Byte
   Pos.y = pY
   Pos.x = pX / 8
   SetPosition
   Command(cmdDisplayRead)
   Pixel = GetData << (pX Mod 8) 
   Result = Pixel.7  
End Function
{
********************************************************************************
* Name    : Cls                                                                *
* Purpose : Clear one of the three graphic screens                             *
********************************************************************************
} 
Public Sub Cls(pLayer As Byte)                       
   Dim MemStart, MemPos As Word
   MemStart = (pLayer - 1) * 9600
   CsrMemPosition(MemStart)   // move to start of graphic memory for layer
   Command(cmdDisplayWrite)   // set to write to display memory
   MemPos = 0
   Repeat
      SetData($00)           
      Inc(MemPos)
   Until MemPos = 9600
   CsrMemPosition(MemStart)   // move to start of graphic memory for layer
   Command(cmdDisplayOn)      // command for screen on to remove cursor
   SetData(Layers)            // sets layers 1 - 3, cursor off
End Sub  
{
********************************************************************************
* Name    : ApplyLine (PRIVATE)                                                *
* Purpose : Applies mask to line                                               *
********************************************************************************
} 
Private Function ApplyLine(pLine, pMask As Byte) As Byte
   If Brush.Color = 0 Then   // brush is white...
      ApplyLine = pLine And (Not pMask)
   Else                      // brush is black...
      ApplyLine = pLine Or pMask
   EndIf
End Function
{
********************************************************************************
* Name    : Fill                                                               *
* Purpose : Fast fill screen area with brush color.                            *
*         : Assumes pX1 < pX2 and pY1 < pY2                                    *
********************************************************************************
} 
Public Sub Fill(pX1, pY1, pX2, pY2 As TXY)
   Dim LastPosX As Word
   Dim MaskL, MaskR As Byte
   Dim Line As Byte
   LastPosX = Pos.x
   MaskL = $FF >> (pX1 Mod 8)
   MaskR = $FF << (7 - pX2 Mod 8)
   Pos.y = pY1
   Repeat
      Pos.x = pX1 / 8
      Line = ReadByte()
      If pX2 / 8 = pX1 / 8 Then       // start & end of rectangle in same byte
         WriteByte(ApplyLine(Line, MaskL And MaskR))
      Else
         WriteByte(ApplyLine(Line, MaskL))     
         Inc(Pos.x)
         SetPosition()
         Command(cmdDisplayWrite)     // set to write to display memory
         While Pos.x < pX2 / 8
            If Brush.Color = 0 Then   // brush is white...
               SetData($00)
            Else                      // brush is black...
               SetData($FF)
            EndIf
            Inc(Pos.x)
         Wend
         Line = ReadByte()            // right side of rectangle
         WriteByte(ApplyLine(Line,MaskR))
      EndIf
      Inc(Pos.y)
   Until Pos.y > pY2
End Sub
{
********************************************************************************
* Name    : WriteImageByte (PRIVATE)                                           *
* Purpose : Write an image byte to GLCD at pixel position x, y                 *
********************************************************************************
} 
#define GLCD_SETIMAGE
Sub WriteImageByte(pX As Word, pY As Byte, pValue As Byte)
   Dim Line, ShiftValue, XBit, XBitReverse As Byte
   Dim LastPosX As Word
 
   LastPosX = Pos.x           // save x position
   XBit = pX Mod 8            // offset
   XBitReverse = 8 - XBit     // reverse offset
   Pos.x = pX / 8             // align to page
   Pos.y = pY                 // save y

   // get first byte...
   Line = ReadByte   

   // mask, if needed...
   If Pen.Mode = pmCopy Then
      Line = Line >> XBitReverse
      Line = Line << XBitReverse
   EndIf
   
   // merge then write data...   
   ShiftValue = pValue >> XBit
   If Pen.Mode = pmXOR Then
      Line = Line Xor ShiftValue
   Else
      Line = Line Or ShiftValue
   EndIf
   WriteByte(Line)
    
   // get next byte...
   If XBit <> 0 Then
      Inc(Pos.x)
      Line = ReadByte
  
      // mask, if needed...
      If Pen.Mode = pmCopy Then
         Line = Line << XBit
         Line = Line >> XBit
      EndIf
   
      // merge then write data...
      ShiftValue = pValue << XBitReverse
      If Pen.Mode = pmXOR Then
         Line = Line Xor ShiftValue
      Else
         Line = Line Or ShiftValue
      EndIf   
      WriteByte(Line) 
   EndIf
   
   // restore x position...
   Pos.x = LastPosX  
End Sub 
{
********************************************************************************
* Name    : ReadImageByte (PRIVATE)                                            *
* Purpose : Read an image byte                                                 *
********************************************************************************
} 
Function ReadImageByte() As Byte
   ASM-
      TBLRD *+
      movff TABLAT, result
   End ASM
End Function
{
********************************************************************************
* Name    : SetImage                                                           *
* Purpose : BitBlit image to GLCD at pixel location x, y.                      *
*         : NOTE - This subroutine only supports $01 (monochrome) bitmaps.     *
*         : It requires images drawn with bytes in the x-direction.            *
********************************************************************************
} 
Public Sub SetImage(pX, pY As TXY, pImageAdr As Word, pMode As Byte = cmCopy)
   Dim Image As TImage
   Dim x,Width As Word
   Dim y,Height As Byte
   Dim Line As Byte
   Dim LastPen As TPen

   // get bitmap ID, width and height...
   TABLEPTR = pImageAdr
   Image.Header = ReadImageByte
   Image.Width = ReadImageByte
   Image.Height = ReadImageByte
   Inc(TABLEPTR)
   
   LastPen = Pen
   Pen.Mode = pMode
    
   // byte aligned bit blit... 
   x = pX
   Width = Image.Width / 8
   While Width > 0
      y = pY
      Height = Image.Height 
      While Height > 0
         WriteImageByte(x,y,ReadImageByte)
         Inc(y)
         Dec(Height)
      Wend
      Inc(x, 8)
      Dec(Width)
   Wend 
         
   // non byte aligned bit blit...
   pX = x
   Image.Width = Image.Width Mod 8   
   If Image.Width > 0 Then
      y = pY
      Height = Image.Height
      While Height > 0     
         Line = ReadImageByte
         Width = Image.Width
         x = pX
         While Width > 0
            Pen.Color = Line.7
            SetPixel(x,y)
            Line = Line << 1
            Dec(Width)
            Inc(x)
         Wend
         Dec(Height)
         Inc(y)
      Wend
   EndIf   
   Pen = LastPen   
End Sub
{
********************************************************************************
* Name    : SetImage                                                           *
* Purpose : BitBlit image To GLCD at pixel location x, y.                      *
*         : NOTE - This subroutine only supports $01 (monochrome) bitmaps.     *
*         : It requires images drawn with bytes in the x-direction.            *
********************************************************************************
} 
Public Sub SetImage(pX, pY As TXY, ByRefConst pImage() As Byte, pMode As Byte = cmCopy)
   SetImage(pX, pY, @pImage, pMode)
End Sub 
{
********************************************************************************
* Name    : ShowLayer (Public)                                                 *
* Purpose : Turns on/off graphic layers                                        *
********************************************************************************
} 
Public Sub ShowLayer(pLayer As Byte, pOn As Boolean)              
   Layers.Bits(2 * pLayer) = Bit(pOn)
   Command(cmdDisplayOn)      // command for screen on
   SetData(Layers)            // sets layers 1 - 3, cursor off
End Sub
{
********************************************************************************
* Name    : SwitchLayer (Public)                                               *
* Purpose : Switches current drawing layer                                     *
********************************************************************************
} 
Public Sub SwitchLayer(pLayer As Byte)              
   CurrentLayer = pLayer
   CurrentLayerMemPos = 9600 * (CurrentLayer - 1)
End Sub
{
********************************************************************************
* Name    : Initialize                                                         *
* Purpose : Configure the GLCD before use.                                     *
*         : Set up ports for I/O and perform RESET on LCD                      *
********************************************************************************
} 
Sub Initialize()                    
Dim i As Word
   SetAllDigital()
   Pos.x = 0
   Pos.y = 0  
#if GLCD_MODE = 6800
   Output(EN)                 // enable
   Output(RW)                 // read/write
#elseif GLCD_MODE = 8080
   Output(RD)                 // read
   Output(WR)                 // write
#endif
   Output(A0)                 // data or instruction
   Output(CS)                 // chip select
   Output(RES)                // reset
#if GLCD_MODE = 6800
   DelayMS(GLCDDelay)         // start up delay, allow GLCD to settle
   RES = 0                    // RES = 0 to reset
   EN = 0                     // start with EN = 0
   A0 = 0
   Data = 0
   CS = 0
   DelayMS(5)
   RES = 1
   DelayMS(10)                // time for reset to finish
#elseif GLCD_MODE = 8080
   RES = 1
   RD = 1                     
   WR = 1
   A0 = 0
   CS = 1
   DelayMS(GLCDDelay)         // start up delay, allow GLCD to settle
   RES = 0                    // RST = 0 to reset 
   DelayMS(5)                 // 1 ms minimum, 5ms for safety
   RES = 1
   DelayMS(5)                 // 3 ms minimum, 5ms for safety
   CS = 1
#endif
   Command(cmdSystem)         // execute 'system set' instruction
   DelayMS(1)
   SetData($30)               // control byte sets internal char gen (see DS) 
   SetData($87)               // FX - horizontal char size - 1 (see DS)
   SetData($07)               // FY - vertical char size - 1
   SetData($27)               // C/R - bytes per line horizintally - 1
   SetData(GLCDTCR)           // TC/R - provides overscan idle time (see DS)
   SetData($EF)               // LF - height of frame in lines - 1 ($EF = 239)
   SetData($28)               // AP[L] - low byte of AP (horizontal address of virtual screen)
   SetData($00)               // AP[H] - high byte of AP (horizontal address of virtual screen)
   Command(cmdScroll)         // sets scroll address and lines per scroll block
   SetData($00)               // graphics layer 1 start[L] ($0000)
   SetData($00)               // graphics layer 1 start[H] 
   SetData($EF)               // graphics layer 1 lines per block - 1 ($EF = 239)
   SetData($80)               // graphics layer 2 start[L] ($2580 = 9600 = 320 x 240 / 8)
   SetData($25)               // graphics layer 2 start[H]
   SetData($EF)               // graphics layer 2 lines per block - 1 ($EF = 239)
   SetData($00)               // graphics layer 3 start[L] ($4B00 = 19200 = 9600 + 320 x 240 / 8)
   SetData($4B)               // graphics layer 3 start[H]
   SetData($00)               // no graphics layer 4
   SetData($00)
   Command(cmdHDotScroll)     // allow screen to scroll by pixels
   SetData($00)               // set to zero pixels
   Command(cmdOverlay)        // controls how graphics layers are combined
   SetData($1C)               // set to priority OR L1 > L2 > L3, all graphics layers
   Command(cmdDisplayOff)     // command for screen off...
   SetData($54)               // but sets screens 1 - 3 for turning on later
   Command(cmdCsrForm)        // select cursor size and shape
   SetData($00)               // cursor width - 1
   SetData($80)               // cursor height - 1 (plus block style)
   Command(cmdCsrDirRight)    // set cursor to increment to right
   CsrMemPosition(0)          // cursor at start of graphics layer 1
   Command(cmdDisplayWrite)   // set to write to display memory
   For i = 1 To 28800         // clear layers 1 - 3 of display memory
      SetData($00)           
   Next
   CsrMemPosition(0)          // cursor at start of graphics layer 1
   Command(cmdDisplayOn)      // command for screen on...
   SetData($54)               // for screens 1 - 3
   Layers = %01010100         // default to all three graphics layers on (1 - 3)
   SwitchLayer(1)             // start with layer 1 as drawing layer
End Sub 


// configure the module
Initialize

Post Reply