- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a Cyclone V GT Dev Kit, and I'm trying to play around with the LCD screen. I'm programming the board via JTAG and using the I2C protocol for the LCD screen. Here is my code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity LCD_1 is
port (
dsw : in std_logic;
clk_50M : in std_logic;
i2c_scl : out std_logic;
i2c_sda : inout std_logic
);
end entity;
architecture Behavioral of LCD_1 is
signal clk_5M : std_logic;
signal clk_50k : std_logic := '0';
signal sig_i2c_scl : std_logic := '1';
signal sig_i2c_sda : std_logic := '1';
signal routine : std_logic := '0';
signal ack : std_logic := '0';
signal ack_returned : std_logic := '0';
signal bounce : std_logic := '0';
signal data : std_logic_vector (7 downto 0);
signal prefix : std_logic_vector (7 downto 0) := x"FE";
signal command : std_logic_vector (7 downto 0) := x"70";
begin
process(clk_50M)
variable count : integer range 0 to 1000;
begin
if rising_edge(clk_50M) then
case count is
when 1000 => clk_50k <= not clk_50k;
count := 0;
when others => count := count + 1;
end case;
end if;
end process;
process(clk_50M)
variable state : integer range 0 to 1000;
begin
if rising_edge(clk_50M) then
if dsw = '0' then
case state is
when 1000 => bounce <= '1';
when others => state := state + 1;
end case;
else
bounce <= '0';
state := 0;
end if;
end if;
end process;
data <= prefix when routine = '0' else command;
i2c_scl <= sig_i2c_scl;
i2c_sda <= sig_i2c_sda when ack <= '0' else 'Z';
ack_returned <= i2c_sda;
process(clk_50k, bounce)
variable state : integer range 0 to 11;
variable index : integer range 7 downto 0;
begin
if rising_edge(clk_50k) then
if bounce = '1' then
case state is
when 0 => sig_i2c_sda <= '0';
state := 1;
when 1 => sig_i2c_scl <= '0';
state := 2;
when 2 => sig_i2c_sda <= data(index);
state := 3;
when 3 => sig_i2c_scl <= '1';
if index = 0 then
state := 5;
else
state := 4;
end if;
when 4 => index := index - 1;
state := 1;
when 5 => index := 7;
state := 6;
when 6 => sig_i2c_scl <= '0';
state := 7;
when 7 => ack <= '1';
state := 8;
when 8 => sig_i2c_scl <= '1';
state := 9;
when 9 => state := 10;
when 10 => sig_i2c_scl <= '0';
if ack_returned = '0' then
state := 2;
elsif routine = '0' then
routine <= '1';
else
state := 11;
end if;
ack <= '0';
when 11 => sig_i2c_sda <= '1';
end case;
else
sig_i2c_scl <= '1';
sig_i2c_sda <= '1';
state := 0;
ack <= '0';
routine <= '0';
index := 7;
end if;
end if;
end process;
end Behavioral;
This is the first time I'm using I2C so I might be doing it wrong. But from what I gather SDA drops from high to low. Then SCL drops from high to low. SCL cycles with SDA updated on the low sides of SCL. First an 8 bit address is transmitted then SDA receives an acknowledge bit from the controller. If the acknowledge bit is not sent then the 8 bit address has to be re-transmitted. But if the acknowledge bit is received. Then transmit a 8 bit command to the controller and wait for the acknowledge bit again. Then when SCL is high make SDA high to terminate the transmission.
I have verified this cycle on modelsim and signal tap, but nothing happens with LCD screen so I'm doing something wrong. Can anybody help me?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi DTruj13,
Have you find the solution for this?
If Yes, could you share the solution to community here?
Thanks
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page