ENTITY lcd_interface IS
--Add Generic
PORT (db : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);
en, rs, rw : OUT STD_LOGIC;
-- clk : IN STD_LOGIC;
lcd_clk_tick : IN STD_LOGIC; -- REMOVE AFTER TESTING
reset : IN STD_LOGIC;
lcd_count_tick_o : OUT STD_LOGIC);
END lcd_interface;
ARCHITECTURE controller OF lcd_interface IS
TYPE STATE_TYPE IS (INIT_0, INIT_1, INIT_2, EN_H, EN_L); -- ADD EN_H??
SIGNAL state, next_state : STATE_TYPE;
SIGNAL i_en : STD_LOGIC;
SIGNAL clk_count, lcd_count : STD_LOGIC_VECTOR (9 DOWNTO 0) := "0000000000";
--SIGNAL lcd_clk_tick : STD_LOGIC;
SIGNAL db_out, db_in : STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
lcd_count_tick_o <= lcd_clk_tick;
en <= i_en;
db <= db_out when i_en = '1' else (OTHERS => 'Z'); -- *FIND OUT IF THIS PART IS CORRECT!!*
db_in <= db;
-- PROCESS (reset, clk)
-- BEGIN
-- IF reset = '0' THEN
-- clk_count <= "0000000000";
-- ELSIF clk'EVENT AND clk = '1' THEN
-- IF clk_count < "1111101000" THEN -- wait 20us (clk_count = 1000)
-- clk_count <= clk_count + 1;
-- lcd_clk_tick <= '0';
-- ELSE
-- clk_count <= (OTHERS => '0');
-- lcd_clk_tick <= '1'; -- generates pulse every 20uS (50kHz)
-- END IF;
-- END IF;
-- END PROCESS;
PROCESS (reset, lcd_clk_tick)
BEGIN
IF reset = '0' THEN
lcd_count <= "0000000000";
db_out <= (OTHERS => '0'); -- data bus
i_en <= '0'; -- en = '1' starts data read/write
rs <= '0'; -- rs = reg select ('0'/'1' = instr_reg(write) / data_reg(read))
rw <= '0'; -- rw' = read/write'
state <= INIT_0;
ELSIF lcd_clk_tick'EVENT AND lcd_clk_tick = '1' THEN
CASE state IS
-- INIT SEQUENCE
WHEN INIT_0 =>
IF lcd_count < "1011101110" THEN -- wait 15ms (lcd_count = 750)
lcd_count <= lcd_count + 1;
ELSE
lcd_count <= (OTHERS => '0');
rs <= '0';
rw <= '0';
db_out <= "00110000";
state <= EN_H; -- rs and rw' need to be stable before en = 'H'
next_state <= INIT_1;
END IF;
WHEN INIT_1 =>
IF lcd_count < "00011010010" THEN -- wait 4.2ms (lcd_count = 210)
lcd_count <= lcd_count + 1;
ELSE
lcd_count <= (OTHERS => '0');
rs <= '0';
rw <= '0';
db_out <= "00110000";
state <= EN_H;
next_state <= INIT_2;
END IF;
WHEN INIT_2 =>
IF lcd_count < "00000000101" THEN -- wait 100us (lcd_count = 5)
lcd_count <= lcd_count + 1;
ELSE
lcd_count <= (OTHERS => '0');
rs <= '0';
rw <= '0';
db_out <= "00110000";
state <= EN_H;
next_state <= INIT_0;
END IF;
-- TRANSFER SEQUENCE -- change enable so it's before?? _/-------\_
WHEN EN_H =>
i_en <= '1';
state <= EN_L;
WHEN EN_L =>
IF lcd_count < "0000000001" THEN -- wait 20us
lcd_count <= lcd_count + 1;
ELSE
lcd_count <= (OTHERS => '0');
i_en <= '0';
state <= next_state;
END IF;
END CASE;
END IF;
END PROCESS;
END controller;