Using the Xtender to Control LCD Module(s) Serially Without TICkit I/O

; Program to use Xtender as a multi-drop serial interface to character
; LCD modules. Requires one Xtender per LCD

DEF tic62_c
LIB fbasic.lib

LIB xtn73h.lib

DEF lcd_rs 0y00001000b
DEF lcd_rw 0y00000100b
DEF lcd_e  0y00000010b


FUNC none xtn_buss_init
    PARAM word i2c_addr ; bit 0 is ignored and must be low
BEGIN
    i2c_write( +( i2c_addr, xtn_pins_in ), 0y11110000b )
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y11111110b )
    i2c_write( +( i2c_addr, xtn_pins_out ), 0y00001110b )
ENDFUN


FUNC none xtn_buss_write
    PARAM word i2c_addr ; bit 8 is used as address RS of LCD
    PARAM byte data
    LOCAL byte temp
BEGIN
    IF b_test( i2c_addr, 0x0100w )
        b_clear( i2c_addr, 0x0100w )
        i2c_write( +( i2c_addr, xtn_pins_low ), 0y11111110b )
        i2c_write( +( i2c_addr, xtn_pins_out ), 0y11111110b )
        =( temp, b_and( data, 0y11110000b ))
        i2c_write( +( i2c_addr, xtn_pins_high ), temp )
        i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
        i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low

        =( temp, *( 16b, b_and( data, 0y00001111b )))
    ELSE
        i2c_write( +( i2c_addr, xtn_pins_low ), 0y11111110b )
        i2c_write( +( i2c_addr, xtn_pins_out ), 0y11111110b )
        =( temp, b_and( data, 0y11110000b ))
        =( temp, b_or( temp, 0y00001000b ))
        i2c_write( +( i2c_addr, xtn_pins_high ), temp )
        i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
        i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low

        =( temp, *( 16b, b_and( data, 0y00001111b )))
    ENDIF

    i2c_write( +( i2c_addr, xtn_pins_low ), 0y11110110b )
    i2c_write( +( i2c_addr, xtn_pins_high ), temp )
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low
ENDFUN


FUNC byte xtn_buss_read
    PARAM word i2c_addr ; bit 8 is used as address of RS of LCD
    LOCAL byte temp
BEGIN
    IF b_test( i2c_addr, 0x0100w )
        b_clear( i2c_addr, 0x0100w )
        i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000100b )
        i2c_write( +( i2c_addr, xtn_pins_low ), 0y00001010b )
    ELSE
        i2c_write( +( i2c_addr, xtn_pins_high ), 0y00001100b )
    ENDIF

    i2c_write( +( i2c_addr, xtn_pins_in ), 0y11110000b )
    i2c_write( +( i2c_addr, xtn_pins_out ), 0y00001110b )
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    =( exit_value, b_and( i2c_read( +( i2c_addr, xtn_pins )), 0y11110000b ))
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low

    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    =( temp, b_and( i2c_read( +( i2c_addr, xtn_pins )), 0y11110000b ))
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low
    =( exit_value, b_or( exit_value, /( temp, 16b )))
ENDFUN


FUNC none xtn_lcd_init
    PARAM word i2c_addr
BEGIN
    xtn_buss_init( i2c_addr )
    delay( 15 )                               ; wait 15ms
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y11111110b )
    i2c_write( +( i2c_addr, xtn_pins_out ), 0y11111110b )
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00110000b )
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low
    delay( 5 )
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low
    delay( 1 )
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low

    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00010000b ) ; make it a 2 nibble
    i2c_write( +( i2c_addr, xtn_pins_high ), 0y00000010b ) ; pulse enable
    i2c_write( +( i2c_addr, xtn_pins_low ), 0y00000010b ) ; enable back low

    xtn_buss_write( +( i2c_addr, 0x0100w ), 0y00101000b )   ; assumes 2 line 5x7 font
    xtn_buss_write( +( i2c_addr, 0x0100w ), 0y00001111b )
    xtn_buss_write( +( i2c_addr, 0x0100w ), 0y00000001b )
    xtn_buss_write( +( i2c_addr, 0x0100w ), 0y00000110b )
ENDFUN


FUNC none xtn_lcd_string
    PARAM word i2c_addr
    PARAM word str_pntr
    LOCAL word pointer
    LOCAL byte data
BEGIN
    =( pointer, str_pntr )
    =( data, ee_read( pointer ))
    WHILE data
        xtn_buss_write( i2c_addr, data )
        ++( pointer )
        =( data, ee_read( pointer ))
    LOOP
ENDFUN



FUNC none main
BEGIN
    delay( 10 )
    rs_param_set( debug_pin )
    con_out( i2c_read( xtn_dev0 | xtn_reset ))
    xtn_lcd_init( xtn_dev0 )
    xtn_lcd_string( xtn_dev0, "Hello There" )
    REP
        debug_on()
    LOOP
ENDFUN

 

Protean Logic Inc. Copyright 05/06/04         Top of Page