------------------------------------------------------------------------ -- LCD driver -- Author : David Li, Eric Cheun, Felicia Cheng, Wilson Kwan -- Date : 2000 winter -- Architecture : Display -- Description: to initialize the LCD and wait for the user -- to input the characters. ------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.CDMA_pkg.all; entity lcddriver is port( clock, clk_en: in std_logic; resetn : in std_logic; -- input from outside such as a keypad message : in std_logic_vector (2 downto 0); -- lcd register select signal lcd_select : out std_logic; lcd_data : out std_logic_vector(7 downto 0); lcd_rw : out std_logic; lcd_enable : out std_logic; -- detect if there is any incoming message enable : in std_logic ); end lcddriver; -- Architecture Description architecture Display of lcddriver is TYPE STATE_TYPE IS (initial, display, entrymode, clear, waiting, verify, putchar, homecursor); SIGNAL state,next_state: STATE_TYPE; -- Clear screen. constant CLR: std_logic_vector(7 downto 0) := "00000001"; -- Display ON, with cursor. constant DON: std_logic_vector(7 downto 0) := "00001110"; -- Set Entry Mode to increment cursor automatically after each character -- is displayed. constant SEM: std_logic_vector(7 downto 0) := "00000110"; -- Home cursor constant HOME: std_logic_vector(7 downto 0) := "00000010"; -- Function set for 8-bit data transfer and 2-line display constant SET: std_logic_vector(7 downto 0) := "00111000"; -- The numbers and symbols constant zero: std_logic_vector(7 downto 0) := "00110000"; constant one: std_logic_vector(7 downto 0) := "00110001"; constant two: std_logic_vector(7 downto 0) := "00110010"; constant three: std_logic_vector(7 downto 0) := "00110011"; constant four: std_logic_vector(7 downto 0) := "00110100"; constant five: std_logic_vector(7 downto 0) := "00110101"; constant six: std_logic_vector(7 downto 0) := "00110110"; constant seven: std_logic_vector(7 downto 0) := "00110111"; constant eight: std_logic_vector(7 downto 0) := "00111000"; constant nine: std_logic_vector(7 downto 0) := "00111001"; constant star: std_logic_vector(7 downto 0) := "00101010"; constant pound: std_logic_vector(7 downto 0) := "00100011"; -- Some potentially useful puctuation. constant SP: std_logic_vector(7 downto 0) := "00100000"; -- Space constant big_delay: integer :=14; constant small_delay: integer :=2; constant reg_setup: integer :=1; constant lastposition: integer:=16; begin lcd_rw<='0'; process (clock,resetn,enable) variable position: integer range 0 to lastposition; variable count: integer range 0 to big_delay; begin wait until clock'event and clock = '1'; IF resetn = '0' THEN -- test resetn state<=initial; position:=0; count:=0; elsif clk_en = '1' then case state is WHEN initial => -- to set the function if count=reg_setup then lcd_enable<='1'; else lcd_enable<='0'; end if; lcd_data<=SET; lcd_select<='0'; if count=small_delay then state<=display; count:=0; else count:=count+1; end if; WHEN display => -- to set display on if count=reg_setup then lcd_enable<='1'; else lcd_enable<='0'; end if; lcd_data<=DON; lcd_select<='0'; if count=small_delay then state<=entrymode; count:=0; else count:=count+1; end if; WHEN entrymode => -- to set entry mode, increment after each character -- is displayed if count=reg_setup then lcd_enable<='1'; else lcd_enable<='0'; end if; lcd_data<=SEM; lcd_select<='0'; if count=small_delay then state<=clear; count:=0; else count:=count+1; end if; WHEN clear => -- clear the screen if count=reg_setup then lcd_enable<='1'; else lcd_enable<='0'; end if; lcd_data<=CLR; lcd_select<='0'; if count=big_delay then state<=waiting; count:=0; else count:=count+1; end if; when waiting => -- wait for input if enable='0' then state<=verify; end if; when verify => if enable='1' then if position=lastposition then state<=homecursor; position:=0; else state<=putchar; end if; end if; when putchar=> -- display the character on the LCD if count=reg_setup then lcd_enable<='1'; else lcd_enable<='0'; end if; case message is when "000" => lcd_data<=zero; when "001" => lcd_data<=one; when "010" => lcd_data<=two; when "011" => lcd_data<=three; when "100" => lcd_data<=four; when "101" => lcd_data<=five; when "110" => lcd_data<=six; when "111" => lcd_data<=seven; --when "1000" => lcd_data<=eight; --when "1001" => lcd_data<=nine; --when "1010" => lcd_data<=star; --when "1011" => lcd_data<=pound; when others => lcd_data<=SP; end case; lcd_select<='1'; if count=small_delay then state<=waiting; position:=position+1; count:=0; else count:=count+1; end if; when homecursor=> if count=reg_setup then lcd_enable<='1'; else lcd_enable<='0'; end if; lcd_data<=HOME; lcd_select<='0'; if count=big_delay then state<=putchar; count:=0; else count:=count+1; end if; end case; end if; end process; end Display;