;; ;; $Id: lcd.asm,v 1.4 2001/03/05 03:43:42 james Exp $ ;; ;; lcd.asm, functions for accessing two line LCD panel. ;; Copyright (C) 2001 James Cameron (quozl@us.netrek.org) ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;; c_lcd_clear equ b'00000001' ; 1.64ms c_lcd_home equ b'00000010' ; 1.64ms c_lcd_entry_mode equ b'00000100' ; 42us m_lcd_entry_mode_increase equ b'00000010' m_lcd_entry_mode_shifted equ b'00000001' c_lcd_display equ b'00001000' ; 42us m_lcd_display_on equ b'00000100' m_lcd_display_cursor_on equ b'00000010' m_lcd_display_blink_on equ b'00000001' c_lcd_shift equ b'00010000' ; 42us m_lcd_shift_display equ b'00001000' m_lcd_shift_right equ b'00000100' c_lcd_function equ b'00100000' m_lcd_function_eight_bit equ b'00010000' m_lcd_function_two_line equ b'00001000' m_lcd_function_5by10 equ b'00000100' c_lcd_cg equ b'01000000' ; 42us m_lcd_cg equ b'00111111' c_lcd_dd equ b'10000000' ; 42us m_lcd_dd equ b'01111111' m_lcd_busy equ b'10000000' ; busy flag reply bit ; addresses of rows lcd_row_0 equ 0x0 lcd_row_1 equ 0x40 lcd_write ; ( -- ) ; set lcd data bus pins to output movf r_trisb,w andlw ~(m_lcdd) movwf r_trisb bsf status,rp0 movwf t_lcdd bcf status,rp0 bcf p_lcdc,b_lcd_rw ; restore to write mode return lcd_read ; ( -- ) ; set lcd data bus pins to input bsf p_lcdc,b_lcd_rw ; set to read mode movf r_trisb,w ; fetch trisb mask iorlw m_lcdd ; set lcd data bus pins movwf r_trisb ; save trisb mask bsf status,rp0 movwf t_lcdd bcf status,rp0 return lcd_get_byte ; ( -- byte ) ; get a byte from the device bsf p_lcdc,b_lcd_e ; raise enable ; device provides high nibble movf p_lcdd,w ; get high nibble andlw m_lcdd ; keep only the data bits pushw ; save on stack bcf p_lcdc,b_lcd_e ; lower enable bsf p_lcdc,b_lcd_e ; raise enable ; device provides low nibble swapf p_lcdd,w ; get low nibble andlw ~m_lcdd ; keep only the data bits iorwf indf,f ; merge with return data bcf p_lcdc,b_lcd_e ; lower enable return lcd_idle ; ( -- ) ; wait for prior operation to complete call lcd_read lcd_idle_loop call lcd_get_byte popw andlw m_lcd_busy ; keep busy flag bnz lcd_idle_loop ; loop until not busy call lcd_write return lcd_put_hex ; ( byte -- ) call eb_hex call lcd_put lcd_put ; ( data -- ) ; put data to the lcd at cursor call lcd_idle ; wait for idle bsf p_lcdc,b_lcd_rs ; raise rs call lcd_put_byte ; send the byte bcf p_lcdc,b_lcd_rs ; lower rs return lcd_put_command ; ( command -- ) ; put a command to the lcd call lcd_idle ; wait for idle lcd_put_byte ; ( byte -- ) ; put a byte to the lcd swapf indf,w ; swap nibbles to accumulator pushw ; and copy byte to stack call lcd_put_nibble_no_wait ; send high nibble first ; send low nibble next lcd_put_nibble_no_wait ; ( nibble -- ) swapf indf,w ; align to upper bits andlw m_lcdd ; keep only data bits movwf indf ; save back to stack movf p_lcdd,w ; get port bits andlw m_lcdc ; keep control bits iorwf indf,w ; set data bits required movwf p_lcdd ; send to lcd pop ; drop the stack lcd_strobe ; strobe the data out bsf p_lcdc,b_lcd_e bcf p_lcdc,b_lcd_e return lcd_move ; ( location -- ) ; move cursor to location popw andlw m_lcd_dd iorlw c_lcd_dd pushw goto lcd_put_command lcd_initialise ; ( -- ) ; initialise the lcd panel call lcd_idle pushl c_lcd_function|m_lcd_function_two_line|m_lcd_function_5by10 call lcd_put_command pushl c_lcd_function|m_lcd_function_two_line|m_lcd_function_5by10 call lcd_put_command pushl c_lcd_display|m_lcd_display_on call lcd_put_command pushl c_lcd_entry_mode|m_lcd_entry_mode_increase call lcd_put_command pushl c_lcd_clear call lcd_put_command pushl c_lcd_home call lcd_put_command return