1 | Library ieee;
|
2 | use ieee.std_logic_1164.all;
|
3 | use ieee.std_logic_arith.all;
|
4 | --use ieee.numeric_std.all;
|
5 |
|
6 | entity i2c_read_write is
|
7 |
|
8 | generic (
|
9 | address : std_logic_vector(0 to 7):="10100110";
|
10 | data : std_logic_vector(0 to 7):="10101010"
|
11 |
|
12 | );
|
13 |
|
14 | port(
|
15 | i_inclk : in std_logic; --Input clock 50mhz
|
16 | i_reset : in std_logic; --Reset
|
17 |
|
18 | start_bit : out std_logic;
|
19 | ledred : out std_logic_vector(7 downto 0):=(others =>'0');
|
20 |
|
21 | o_scl : out std_logic; --I2C SCL line
|
22 | io_sda : inout std_logic:='Z' --I2C SDA line
|
23 |
|
24 | );
|
25 | end i2c_read_write;
|
26 |
|
27 | architecture model of i2c_read_write is
|
28 |
|
29 | type states is(i2c_idle,i2c_start,i2c_sendaddress,i2c_sendaddress_0,i2c_sendaddress_1,i2c_addressack,i2c_addressack_0,i2c_addressack_1,i2c_data,i2c_senddata,i2c_senddata_0,i2c_dataack,i2c_dataack_0,i2c_dataack_1,i2c_dataack_2,i2c_stop,i2c_stop_0,i2c_stop_1,i2c_stop_2,i2c_stop_3);
|
30 | signal i2c_state : states:=i2c_idle;
|
31 |
|
32 | signal scl_line : std_logic;
|
33 | signal sda_line : std_logic;
|
34 |
|
35 | signal slave_address : std_logic_vector(0 to 7):=(others =>'0');
|
36 |
|
37 | signal data_bytes : std_logic_vector(0 to 7):=(others =>'0');
|
38 |
|
39 | signal index_address : integer range 0 to 7:=0;
|
40 | signal index_data : integer range 0 to 7:=0;
|
41 |
|
42 | signal speed_counter : integer:=0;
|
43 |
|
44 | signal i2c_tic : std_logic:='1';
|
45 |
|
46 | signal stop_bit : std_logic:='0';
|
47 |
|
48 | signal slaveack : std_logic:='1';
|
49 | signal dataack : std_logic:='1';
|
50 |
|
51 |
|
52 |
|
53 | begin
|
54 |
|
55 |
|
56 |
|
57 | slave_address <= address;
|
58 | data_bytes <= data;
|
59 |
|
60 | process(i_inclk)
|
61 | begin
|
62 | if(rising_edge(i_inclk))then
|
63 | if(speed_counter=125)then
|
64 | speed_counter <= 0;
|
65 | i2c_tic <= not(i2c_tic);
|
66 | else
|
67 | speed_counter <= speed_counter+1;
|
68 | end if;
|
69 | end if;
|
70 | end process;
|
71 |
|
72 |
|
73 | start_bit <= i2c_tic;
|
74 |
|
75 | process(i2c_tic,i_reset)
|
76 | begin
|
77 | if(rising_edge(i2c_tic))then
|
78 |
|
79 | case i2c_state is
|
80 |
|
81 | when i2c_idle => --Idle
|
82 | scl_line <= '1';
|
83 |
|
84 | sda_line <= '1';
|
85 | i2c_state <= i2c_start;
|
86 |
|
87 | when i2c_start => --Start
|
88 | if(stop_bit='0')then
|
89 | scl_line <= '1';
|
90 | sda_line <= '0';
|
91 | i2c_state <= i2c_sendaddress;
|
92 | else
|
93 | i2c_state <= i2c_idle;
|
94 | end if;
|
95 |
|
96 | when i2c_sendaddress => --Slave address
|
97 | scl_line <= '0';
|
98 | i2c_state <= i2c_sendaddress_0;
|
99 |
|
100 | when i2c_sendaddress_0 => --8 bit address transmission
|
101 | scl_line <= '0';
|
102 | sda_line <= slave_address(index_address);
|
103 | i2c_state <= i2c_sendaddress_1;
|
104 |
|
105 | when i2c_sendaddress_1 =>
|
106 | scl_line <= '1';
|
107 |
|
108 | sda_line <= slave_address(index_address);
|
109 | if(index_address<7)then
|
110 | index_address <= index_address+1;
|
111 | i2c_state <= i2c_sendaddress;
|
112 | else
|
113 | index_address <= 0;
|
114 | i2c_state <= i2c_addressack;
|
115 | end if;
|
116 |
|
117 | when i2c_addressack => --Slave address acknoweldgement
|
118 | scl_line <= '0';
|
119 | i2c_state <= i2c_addressack_0;
|
120 |
|
121 | when i2c_addressack_0 =>
|
122 | scl_line <= '0';
|
123 |
|
124 | slaveack <= sda_line;
|
125 | i2c_state <= i2c_addressack_1;
|
126 |
|
127 | when i2c_addressack_1 =>
|
128 | scl_line <= '1';
|
129 | if(slaveack = '0')then
|
130 | i2c_state <= i2c_data;
|
131 | else
|
132 | i2c_state <= i2c_stop;
|
133 | end if;
|
134 |
|
135 | when i2c_data => --Data transmission starts
|
136 | scl_line <= '0';
|
137 | i2c_state <= i2c_senddata_0;
|
138 |
|
139 | when i2c_senddata_0 =>
|
140 | scl_line <= '0';
|
141 | sda_line <= data_bytes(index_data);
|
142 | i2c_state <= i2c_senddata;
|
143 |
|
144 | when i2c_senddata => --Transmitting 8 bit data
|
145 | scl_line <= '1';
|
146 |
|
147 | if(index_data<7)then
|
148 | index_data <= index_data+1;
|
149 | i2c_state <= i2c_data;
|
150 | else
|
151 | index_data <= 0;
|
152 | i2c_state <= i2c_dataack_0;
|
153 | end if;
|
154 |
|
155 | when i2c_dataack_0 => --Data acknoweldgement
|
156 | scl_line <= '0';
|
157 | i2c_state <= i2c_dataack_1;
|
158 |
|
159 | when i2c_dataack_1 =>
|
160 | scl_line <= '0';
|
161 |
|
162 | dataack <= sda_line;
|
163 | i2c_state <= i2c_dataack_2;
|
164 |
|
165 | when i2c_dataack_2 =>
|
166 | scl_line <= '1';
|
167 |
|
168 | if(dataack = '0')then
|
169 | i2c_state <= i2c_stop;
|
170 | else
|
171 | i2c_state <= i2c_stop;
|
172 | end if;
|
173 |
|
174 | when i2c_stop => --Stop bit
|
175 | scl_line <= '0';
|
176 | i2c_state <= i2c_stop_0;
|
177 |
|
178 | when i2c_stop_0 =>
|
179 | scl_line <= '0';
|
180 | sda_line <= '0';
|
181 | i2c_state <= i2c_stop_1;
|
182 |
|
183 | when i2c_stop_1 =>
|
184 | scl_line <= '0';
|
185 | i2c_state <= i2c_stop_2;
|
186 |
|
187 | when i2c_stop_2 =>
|
188 | scl_line <= '1';
|
189 | i2c_state <= i2c_stop_3;
|
190 |
|
191 | when i2c_stop_3 =>
|
192 | sda_line <= '1';
|
193 | stop_bit <= '1';
|
194 | stop_bit <= '1';
|
195 | i2c_state <= i2c_idle;
|
196 |
|
197 | when others =>
|
198 | i2c_state <= i2c_idle;
|
199 |
|
200 | end case;
|
201 |
|
202 | end if;
|
203 | end process;
|
204 |
|
205 | o_scl <= scl_line;
|
206 | io_sda <= 'Z' when sda_line='1' else '0';
|
207 |
|
208 | ledred <= data_bytes;
|
209 |
|
210 | end model;
|