From Swordfish Wiki

SwordfishUser: SED1520

This library supports a 122 x 32 GLCD with the SED1520 controller. The GLCD is a monochrome display and is commonly available. The library is intended for use with the standard Swordfish GLCD library (GLCD.bas). This will allow use of proportional fonts, bitmap images and vector graphics.

The library is included below. Use with the GLCD library requires an addition to the GLCD library itself. However, this has already been done for you. You do not need to add the module code shown below to the user library folder. Just do one of the following:

This will update the GLCD library and add the new SED1520 library.

Note that the library assumes that the RST pin of the display is left disconnected. In addition, the CS1 and CS2 pins are sometimes labelled E1 and E2 and the RS pin is labelled A0.

Below are two images of the display in use - the first shows the use of Rectangle() and proportional fonts, the second also shows the use of bitmap images with SetImage() for the buttons.

It is a useful exercise to compare this libary to the standard Swordfish KS0108 driver library - this shows how easy it is to adapt an existing library for use with a new controller. The development of this driver did not take more than around five hours.

Steven Wright

SED1520 Graphics Driver

Sample Code

Device = 18F452
Clock =  20

#option GLCD_MODEL = SED1520

Include "Graphics.bas"
Include "GLCD.bas"
Include "Tahoma.bas"
Include "Bitmaps.bas"

SetFont(Tahoma)
Font.Style = fsNormal
TextAlign = taCenter

Cls

WriteStr(60,4,"- SWORDFISH SED1520 -")

SetImage(0,19,BtnOK)
SetImage(83,19,BtnCancel)

SED1520 Module

{
****************************************************************************
*  Name    : SED1520.BAS                                                   *
*  Author  : S Wright                                                      *
*  Notice  : Copyright (c) 2006 S Wright                                   *
*          : All Rights Reserved                                           *
*  Date    : 03/11/2006                                                    *
*  Version : 1.0                                                           *
*  Notes   :                                                               *
*          :                                                               *
****************************************************************************
}
Module SED1520

// import the graphics module...
#define GLCD_PIXEL_01
#define GLCD_COLOR_01
#define GLCD_XY_08
Include "Graphics.bas"   
Include "System.bas"   

// default module options - user options can override these values...
#option GLCD_DATA = PORTD        // data port
#option GLCD_RS = PORTC.0        // RS pin (control or data)
#option GLCD_RW = PORTC.1        // RW pin (read or write)
#option GLCD_CS1 = PORTC.2       // chip select
#option GLCD_CS2 = PORTC.3       // chip select
#option GLCD_ASPECT_RATIO = 110  // aspect ratio, smaller number will squeeze y for GLCD circles and box
#option GLCD_INIT_DELAY = 100    // initialisation delay (ms)

// 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 RS pin...
#if IsOption(GLCD_RS) And Not IsValidPortPin(GLCD_RS) 
   #error GLCD_RS, "Invalid option. RS 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 CS1 pin...
#if IsOption(GLCD_CS1) And Not IsValidPortPin(GLCD_CS1) 
   #error GLCD_CS1, "Invalid option. CS1 must be a valid port pin."
#endif

// validate CS2 pin...
#if IsOption(GLCD_CS2) And Not IsValidPortPin(GLCD_CS2) 
   #error GLCD_CS2, "Invalid option. CS2 must be a valid port pin."
#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 = 122,
   GLCDHeight = 32

// x, y position...
Public Dim
   Pos As TPosition

// left or right controller
Dim
   Side As Byte

// SED1520 commands...   
Const
   cmdOn = $AF,                 // turn on display
   cmdOff = $AE,                // turn off display
   cmdStaticOff = $A4,          // turn static drive off
   cmdDutyCycle = $A9,          // set duty cycle to 1/32
   cmdReset = $E2,              // reset display
   cmdSetADC = $A0,             // set ADC
   cmdRMWDisable = $EE,         // disable read-modify-write
   cmdRMWEnable = $E0,          // enable read-modify-write
   cmdDisplayStartLine = $C0,
   cmdPage = $B8,
   cmdColumn = $00,
   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
   RS As GLCD_RS.GLCD_RS@,      // RS pin (control or data)
   RW As GLCD_RW.GLCD_RW@,      // RW pin (read or write)
   CS1 As GLCD_CS1.GLCD_CS1@,   // chip1 select
   CS2 As GLCD_CS2.GLCD_CS2@    // chip2 select
{
****************************************************************************
* Name    : GLCDData (PRIVATE)                                             *
* Purpose : Switch to GLCD data mode                                       *
****************************************************************************
}    
Inline Sub GLCDData()
   RS = 1                   
End Sub
{
****************************************************************************
* Name    : GLCDInst (PRIVATE)                                             *
* Purpose : Switch to GLCD instruction mode                                *
****************************************************************************
}    
Inline Sub GLCDInst()
   RS = 0	                 
End Sub
{
****************************************************************************
* Name    : GLCDRead (PRIVATE)                                             *
* Purpose : Set GLCD to read mode                                          *
****************************************************************************
}    
Inline Sub GLCDRead()
   RW = 1                     
End Sub
{
****************************************************************************
* Name    : GLCDWrite (PRIVATE)                                            *
* Purpose : Set GLCD to write mode                                         *
****************************************************************************
}    
Inline Sub GLCDWrite()
   RW = 0	                  
End Sub
{
****************************************************************************
* Name    : WaitForIdle (PRIVATE)                                          *
* Purpose : Block further GLCD access until signalled ready.               *
****************************************************************************
}     
Sub WaitForIdle()                           
   Dim Timeout As Byte
   CS1 = Side.Bits(0)          // CS high for left or ...
   CS2 = Side.Bits(1)          // right sides (or both)
   Timeout = $FF 
   GLCDInst	          // instruction data
   GLCDRead           // read mode
   TRISData = $FF     // set data bus to input
   Repeat
      ClrWDT
      Dec(Timeout)
   Until (Data.7 = 0) Or (Timeout = 0)
   CS1 = 0
   CS2 = 0
End Sub 
{
****************************************************************************
* Name    : SetData (PRIVATE)                                              *
* Purpose : Write a data byte to GLCD                                      *
*         : pSide: %01 = Left, %10 = Right, %11 = Both                     *
****************************************************************************
}     
Sub SetData(pData As Byte)                         
   WaitForIdle                 // block until not busy
   GLCDData                    // access display RAM data
   GLCDWrite				       // write mode
   CS1 = Side.Bits(0)          // CS high for left or ...
   CS2 = Side.Bits(1)          // right sides (or both)
   TRISData = $00              // set data bus to output
   Data = pData                // write to the bus    
   DelayUS(2)               
   CS1 = 0                     // latch data to GLCD
   CS2 = 0
   DelayUS(2)               
End Sub
{
****************************************************************************
* Name    : Command (PRIVATE)                                              *
* Purpose : Write a command byte to GLCD                                   *
*         : pSide: %01 = Left, %10 = Right, %11 = Both                     *
****************************************************************************
}     
Sub Command(pCommand As Byte)                   
   WaitForIdle                 // block until not busy
   GLCDInst                    // instruction mode
   GLCDWrite			          // write mode
   CS1 = Side.Bits(0)          // CS high for left or ...
   CS2 = Side.Bits(1)          // right sides (or both)
   TRISData = $00              // set data bus to output
   Data = pCommand             // write to the bus    
   DelayUS(2)               
   CS1 = 0                     // latch data to GLCD
   CS2 = 0
   DelayUS(2)               
End Sub
{
****************************************************************************
* Name    : GetData (PRIVATE)                                              *
* Purpose : Read byte from GLCD                                            *
*         : pSide: %01 = Left, %10 = Right, %11 = Both                     *
****************************************************************************
}     
Function GetData() As Byte               
   Command(cmdRMWEnable)
   WaitForIdle                 // block until not busy
   CS1 = Side.Bits(0)          // CS high for left or ...
   CS2 = Side.Bits(1)          // right sides (or both)
   GLCDData                    // access display RAM data
   GLCDRead                    // read mode
   CS1 = 0
   CS2 = 0
   DelayUS(2)
   TRISData = $FF              // set data bus to input
   CS1 = Side.Bits(0)          // CS high for left or ...
   CS2 = Side.Bits(1)          // right sides (or both)
   DelayUS(2)
   Result = Data               // get the data
   CS1 = 0
   CS2 = 0
   DelayUS(2)
   Command(cmdRMWDisable)
End Function  
{
****************************************************************************
* Name    : SetPosition (PRIVATE)                                          *
* Purpose : Set GLCD x and y positions                                     *
****************************************************************************
}     
Sub SetPosition()                                       
   Dim xPos As Byte
   If Pos.x < 61 Then           // find x position for left or right controller
      xPos = Pos.x
      Side = %01
   Else
      xPos = Pos.x - 61
      Side = %10
   EndIf
   Command(cmdColumn Or xPos)   // set x position	
   Command(cmdPage Or Pos.y)    // set y position
End Sub
{
****************************************************************************
* Name    : WriteByte                                                      *
* Purpose : Write a byte at x, page                                        *
****************************************************************************
} 
Public Sub WriteByte(pValue As Byte)            
   SetPosition
   SetData(pValue)
End Sub 
{
****************************************************************************
* Name    : ReadByte                                                       *
* Purpose : Read a byte at x, page                                         *
****************************************************************************
} 
Public Function ReadByte() As Byte                
   SetPosition
   GetData
   Result = GetData
End Function
{
****************************************************************************
* Name    : SetPixel                                                       *
* Purpose : Set pixel at pixel location x,y                                *
****************************************************************************
} 
Public Sub SetPixel(pX, pY As Byte)                         
   Dim YBit As Byte
   Dim Pixel As Byte

   If (pX < GLCDWidth) And (pY < GLCDHeight) Then

      YBit = 1 << (pY Mod 8)
      Pos.y = pY / 8
      Pos.x = pX

      SetPosition
      GetData
      Pixel = GetData  

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

      // pen is black...
      Else

         // pen copy or merge...
         If Pen.Mode <> pmXOR Then
            Pixel = Pixel Or YBit

         // pen XOR
         Else
            If (Pixel And YBit) = 0 Then
               Pixel = Pixel Or yBit
            Else
               yBit = Not yBit
               Pixel = Pixel And YBit
            EndIf      
         EndIf
      EndIf

      SetPosition
      SetData(Pixel)
   EndIf
End Sub
{
****************************************************************************
* Name    : GetPixel                                                       *
* Purpose : Return pixel colour at pixel position x, y                     *
****************************************************************************
}
Public Function GetPixel(pX, pY As Byte) As TColor              
   Dim Pixel As Byte
   Pos.y = pY / 8
   Pos.x = pX
   SetPosition
   GetData
   Pixel = GetData >> (pY Mod 8) 
   Result = Pixel.0  
End Function
{
****************************************************************************
* Name    : Cls                                                            *
* Purpose : Clear the GLCD screen                                          *
****************************************************************************
} 
Public Sub Cls()                             
   Dim x, y As Byte
   Side = %11
   Command(cmdOff) 
   y = 0
   Repeat	
      Command(cmdPage Or y)
      x = 0
      Repeat	
	 Command(cmdColumn Or x)
         SetData($00)
         Inc(x)
      Until x > 60
      Inc(y)
   Until y > 3	
   Command(cmdOn)           
End Sub 
{
****************************************************************************
* Name    : Initialize                                                     *
* Purpose : Configure the GLCD before use                                  *
****************************************************************************
} 
Sub Initialize()                                 
   Pos.x = 0
   Pos.y = 0  
   DelayMS(GLCDDelay) // start up delay, allow GLCD to settle
   Output(RS)
   Output(RW)
   Output(CS1)        // screen (1)
   Output(CS2)        // screen (2)
   Side = %01
   Repeat
      Command(cmdOn) 
      Command(cmdStaticOff) 
      Command(cmdDutyCycle) 
      Command(cmdReset) 
      Command(cmdSetADC) 
      Command(cmdRMWDisable) 
      Command(cmdDisplayStartLine)   // set start position to top-left
      Command(cmdPage) 
      Command(cmdColumn)
      Inc(Side)
   Until Side > %10
   CS1 = 0
   CS2 = 0
End Sub 

// configure the module
Initialize
Retrieved from http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.SED1520
Page last modified on October 11, 2008, at 11:17 AM