-- -- The Electronic Gardener -- -- -- Mark Kudryk, Kim Ellis -- -- Module Name: LCD Driver -- Author: Mark Kudryk -- Date: October 24, 1998 -- Status: Completed -- -- Size: 170 Logic Cells -- Period: 55.4 ns -- Clock: 17.88 MHz library ieee; use ieee.std_logic_1164.all; entity lcd is port (data_in: in std_logic_vector (7 downto 0); ready_for_line, byte_request: out std_logic; new_line_request, byte_valid: in std_logic; clock, reset: in std_logic; data_out: out std_logic_vector (7 downto 0); read_write, register_select, enable: out std_logic); end entity lcd; architecture behaviour of lcd is type state_type is (i0, i1, i2, i3, i4, i5, i6, i7, s1, s2, s2a, s2b, s2c, s2d, s3, s4); signal state: state_type; signal line1, line2: std_logic_vector(7 downto 0); signal sig1, sig2: std_logic_vector(2 downto 0); signal pick: std_logic; constant RS: natural := 0; constant RW: natural := 1; constant EN: natural := 2; component datareg is generic (WIDTH :positive := 8); port (data_in: in std_logic_vector(WIDTH-1 downto 0); reset, latch: in std_logic; data_out: out std_logic_vector(WIDTH-1 downto 0)); end component datareg; component mux_test is generic (width: positive := 8); port(data0, data1: in std_logic_vector (width-1 downto 0); choose: in std_logic; output: out std_logic_vector(width-1 downto 0)); end component mux_test; begin lcd_reg1: component datareg generic map (WIDTH => 8) port map(data_in => line2, reset => reset, latch => clock, data_out => data_out); lcd_reg2: component datareg generic map (WIDTH => 3) port map(data_in => sig1, reset => reset, latch => clock, data_out => sig2); read_write <= sig2(RW); register_select <= sig2(RS); enable <= sig2(EN); lcd_mux: component mux_test generic map (width => 8) port map(data0 => data_in, data1 => line1, choose => pick, output => line2); lcd_sm: process(reset, clock) variable count: natural range 0 to 2**6-1 := 0; begin if reset = '1' then state <= i0; pick <= '0'; -- used to be set to '1' count := 0; sig1(RS) <= '0'; sig1(RW) <= '0'; sig1(EN) <= '0'; ready_for_line <= '0'; byte_request <= '0'; line1 <= "00000000"; -- a new addition --elsif clock'event and clock = '1' then elsif rising_edge(clock) then case state is when i0 => if count = 0 then line1 <= "00110000"; pick <= '1'; -- a new addition; sig1(EN) <= '1'; count := 1; elsif count = 50 then -- delay for 4.1 ms state <= i1; count := 0; else sig1(EN) <= '0'; count := count + 1; end if; when i1 => if count = 0 then line1 <= "00110000"; sig1(EN) <= '1'; count := 1; elsif count = 2 then -- delay for 200 us state <= i2; count := 0; else sig1(EN) <= '0'; count := count + 1; end if; when i2 => if count = 0 then line1 <= "00110000"; sig1(EN) <= '1'; count := 1; else count := 0; sig1(EN) <= '0'; state <= i3; end if; when i3 => if count = 0 then line1 <= "00111100"; -- Function Set sig1(EN) <= '1'; count := 1; else count := 0; sig1(EN) <= '0'; state <= i4; end if; when i4 => if count = 0 then line1 <= "00001000"; -- Display Off sig1(EN) <= '1'; count := 1; else count := 0; sig1(EN) <= '0'; state <= i5; end if; when i5 => if count = 0 then line1 <= "00000001"; -- Display Clear sig1(EN) <= '1'; count := 1; elsif count = 17 then -- delay for 200 us state <= i6; count := 0; else sig1(EN) <= '0'; count := count + 1; end if; when i6 => if count = 0 then line1 <= "00000110"; -- Entry Mode Set sig1(EN) <= '1'; count := 1; else count := 0; sig1(EN) <= '0'; state <= i7; end if; when i7 => if count = 0 then line1 <= "00001100"; -- Display ON sig1(EN) <= '1'; count := 1; else count := 0; sig1(EN) <= '0'; state <= s1; end if; when s1 => ready_for_line <= '1'; count := 0; sig1(EN) <= '0'; state <= s2; when s2 => if new_line_request = '1' then ready_for_line <= '0'; line1 <= "10000000"; pick <= '1'; sig1(RS) <= '0'; sig1(RW) <= '0'; sig1(EN) <= '1'; state <= s3; end if; when s2a => sig1(EN) <= '0'; state <= s2b; when s2b => sig1(EN) <= '1'; state <= s2c; when s2c => line1 <= "11000000"; pick <= '1'; sig1(RS) <= '0'; sig1(RW) <= '0'; sig1(EN) <= '0'; state <= s2d; when s2d => sig1(EN) <= '1'; state <= s3; when s3 => byte_request <= '1'; sig1(EN) <= '0'; state <= s4; when s4 => if byte_valid = '1' then byte_request <= '0'; pick <= '0'; sig1(RS) <= '1'; sig1(RW) <= '0'; sig1(EN) <= '1'; if count = 15 then state <= s2a; elsif count = 31 then state <= s1; else state <= s3; end if; count := count + 1; else state <= s4; end if; end case; end if; end process lcd_sm; end architecture behaviour;