EmbDev.net

Forum: FPGA, VHDL & Verilog Testing I2C on cyclone 2 board


von Hareesh M. (Company: Mindteck) (hareeshp)


Rate this post
useful
not useful
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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?

von Hareesh M. (Company: Mindteck) (hareeshp)


Attached files:

Rate this post
useful
not useful
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
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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
von Hareesh M. (Company: Mindteck) (hareeshp)


Rate this post
useful
not useful
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

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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.

von Hareesh M. (Company: Mindteck) (hareeshp)


Attached files:

Rate this post
useful
not useful
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Whats that attachment?
Pls attach a VHDL file. Or severeal VHDL files. But no zip file or 
whatsoever.

: Edited by Moderator
von Hareesh M. (Company: Mindteck) (hareeshp)


Rate this post
useful
not useful
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;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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
von Hareesh M. (Company: Mindteck) (hareeshp)


Attached files:

Rate this post
useful
not useful
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.

von Hareesh M. (Company: Mindteck) (hareeshp)


Rate this post
useful
not useful
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Attached files:

Rate this post
useful
not useful
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
No account? Register here.