daisyzari
Junior Member level 3
**broken link removed**
I just want to ask in concern with the above waveform and code why the i6 state under state_write is not included in the waveform. Also I want to ask why the start and stop after the fifth state is both high.
Code:
-- Simple I2C controller
--
-- 1) No multimaster
-- 2) No slave mode
-- 3) No fifo's
--
-- notes:
-- Every command is acknowledged. Do not set a new command before previous is acknowledged.
-- Dout is available 1 clock cycle later as cmd_ack
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
--for easier access
package I2C is
component i2c_statemachine is
port (
clk : in std_logic;
ena : in std_logic;
nReset : in std_logic;
clk_cnt : in unsigned(7 downto 0); -- 4x SCL
-- input signals
start,
stop,
RDRF,
TDRE,
ack_in : std_logic;
Din : in std_logic_vector(7 downto 0);
-- output signals
cmd_ack : out std_logic;
ack_out : out std_logic;
Dout : out std_logic_vector(7 downto 0);
-- i2c signals
SCL : inout std_logic;
SDA : inout std_logic
);
end component i2c_statemachine;
end package I2C;
--
--
-- State machine for reading data from Dallas 1621
--
-- Testsystem for i2c controller
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.i2c.all;
entity EEPROM_interface is
port (
clk : in std_logic;
nReset : in std_logic;
-- data from EEPROM
Dprom : out std_logic_vector(7 downto 0); -- out from interface; in to i2c
error : out std_logic; -- no correct ack received
SCL : inout std_logic;
SDA : inout std_logic
);
end entity EEPROM_interface;
architecture structural of EEPROM_interface is
constant SLAVE_ADDR : std_logic_vector(6 downto 0) := "1010001";
constant PROM_HBYT : std_logic_vector(7 downto 0) := "00000000";
constant PROM_LBYT : std_logic_vector(7 downto 0) := "11111111";
constant CLK_CNT : unsigned(7 downto 0) := conv_unsigned(100, 8); --28 binary
signal cmd_ack : std_logic;
signal D : std_logic_vector(7 downto 0);
signal lack : std_logic;
signal start, RDRF, TDRE, ack, stop : std_logic;
signal i2c_dout : std_logic_vector(7 downto 0);
begin
-- instantiate to i2c_statemachine
u1: i2c_statemachine port map (clk => clk, ena => '1', clk_cnt => clk_cnt, nReset => nReset,
RDRF => RDRF, TDRE => TDRE, start => start, stop => stop, ack_in => ack, cmd_ack => cmd_ack,
Din => D, Dout => i2c_dout, ack_out => lack, SCL => SCL, SDA => SDA);
interface : block -- grouping,organizing
type states_w is (i1, i2, i3, i4, i5, i6);
type states_r is (t1, t2, t3, t4, t5, t6);
type states_all is (a1, a2);
signal state_write : states_w;
signal state_read : states_r;
signal state_all : states_all;
begin
state_decoder: process(clk, nReset, state_write, state_read, state_all)
variable nxt_state_w : states_w;
variable nxt_state_r : states_r;
variable nxt_state_all : states_all;
variable iD : std_logic_vector(7 downto 0);
variable ierr : std_logic;
variable istart, iread, iwrite, iack, istop : std_logic;
--variable istore_dout : std_logic;
begin
nxt_state_w := state_write;
nxt_state_r := state_read;
nxt_state_all := state_all;
ierr := '0';
istart := start;
iread := RDRF;
iwrite := TDRE;
iack := ack;
istop := stop;
iD := D;
case (state_all) is
when a1 => --write
case (state_write) is
-- init EEPROM
-- 1) send start condition
-- 2) send slave address + wbit
-- 3) check ack
-- 4) send slave address + wbit
-- 5) check ack
-- 6) send PROM highbit
-- 7) check ack
-- 6) send config register data (0x00)
-- 7) check ack
-- send stop condition
-- 9) send start condition
-- 10) send slave address + write
-- 11) check ack
-- 12) send "start conversion" command (0xEE)
-- 13) check ack
-- 14) send stop condition
when i1 => -- send start condition, sent slave address + write
istart := '1';
iread := '0';
iwrite := '1';
iack := '0'; -- means acknowledged
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
istop := '1';
nxt_state_w := i2;
when i2 => -- send start condition, sent slave address + write
if (cmd_ack = '1') then
nxt_state_w := i3;
-- check aknowledge bit
if (lack = '1') then
ierr := '1'; -- no acknowledge received from last command, expected ACK
end if;
istart := '1';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
end if;
-- send PROM highbit
when i3 =>
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1'; -- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := PROM_HBYT;
nxt_state_w := i4;
end if;
-- send PROM lowbit
when i4 =>
if (cmd_ack = '1') then
nxt_state_w := i5;
-- check aknowledge bit
if (lack = '1') then
ierr := '1';
-- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := PROM_LBYT;
end if;
when i5 => -- send PROM lowbit
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1';
-- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := x"0F";
nxt_state_w := i6;
end if;
when i6=> -- send PROM lowbit
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1';
-- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '0';
iwrite := '1';
iack := '0';
istop := '1';
iD := x"00";
nxt_state_all := a2;
end if;
end case;
-- read temperature
-- 1) sent start condition
-- 2) sent slave address + write
-- 3) check ack
-- 4) sent "read temperature" command (0xAA)
-- 5) check ack
-- 6) sent start condition
-- 7) sent slave address + read
-- check ack
-- 9) read msb
-- 10) send ack
-- 11) read lsb
-- 12) send nack
-- 13) send stop condition
when a2 => -- read
case(state_read) is
when t1 => -- send start condition, sent slave address + write
istart := '1';
iread := '0';
iwrite := '0';
iack := '0'; -- means acknowledged
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
istop := '1';
nxt_state_r := t2;
when t2 => -- send start condition, sent slave address + write
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1'; -- no acknowledge received from last command, expected ACK
end if;
istart := '1';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
nxt_state_r := t3;
end if;
when t3 => -- send PROM highbit
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1'; -- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := PROM_HBYT;
nxt_state_r := t4;
end if;
when t4 => -- send PROM lowbit
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1';
-- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := PROM_LBYT;
nxt_state_r := t5;
end if;
when t5 => -- send (repeated) start condition, send slave address + read
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1'; -- no acknowledge received, expected ACK
end if;
istart := '1';
iread := '0';
iwrite := '1';
iack := '0';
istop := '0';
iD := (slave_addr & '1'); -- read from slave (R/W = '1')
nxt_state_r := t6;
end if;
when t6 => -- read MSB (hi-byte), send acknowledge
if (cmd_ack = '1') then
-- check aknowledge bit
if (lack = '1') then
ierr := '1'; -- no acknowledge received from last command, expected ACK
end if;
istart := '0';
iread := '1';
iwrite := '0';
iack := '1'; --NACK
istop := '1';
nxt_state_all := a1;
end if;
end case;
end case;
-- genregs
if (nReset = '0') then
state_all <= a1;
state_write <=i1;
state_read <=t1;
error <= '0';
start <= '0';
RDRF <= '0';
TDRE <= '0';
ack <= '0';
stop <= '0';
D <= (others => '0');
elsif (clk'event and clk = '1') then
state_all <= nxt_state_all;
state_write <= nxt_state_w;
state_read <= nxt_state_r;
error <= ierr;
start <= istart;
RDRF <= iread;
TDRE <= iwrite;
ack <= iack;
stop <= istop;
D <= iD;
end if;
end process state_decoder;
end block interface;
end architecture structural;
I just want to ask in concern with the above waveform and code why the i6 state under state_write is not included in the waveform. Also I want to ask why the start and stop after the fifth state is both high.