--
|
--
|
--
|
--
|
-- State machine for reading data from Dallas 1621
|
-- State machine for reading data from Dallas 1621
|
--
|
--
|
-- Testsystem for i2c controller
|
-- Testsystem for i2c controller
|
--
|
--
|
--
|
--
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
|
|
use work.i2c.all;
|
use work.i2c.all;
|
|
|
entity DS1621_interface is
|
entity DS1621_interface is
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
nReset : in std_logic;
|
nReset : in std_logic;
|
|
|
Dout : out std_logic_vector(7 downto 0); -- data read from ds1621
|
Dout : out std_logic_vector(7 downto 0); -- data read from ds1621
|
|
|
error : out std_logic; -- no correct ack received
|
error : out std_logic; -- no correct ack received
|
|
|
SCL : inout std_logic;
|
SCL : inout std_logic;
|
SDA : inout std_logic
|
SDA : inout std_logic
|
);
|
);
|
end entity DS1621_interface;
|
end entity DS1621_interface;
|
|
|
architecture structural of DS1621_interface is
|
architecture structural of DS1621_interface is
|
constant SLAVE_ADDR : std_logic_vector(6 downto 0) := "1001000";
|
constant SLAVE_ADDR : std_logic_vector(6 downto 0) := "1001000";
|
constant CLK_CNT : unsigned(7 downto 0) := conv_unsigned(20, 8);
|
constant CLK_CNT : unsigned(7 downto 0) := conv_unsigned(20, 8);
|
|
|
signal cmd_ack : std_logic;
|
signal cmd_ack : std_logic;
|
signal D : std_logic_vector(7 downto 0);
|
signal D : std_logic_vector(7 downto 0);
|
signal lack, store_dout : std_logic;
|
signal lack, store_dout : std_logic;
|
|
|
signal start, read, write, ack, stop : std_logic;
|
signal start, read, write, ack, stop : std_logic;
|
signal i2c_dout : std_logic_vector(7 downto 0);
|
signal i2c_dout : std_logic_vector(7 downto 0);
|
|
|
begin
|
begin
|
-- hookup I2C controller
|
-- hookup I2C controller
|
u1: simple_i2c port map (clk => clk, ena => '1', clk_cnt => clk_cnt, nReset => nReset,
|
u1: simple_i2c port map (clk => clk, ena => '1', clk_cnt => clk_cnt, nReset => nReset,
|
read => read, write => write, start => start, stop => stop, ack_in => ack, cmd_ack => cmd_ack,
|
read => read, write => write, start => start, stop => stop, ack_in => ack, cmd_ack => cmd_ack,
|
Din => D, Dout => i2c_dout, ack_out => lack, SCL => SCL, SDA => SDA);
|
Din => D, Dout => i2c_dout, ack_out => lack, SCL => SCL, SDA => SDA);
|
|
|
init_statemachine : block
|
init_statemachine : block
|
type states is (i1, i2, i3, i4, i5, t1, t2, t3, t4, t5);
|
type states is (i1, i2, i3, i4, i5, t1, t2, t3, t4, t5);
|
signal state : states;
|
signal state : states;
|
begin
|
begin
|
nxt_state_decoder: process(clk, nReset, state)
|
nxt_state_decoder: process(clk, nReset, state)
|
variable nxt_state : states;
|
variable nxt_state : states;
|
variable iD : std_logic_vector(7 downto 0);
|
variable iD : std_logic_vector(7 downto 0);
|
variable ierr : std_logic;
|
variable ierr : std_logic;
|
variable istart, iread, iwrite, iack, istop : std_logic;
|
variable istart, iread, iwrite, iack, istop : std_logic;
|
variable istore_dout : std_logic;
|
variable istore_dout : std_logic;
|
begin
|
begin
|
nxt_state := state;
|
nxt_state := state;
|
ierr := '0';
|
ierr := '0';
|
istore_dout := '0';
|
istore_dout := '0';
|
|
|
istart := start;
|
istart := start;
|
iread := read;
|
iread := read;
|
iwrite := write;
|
iwrite := write;
|
iack := ack;
|
iack := ack;
|
istop := stop;
|
istop := stop;
|
iD := D;
|
iD := D;
|
|
|
case (state) is
|
case (state) is
|
-- init DS1621
|
-- init DS1621
|
-- 1) send start condition
|
-- 1) send start condition
|
-- 2) send slave address + write
|
-- 2) send slave address + write
|
-- 3) check ack
|
-- 3) check ack
|
-- 4) send "access config" command (0xAC)
|
-- 4) send "access config" command (0xAC)
|
-- 5) check ack
|
-- 5) check ack
|
-- 6) send config register data (0x00)
|
-- 6) send config register data (0x00)
|
-- 7) check ack
|
-- 7) check ack
|
-- 8) send stop condition
|
-- 8) send stop condition
|
-- 9) send start condition
|
-- 9) send start condition
|
-- 10) send slave address + write
|
-- 10) send slave address + write
|
-- 11) check ack
|
-- 11) check ack
|
-- 12) send "start conversion" command (0xEE)
|
-- 12) send "start conversion" command (0xEE)
|
-- 13) check ack
|
-- 13) check ack
|
-- 14) send stop condition
|
-- 14) send stop condition
|
|
|
when i1 => -- send start condition, sent slave address + write
|
when i1 => -- send start condition, sent slave address + write
|
nxt_state := i2;
|
nxt_state := i2;
|
istart := '1';
|
istart := '1';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '0';
|
istop := '0';
|
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
|
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
|
|
|
when i2 => -- send "access config" command
|
when i2 => -- send "access config" command
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := i3;
|
nxt_state := i3;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
end if;
|
end if;
|
|
|
istart := '0';
|
istart := '0';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '0';
|
istop := '0';
|
iD := x"AC";
|
iD := x"AC";
|
end if;
|
end if;
|
|
|
when i3 => -- send config register data, sent stop condition
|
when i3 => -- send config register data, sent stop condition
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := i4;
|
nxt_state := i4;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
end if;
|
end if;
|
|
|
istart := '0';
|
istart := '0';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '1';
|
istop := '1';
|
iD := x"00";
|
iD := x"00";
|
end if;
|
end if;
|
|
|
when i4 => -- send start condition, sent slave address + write
|
when i4 => -- send start condition, sent slave address + write
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := i5;
|
nxt_state := i5;
|
|
|
istart := '1';
|
istart := '1';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '0';
|
istop := '0';
|
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
|
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
|
end if;
|
end if;
|
|
|
when i5 => -- send "start conversion" command + stop condition
|
when i5 => -- send "start conversion" command + stop condition
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := t1;
|
nxt_state := t1;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
end if;
|
end if;
|
|
|
istart := '0';
|
istart := '0';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '1';
|
istop := '1';
|
iD := x"EE";
|
iD := x"EE";
|
end if;
|
end if;
|
-- read temperature
|
-- read temperature
|
-- 1) sent start condition
|
-- 1) sent start condition
|
-- 2) sent slave address + write
|
-- 2) sent slave address + write
|
-- 3) check ack
|
-- 3) check ack
|
-- 4) sent "read temperature" command (0xAA)
|
-- 4) sent "read temperature" command (0xAA)
|
-- 5) check ack
|
-- 5) check ack
|
-- 6) sent start condition
|
-- 6) sent start condition
|
-- 7) sent slave address + read
|
-- 7) sent slave address + read
|
-- 8) check ack
|
-- 8) check ack
|
-- 9) read msb
|
-- 9) read msb
|
-- 10) send ack
|
-- 10) send ack
|
-- 11) read lsb
|
-- 11) read lsb
|
-- 12) send nack
|
-- 12) send nack
|
-- 13) send stop condition
|
-- 13) send stop condition
|
|
|
when t1 => -- send start condition, sent slave address + write
|
when t1 => -- send start condition, sent slave address + write
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := t2;
|
nxt_state := t2;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
end if;
|
end if;
|
|
|
istart := '1';
|
istart := '1';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '0';
|
istop := '0';
|
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
|
iD := (slave_addr & '0'); -- write to slave (R/W = '0')
|
end if;
|
end if;
|
|
|
when t2 => -- send read temperature command
|
when t2 => -- send read temperature command
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := t3;
|
nxt_state := t3;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
end if;
|
end if;
|
|
|
istart := '0';
|
istart := '0';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '0';
|
istop := '0';
|
iD := x"AA";
|
iD := x"AA";
|
end if;
|
end if;
|
|
|
when t3 => -- send (repeated) start condition, send slave address + read
|
when t3 => -- send (repeated) start condition, send slave address + read
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := t4;
|
nxt_state := t4;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received, expected ACK
|
ierr := '1'; -- no acknowledge received, expected ACK
|
end if;
|
end if;
|
|
|
istart := '1';
|
istart := '1';
|
iread := '0';
|
iread := '0';
|
iwrite := '1';
|
iwrite := '1';
|
iack := '0';
|
iack := '0';
|
istop := '0';
|
istop := '0';
|
iD := (slave_addr & '1'); -- read from slave (R/W = '1')
|
iD := (slave_addr & '1'); -- read from slave (R/W = '1')
|
end if;
|
end if;
|
|
|
when t4 => -- read MSB (hi-byte), send acknowledge
|
when t4 => -- read MSB (hi-byte), send acknowledge
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := t5;
|
nxt_state := t5;
|
-- check aknowledge bit
|
-- check aknowledge bit
|
if (lack = '1') then
|
if (lack = '1') then
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
ierr := '1'; -- no acknowledge received from last command, expected ACK
|
end if;
|
end if;
|
|
|
istart := '0';
|
istart := '0';
|
iread := '1';
|
iread := '1';
|
iwrite := '0';
|
iwrite := '0';
|
iack := '0'; --ACK
|
iack := '0'; --ACK
|
istop := '0';
|
istop := '0';
|
end if;
|
end if;
|
|
|
when t5 => -- read LSB (lo-byte), send acknowledge, sent stop
|
when t5 => -- read LSB (lo-byte), send acknowledge, sent stop
|
if (cmd_ack = '1') then
|
if (cmd_ack = '1') then
|
nxt_state := t1;
|
nxt_state := t1;
|
|
|
istart := '0';
|
istart := '0';
|
iread := '1';
|
iread := '1';
|
iwrite := '0';
|
iwrite := '0';
|
iack := '1'; --NACK
|
iack := '1'; --NACK
|
istop := '1';
|
istop := '1';
|
|
|
istore_dout := '1';
|
istore_dout := '1';
|
end if;
|
end if;
|
end case;
|
end case;
|
|
|
-- genregs
|
-- genregs
|
if (nReset = '0') then
|
if (nReset = '0') then
|
state <= i1;
|
state <= i1;
|
error <= '0';
|
error <= '0';
|
store_dout <= '0';
|
store_dout <= '0';
|
|
|
start <= '0';
|
start <= '0';
|
read <= '0';
|
read <= '0';
|
write <= '0';
|
write <= '0';
|
ack <= '0';
|
ack <= '0';
|
stop <= '0';
|
stop <= '0';
|
D <= (others => '0');
|
D <= (others => '0');
|
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
state <= nxt_state;
|
state <= nxt_state;
|
error <= ierr;
|
error <= ierr;
|
store_dout <= istore_dout;
|
store_dout <= istore_dout;
|
|
|
start <= istart;
|
start <= istart;
|
read <= iread;
|
read <= iread;
|
write <= iwrite;
|
write <= iwrite;
|
ack <= iack;
|
ack <= iack;
|
stop <= istop;
|
stop <= istop;
|
D <= iD;
|
D <= iD;
|
end if;
|
end if;
|
end process nxt_state_decoder;
|
end process nxt_state_decoder;
|
end block init_statemachine;
|
end block init_statemachine;
|
|
|
-- store temp
|
-- store temp
|
gen_dout : process(clk)
|
gen_dout : process(clk)
|
begin
|
begin
|
if (clk'event and clk = '1') then
|
if (clk'event and clk = '1') then
|
if (store_dout = '1') then
|
if (store_dout = '1') then
|
Dout <= i2c_dout;
|
Dout <= i2c_dout;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process gen_dout;
|
end process gen_dout;
|
|
|
end architecture structural;
|
end architecture structural;
|
|
|
|
|
|
|