Hi Guys, I need suggestion from you, I have written code for I2C read and write, But i don't know i how can test the code on Cyclone ii ep2c20484c7 board. I tried to set up a eeprom ic on bread board. In that set up i am not able to identify whether the READ or WRITE are happened or not. Please give me a suggestion to test my code. Buying an I2C slave device is a last option for me. So suggest me something else. Thanks & Regards, Hareesh.
Hareesh M. wrote: > Please give me a suggestion to test my code. First step is to setup a simulation without any hardware. When this is working you can turn over to real life... > In that set up i am not able to identify whether the READ or WRITE are > happened or not. How did you find that out? What does the logic analyzer say? Does the timing on that look OK?
Lothar M. wrote: > Hareesh M. wrote: >> Please give me a suggestion to test my code. > First step is to setup a simulation without any hardware. When this is > working you can turn over to real life... when i simulated the code in modelsim the waveforms looked fine. > >> In that set up i am not able to identify whether the READ or WRITE are >> happened or not. > How did you find that out? What does the logic analyzer say? Does the > timing on that look OK? But to verify the waveform i need to get the ack from slave right? i have attached the modelsim waveform for your reference. It is write operation Slave address: 0X53 Data : 0XAA
:
Edited by User
Hareesh M. wrote: > But to verify the waveform i need to get the ack from slave right? No. Then you will see the master sending the first bits and you will also see how the slave responds (is there an ACK or not?). And even so you will see, whether the bus timing is correct or not. BTW: your SDA line seems to change at the very same time with the SCL falling edge. Better would be to keep the SDA stable a little bit longer than SCL, so changes in SDA occur only while SCL is low. See there chapter 2.3.1: http://www.ti.com/lit/an/scaa106/scaa106.pdf And overall see the I2C spec: https://www.nxp.com/docs/en/user-guide/UM10204.pdf
:
Edited by Moderator
Lothar M. wrote: > Hareesh M. wrote: >> But to verify the waveform i need to get the ack from slave right? > No. Then you will see the master sending the first bits and you will > also see how the slave responds (is there an ACK or not?). And even so > you will see, whether the bus timing is correct or not. > > BTW: your SDA line seems to change at the very same time with the SCL > falling edge. Better would be to keep the SDA stable a little bit longer > than SCL, so changes in SDA occur only while SCL is low. i got your point, but the thing is im using case statement for fsm. I am not getting the idea for that. > See there chapter 2.3.1: > http://www.ti.com/lit/an/scaa106/scaa106.pdf > And overall see the I2C spec: > https://www.nxp.com/docs/en/user-guide/UM10204.pdf
Hareesh M. wrote: > i got your point, but the thing is im using case statement for fsm. So simply add one state for that falling edge of SCL while SDA stays stable.
Lothar M. wrote: > Hareesh M. wrote: >> i got your point, but the thing is im using case statement for fsm. > So simply add one state for that falling edge of SCL while SDA stays > stable. I have updated the code as per your suggestion.
Whats that attachment? Pls attach a VHDL file. Or severeal VHDL files. But no zip file or whatsoever.
:
Edited by Moderator
Lothar M. wrote: > Whats that attachment? > Pls attach a VHDL file. Or severeal VHDL files. But no zip file or > whatsoever.
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; |
Hareesh M. wrote: > I have updated the code as per your suggestion. Ok, and now? How does the waveform look like? Whats the problem with it? Hareesh M. wrote: > Lothar M. wrote: >> Pls attach a VHDL file. Hmpf.... you know, what "to attach" means?
:
Edited by Moderator
Lothar M. wrote: > Hareesh M. wrote: >> I have updated the code as per your suggestion. > Ok, and now? How does the waveform look like? Whats the problem with it? > > Hareesh M. wrote: >> Lothar M. wrote: >>> Pls attach a VHDL file. > Hmpf.... you know, what "to attach" means? Sorry, I have attached the vhdl file.
Hareesh M. wrote: > Lothar M. wrote: >> Hareesh M. wrote: >>> I have updated the code as per your suggestion. >> Ok, and now? How does the waveform look like? Whats the problem with it? >> But the thing is, I have a 265Kbit EEPROM. So to write something into it we need to give byte address. If i add that in my code also, the will become very large.
Hareesh M. wrote: > Sorry, I have attached the vhdl file. This is no VHDL file because it has no *.VHD or *.VHDL extension. See the difference between your attachment and mine... Hareesh M. wrote: > If i add that in my code also, the will become very large. Indeed. But whats the problem with that? This ist NOT a proper way to generate a clock on a FPGA:
1 | if(speed_counter=125)then |
2 | i2c_tic <= not(i2c_tic); |
Use a clock manager or much better: use a clock enable instead! Best way for a beginner is to have only 1 clock throughout the whole design.
1 | -- clock divider to generate clock enable for I2C
|
2 | process(i_inclk) |
3 | begin
|
4 | if rising_edge(i_inclk) then -- the one and only clock |
5 | if speed_counter=249 then |
6 | speed_counter <= 0; |
7 | i2c_tic_enable <= '1'; |
8 | else
|
9 | speed_counter <= speed_counter+1; |
10 | i2c_tic_enable <= '0'; |
11 | end if; |
12 | end if; |
13 | end process; |
14 | |
15 | |
16 | start_bit <= i2c_tic; |
17 | |
18 | process(i_inclk) |
19 | begin
|
20 | if rising_edge(i_inclk) then -- the one and only clock |
21 | if i2c_tic_enable <= '1' then -- this is the I2C clock enable |
22 | case i2c_state is |
23 | :
|
24 | :
|
And also you have the usual "off by one" problem: your prescaler divides by 252, not like you want by 250! Because from 0 to 125 there are 126 clock cycles.
:
Edited by Moderator
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.