# glcd_t6963

Character/graphic LCD with Toshiba T6963C controller

Author | Rob Hamerling, Copyright © 2015-2015, all rights reserved
Adapted-by |
Compiler | 2.4q3

Description

    Library to handle character/graphics LCD with Toshiba T6963c controller
    Tested with thi following modules:
           TW-7894V-0 (120x64)
           MG2406G    (240x64)
           MTG-2460G  (240x64)
    .
    The t6963 ia a rather special glcd controller: it supports an LCD as
    text and as graphics display simultaneously and independently.
    .
    Connector pins of these modules:
      pin    symb   I/O   description
       1      FG          frame ground
       2     GND          ground
       3     VCC          lcd logic voltage
       4     VEE          lcd (contrast) voltage
       5      wr     O    write enable (L)
       6      rd     O    read enable (L)
       7      ce     O    chip enable (L)
       8      cd     O    H: command, L: data
       9                  not connected
      10    reset    O    reset (L)
     11-18  db0-7   I/O   data byte
      19      fs     O    font select (H: 6X8, L: 8x8)
      20                 not connected
    Other modules may have a different pin layout!
    Of the TW-7894V-0 pin 19 seems not connected: fixed 6x8 font.
    Of the MG2406G pin 9 is Vee: negative voltage for LCD contrast.
    .
    The following aliases must be defined by the user program:
    .
    Data port:
       alias t6963_dataport  is portX
       alias t6963_dataport_direction is portX_direction
    The library requires that all 8 data pins are wired to the
    same PIC-port and in sequence 'd0' to pin_X0, 'd1' to pin_X1, etc.
    All pins must be capable of digital output and input.
    The port direction is dynamically selected by the library.
    .
    Control pins:
       alias t6963_wr        is pin_Ya      -- write enable
       alias t6963_rd        is pin_Yb      -- read enable
       alias t6963_cd        is pin_Yc      -- command or data selection
       alias t6963_ce        is pin_Yd      -- chip enable
       alias t6963_reset     is pin_Ye      -- reset controller
       alias t6963_fs        is pin_Yf      -- font select
    The control pins may be connected to any pin of the PIC capable
    of digital output and must be set for output by the user program.
    The font selection pin of the glcd module may be hard wired or the module
    may have a fixed font width. In that case the specification of t6963_fs
    is not required.
    .
    The following constant declarations are required:
      const byte T6963X_PIXELS    = 120    )
      const byte T6963Y_PIXELS    = 64     ) example values
      const byte T6963_FONT_WIDTH = 6      )
    T6963_FONT_WIDTH is optional, when not specified an 6 pixels wide font is assumed.
    Remarks: - The line length is derived from X-pixels and font width.
               The T6963c performs auto-wrapping of text and attributes based
               on this line length.
             - When the specified font width does not match with the hardware
               you may not see what you expected to see.
    For graphics display the following constants and variables may be needed:
      const bit T6963_CLIPPING   = TRUE   (default is FALSE)
      var   bit t6963_pen_color  = ON     (default, OFF = clear pixel)
    .
    T6963c memory organisation as used by this library.
       +-----------------------+ 0x0000
       |                       |
       |      Text Space       |
       |        (2 KB)         |
       + ----------------------+ 0x0800
       |                       |
       |   Graphics Space      |
       |        (4 KB)         |
       |                       |
       +-----------------------+ 0x1800
       |   CG area (2KB)       |
       +-----------------------+ 0x2000
    This memory layout is (temporary) fixed as ths proved to work fine
    with the tested modules.
    However this may be a limitation for more fancy applications!
    Modules can have up to 64 KB of memory. A probe function to determine
    the actual amount of RAM is already present, but not activated
    bacause it didn't work properly with a module with 64 KB RAM.
    .
    Public procedures and functions:
       t6963_init()
       t6963_set_mode()
       t6963_display_mode()
       t6963_clear_text()
       t6963_clear_graphics()
       t6963_clear_screen()
       t6963_read_char()
       t6963_read_next_char()
       t6963_write_char()
       t6963_write_next_char()
       t6963_write_string()
       t6963_set_cursor_pattern()
       t6963_set_cursor_position()
       t6963_set_attribute()
       t6963_write_pixel()
       t6963_read_cg_memory()
       t6963_write_cg_memory()
    .
    The library 'glcd_common' may be included by the user program for
    drawing lines, rectangulars, blocks, ellipses, etc.
    This requires that aliases  may have to be declared for
    device specific functions.
    Probably the very least you'll need to declare:
       alias  GLCD_X_PIXELS      is T6963_X_PIXELS
       alias  GLCD_Y_PIXELS      is T6963_Y_PIXELS
       alias  GLCD_FONT_WIDTH    is T6963_FONT_WIDTH
       alias  glcd_pen_color     is t6963_pen_color
       alias  glcd_write_pixel   is t6963_write_pixel
    In addition aliases may be needed for glcd_common library to
    get access to public procedures and functions of the t6963 library,
    such as:
       alias  glcd_init          is t6963_init
       alias  glcd_clear_screen  is t6963_clear_screen
       alias  glcd_write_pixel   is t6963_write_pixel
    and maybe more.

Sources

    http://www.lcd-module.de/fileadmin/eng/pdf/zubehoer/t6963c.pdf
             https://www.crystalfontz.com/controllers/Toshiba/T6963C/360

Notes

    - This library supports a subset of the features of the T6963c controller.
             Unsupported are for example:
             - screen peek and copy (combined text and graphics memory)
             - modules with 'dual scan'
             - RAM other than 8 KB

Dependencies

No dependency found

## Summary

### Global variables/contants

- `const byte T6963_SET_MODE_OR = 0x80`
- `const word T6963_TEXT_HOME = 0x0000`
- `const byte T6963_DISPLAY_OFF = 0x90`
- `const byte T6963_SET_MODE_TEXT_ONLY = 0x84`
- `var word t6963_memsize = 0x2000`
- `const byte T6963_ATTRIBUTE_REVERSE_BLINK = 0x0D`
- `const byte T6963_SET_MODE_EXOR = 0x81`
- `const byte T6963_SET_ADDRESS_POINTER = 0x24`
- `const byte T6963_DATA_READ_AND_DECREMENT = 0xC3`
- `const byte T6963_ATTRIBUTE_INHIBIT = 0x03`
- `const byte T6963_SCREEN_COPY = 0xE8`
- `const byte T6963_DISPLAY_CURSOR_BLINK_ON = 0x91`
- `const byte T6963_DATA_AUTO_RESET = 0xB2`
- `const byte T6963_CURSOR_PATTERN_SELECT = 0xA0`
- `const byte T6963_DISPLAY_GRAPHICS_ON = 0x98`
- `const byte T6963_SET_TEXT_HOME_ADDRESS = 0x40`
- `const byte T6963_SET_CURSOR_POINTER = 0x21`
- `const byte T6963_TEXT_AREA = T6963_X_PIXELS / T6963_FONT_WIDTH`
- `const byte T6963_DATA_WRITE_AND_INCREMENT = 0xC0`
- `const byte T6963_ATTRIBUTE_INHIBIT_BLINK = 0x0B`
- `const byte T6963_DATA_WRITE = 0xC4`
- `const byte T6963_ATTRIBUTE_NORMAL = 0x00`
- `const byte T6963_DISPLAY_CURSOR_ON = 0x92`
- `const byte T6963_DATA_READ = 0xC5`
- `const byte T6963_ATTRIBUTE_REVERSE = 0x05`
- `const byte T6963_TEXT_ROWS = T6963_Y_PIXELS / 8`
- `const byte T6963_SCREEN_PEEK = 0xE0`
- `const byte T6963_DATA_AUTO_READ = 0xB1`
- `const byte T6963_ATTRIBUTE_NORMAL_BLINK = 0x08`
- `const byte T6963_DATA_WRITE_AND_DECREMENT = 0xC2`
- `const byte T6963_PIXEL_SET = 0xF8`
- `const byte T6963_SET_TEXT_AREA = 0x41`
- `const byte T6963_GRAPHICS_AREA = T6963_X_PIXELS / T6963_FONT_WIDTH`
- `const byte T6963_SET_OFFSET_REGISTER = 0x22`
- `const byte T6963_SET_MODE_CG_EXTERNAL = 0x88`
- `const byte T6963_DATA_AUTO_WRITE = 0xB0`
- `const byte T6963_DATA_READ_AND_INCREMENT = 0xC1`
- `const byte T6963_SET_MODE_AND = 0x83`
- `var word t6963_cg_home = 0x1800`
- `const byte T6963_PIXEL_CLEAR = 0xF0`
- `const byte T6963_SET_GRAPHICS_HOME_ADDRESS = 0x42`
- `var word t6963_graphics_home = 0x0800`
- `const byte T6963_SET_GRAPHICS_AREA = 0x43`
- `const byte T6963_DISPLAY_TEXT_ON = 0x94`

### Procedures

- `t6963_wait_until_ready()`
- `t6963_set_attribute(byte in column, byte in row, byte in attr, byte in num)`
- `t6963_write_dataport(byte in data)`
- `t6963_init()`
- `t6963_write_command(byte in cmd)`
- `t6963_set_mode(byte in mode)`
- `t6963_write_char(byte in column, byte in row, byte in d)`
- `t6963_clear_text()`
- `t6963_write_string(byte in column, byte in row, byte in string[])`
- `t6963_write_next_char(byte in d)`
- `t6963_display_mode(byte in mode)`
- `t6963_set_cg_offset()`
- `t6963_clear_memory_region(word in addr, word in amount)`
- `t6963_write_data(byte in data)`
- `t6963_read_data()`
- `t6963_set_address(word in address)`
- `t6963_clear_graphics()`
- `t6963_read_cg_memory(byte in x, byte in pattern[])`
- `t6963_set_cursor_pattern(byte in lines)`
- `t6963_wait_until_ready_to_auto_read()`
- `t6963_draw_image(byte in x, byte in y, byte in image[])`
- `t6963_clear_screen()`
- `t6963_set_cursor_position(byte in column, byte in row)`
- `t6963_write_cg_memory(byte in ascii, byte in pattern[])`
- `t6963_wait_until_ready_to_auto_write()`
- `t6963_write_pixel(byte in x, byte in y)`
- `t6963_wait_until_ready_mask(byte in mask)`

### Functions

- `t6963_probe_memory() return byte`
- `t6963_read_next_char() return byte`
- `t6963_read_char(byte in column, byte in row) return byte`
- `t6963_read_dataport() return byte`

## API details

### Global variables/contants

- `const byte T6963_SET_MODE_OR = 0x80`

  No documentation found

- `const word T6963_TEXT_HOME = 0x0000`

      fixed

- `const byte T6963_DISPLAY_OFF = 0x90`

  No documentation found

- `const byte T6963_SET_MODE_TEXT_ONLY = 0x84`

  No documentation found

- `var word t6963_memsize = 0x2000`

      8 KB

- `const byte T6963_ATTRIBUTE_REVERSE_BLINK = 0x0D`

  No documentation found

- `const byte T6963_SET_MODE_EXOR = 0x81`

  No documentation found

- `const byte T6963_SET_ADDRESS_POINTER = 0x24`

  No documentation found

- `const byte T6963_DATA_READ_AND_DECREMENT = 0xC3`

  No documentation found

- `const byte T6963_ATTRIBUTE_INHIBIT = 0x03`

  No documentation found

- `const byte T6963_SCREEN_COPY = 0xE8`

  No documentation found

- `const byte T6963_DISPLAY_CURSOR_BLINK_ON = 0x91`

  No documentation found

- `const byte T6963_DATA_AUTO_RESET = 0xB2`

  No documentation found

- `const byte T6963_CURSOR_PATTERN_SELECT = 0xA0`

  No documentation found

- `const byte T6963_DISPLAY_GRAPHICS_ON = 0x98`

  No documentation found

- `const byte T6963_SET_TEXT_HOME_ADDRESS = 0x40`

  No documentation found

- `const byte T6963_SET_CURSOR_POINTER = 0x21`

  No documentation found

- `const byte T6963_TEXT_AREA = T6963_X_PIXELS / T6963_FONT_WIDTH`

  No documentation found

- `const byte T6963_DATA_WRITE_AND_INCREMENT = 0xC0`

  No documentation found

- `const byte T6963_ATTRIBUTE_INHIBIT_BLINK = 0x0B`

  No documentation found

- `const byte T6963_DATA_WRITE = 0xC4`

  No documentation found

- `const byte T6963_ATTRIBUTE_NORMAL = 0x00`

  No documentation found

- `const byte T6963_DISPLAY_CURSOR_ON = 0x92`

  No documentation found

- `const byte T6963_DATA_READ = 0xC5`

  No documentation found

- `const byte T6963_ATTRIBUTE_REVERSE = 0x05`

  No documentation found

- `const byte T6963_TEXT_ROWS = T6963_Y_PIXELS / 8`

  No documentation found

- `const byte T6963_SCREEN_PEEK = 0xE0`

  No documentation found

- `const byte T6963_DATA_AUTO_READ = 0xB1`

  No documentation found

- `const byte T6963_ATTRIBUTE_NORMAL_BLINK = 0x08`

  No documentation found

- `const byte T6963_DATA_WRITE_AND_DECREMENT = 0xC2`

  No documentation found

- `const byte T6963_PIXEL_SET = 0xF8`

  No documentation found

- `const byte T6963_SET_TEXT_AREA = 0x41`

  No documentation found

- `const byte T6963_GRAPHICS_AREA = T6963_X_PIXELS / T6963_FONT_WIDTH`

  No documentation found

- `const byte T6963_SET_OFFSET_REGISTER = 0x22`

  No documentation found

- `const byte T6963_SET_MODE_CG_EXTERNAL = 0x88`

  No documentation found

- `const byte T6963_DATA_AUTO_WRITE = 0xB0`

  No documentation found

- `const byte T6963_DATA_READ_AND_INCREMENT = 0xC1`

  No documentation found

- `const byte T6963_SET_MODE_AND = 0x83`

  No documentation found

- `var word t6963_cg_home = 0x1800`

      +6 KB

- `const byte T6963_PIXEL_CLEAR = 0xF0`

  No documentation found

- `const byte T6963_SET_GRAPHICS_HOME_ADDRESS = 0x42`

  No documentation found

- `var word t6963_graphics_home = 0x0800`

      +2 KB

- `const byte T6963_SET_GRAPHICS_AREA = 0x43`

  No documentation found

- `const byte T6963_DISPLAY_TEXT_ON = 0x94`

  No documentation found

### Procedures

- `t6963_wait_until_ready()`

      Spin until ready for next data (status bits 0 and 1 are both 1)

- `t6963_set_attribute(byte in column, byte in row, byte in attr, byte in num)`

      Set attribute
      Input: - (Start-)column and row of the text for which the
      attribute is meant.
        the atribute byte and the number of atttributes.
      The attribyte byte may be one of the following:
      T6963_ATTRIBUTE_NORMAL
      T6963_ATTRIBUTE_REVERSE
      T6963_ATTRIBUTE_INHIBIT
      T6963_ATTRIBUTE_NORMAL_BLINK
      T6963_ATTRIBUTE_REVERSE_BLINK
      T6963_ATTRIBUTE_INHIBIT_BLINK
      Notes: - Attribute bytes are bytes in graphics memory, corresponding to
      characters in text memory
       The controller is set to text mode only (required with attributes)
       Graphics memory may have to be erased by the user program when
      starting with attributes.
       Text AND graphics display must be selected by the user program
      with or without cursor(blinking) to activate the attributes.

- `t6963_write_dataport(byte in data)`

      write dataport
      Setting of t6963_cd by caller determines data or command write
      Upon return:
       the dataport is left in OUTPUT mode

- `t6963_init()`

      Initialize t6963
      Control signals use negative logic  (high is inactive)
      All control pins must be set for output by the application
      Both text and graphics display are active

- `t6963_write_command(byte in cmd)`

- `t6963_set_mode(byte in mode)`

      Set mode for mixed graphics and text (or text only)
      Set one of the following constants:
      T6963_SET_MODE_OR
      T6963_SET_MODE_EXOR
      T6963_SET_MODE_AND
      T6963_SET_MODE_TEXT_ONLY
      Optionally combined (or-ed) with characterset selection:
      T6963_SET_MODE_CG_EXTERNAL

- `t6963_write_char(byte in column, byte in row, byte in d)`

      Display a character at a specific location on the screen,
      column and row are character offsets on the physical screen.
      After the write the address is incremented. Adjacent characters
      (e.g. of an array or string) may use t6963_write_next_char(),
      no need for the user to maintain the current position.

- `t6963_clear_text()`

      Clear text memory

- `t6963_write_string(byte in column, byte in row, byte in string[])`

      Display a string starting at a specific location on the screen,
      column and row are character offsets on the physical screen.
      This procedure is more efficient than writing individual adjacent characters.

- `t6963_write_next_char(byte in d)`

      Display a character on the screen at the current location.
      The address is incremented and subsequent t6963_write_next_char()
      will use the next text location and wraps automatically.
      Notes: The ASCII values of built-in font are 32 less!
      This difference is taken care of by this procedure and means
      a.o. that ASCII values 0x00-0x1F (dec 0..31) cannot be displayed.
      Example: "A" with ASCII value 0x41 is written as 0x21,
      thus reading back would show 0x21.

- `t6963_display_mode(byte in mode)`

      Set display mode
      Set any or a combination (or-ed) of the following constants:
      T6963_DISPLAY_OFF
      T6963_DISPLAY_CURSOR_BLINK_ON
      T6963_DISPLAY_CURSOR_ON
      T6963_DISPLAY_TEXT_ON
      T6963_DISPLAY_GRAPHICS_ON
      Note: To switch one of these off de-select it!

- `t6963_set_cg_offset()`

      Select CG-RAM as upper 2 KB of RAM

- `t6963_clear_memory_region(word in addr, word in amount)`

      Clear memory region

- `t6963_write_data(byte in data)`

- `t6963_read_data()`

- `t6963_set_address(word in address)`

- `t6963_clear_graphics()`

      Clear graphics memory
      Note: Works fine even with 64K memory (when t6963_memsize is 0)

- `t6963_read_cg_memory(byte in x, byte in pattern[])`

      Read font pattern(s) from CG RAM
      The pattern of one CG RAM character consists of 8 bytes.
      This procedure allows to read one or more font patterns,
      depending on the size of the specified array.
      The whole rangeof ASCII values can be read, both
      internal (0x00-7F) and external (0x80..FF) CG-RAM.

- `t6963_set_cursor_pattern(byte in lines)`

      Set cursor pattern
      Input: height of the cursor: number of pixels (1..8)
      Notes: - Cursor ON/OFF/BLINK must be selected with t6963_display_mode)
       lines=1 is bottom line, lines=2 bottom 2 lines, lines=8 block cursor

- `t6963_wait_until_ready_to_auto_read()`

      Spin until ready to auto-read (status bit 2 is 1)

- `t6963_draw_image(byte in x, byte in y, byte in image[])`

      Display an image in graphics
      (x,y) are pixel offsets on the physical screen of upper left corner of the image
      image is a byte array
      Notes: work in progress!

- `t6963_clear_screen()`

      Clear screen (both text and graphics memory

- `t6963_set_cursor_position(byte in column, byte in row)`

      Set cursor position
      Input: column and row of the cursor
      Notes: - Cursor ON/OFF/BLINK must be selected with t6963_display_mode.
       The cursor does not automatically move when writing characters!

- `t6963_write_cg_memory(byte in ascii, byte in pattern[])`

      Write font pattern(s) to CG-RAM
      This procedure allows to write font patterns for one or more
      characters in one operation. It takes the specified character ASCII
      value as the first position and writes as many patterns as are in
      the pattern array (most likely 8 or a multiple of 8 bytes).
      The characters after the first will have subsequent character values.
      Input: - Character (ASCII value)
       Array with bitpatterns (8 bytes per CG character, each of
      the bytes represents a horizontal line of 8 pixels.
      Notes: - This library uses the internal font, which means:
       characters 0x00..0x7F are fixed (T6963 chip builtin)
       characters 0x80..0xFF are user defined.

- `t6963_wait_until_ready_to_auto_write()`

      Spin until ready to auto-write (status bit 3 is 1)

- `t6963_write_pixel(byte in x, byte in y)`

      Display or clear a single pixel in graphics
      (x,y) are pixel offsets on the physical screen
      Current value of t6963_pen_color determines if pixel is set or cleared

- `t6963_wait_until_ready_mask(byte in mask)`

      Spin until ready for next command or data
      Input: Mask is the bit combination in the status byte
      to specify which bytes must be set

### Functions

- `t6963_probe_memory() return byte`

      Probe RAM memory to determine the amount of available RAM
      Using steps of 2 KB
      Writes and reads back 0x55 and 0xAA to last byte of each 2K block
      as long as read back data matches written data.
      Returns the number of 2KB blocks available.
      Note: Seems to work only after complete initialisation of the T6963

- `t6963_read_next_char() return byte`

      Read a byte from the current address.
      and increment address afterwards

- `t6963_read_char(byte in column, byte in row) return byte`

      Read a character at a specific location (column, row) in text memory
      This procedured

- `t6963_read_dataport() return byte`

      read dataport
      Setting of t6963_cd by caller determines data or command read
      Upon return:
       the dataport is left in INPUT mode

## Related samples

Here are the list of samples which use this library:

16f877a | 16f877a_glcd_t6963.jal