OpenCores
URL https://opencores.org/ocsvn/i2c_master_slave/i2c_master_slave/trunk

Subversion Repositories i2c_master_slave

[/] [i2c_master_slave/] [web_uploads/] [i2c_master_v01.vhd] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 vassago057
--
2
-- VHDL Architecture rada_comp_lib.i2c_master_v01.arc
3
--
4
-- Created:
5
--          by - elis@(ELIS-WXP)
6
--          at - 15:30:47 01/03/2009
7
--
8
-- using Mentor Graphics HDL Designer(TM) 2008.1 (Build 17)
9
--
10
LIBRARY ieee;
11
USE ieee.std_logic_1164.all;
12
USE ieee.std_logic_arith.all;
13
 
14
ENTITY i2c_master_v01 IS
15
   GENERIC(
16
      CLK_FREQ : natural := 25000000;
17
      BAUD     : natural := 100000
18
   );
19
   PORT(
20
      --INPUTS
21
      sys_clk    : IN     std_logic;
22
      sys_rst    : IN     std_logic;
23
      start      : IN     std_logic;
24
      stop       : IN     std_logic;
25
      read       : IN     std_logic;
26
      write      : IN     std_logic;
27
      send_ack   : IN     std_logic;
28
      mstr_din   : IN     std_logic_vector (7 DOWNTO 0);
29
      --OUTPUTS
30
      sda        : INOUT  std_logic;
31
      scl        : INOUT  std_logic;
32
      free       : OUT    std_logic;
33
      rec_ack    : OUT    std_logic;
34
      ready      : OUT    std_logic;
35
      core_state : OUT    std_logic_vector (5 DOWNTO 0);  --for debug purpose
36
      mstr_dout  : OUT    std_logic_vector (7 DOWNTO 0)
37
   );
38
 
39
-- Declarations
40
 
41
END i2c_master_v01 ;
42
 
43
--
44
ARCHITECTURE arc OF i2c_master_v01 IS
45
 
46
  constant FRAME     : natural := 11; -- number of bits in frame: start, stop, 8 bits data, 1 bit acknoledge
47
 -- constant BAUD      : natural := 100000;
48
  constant FULL_BIT  : natural := ( CLK_FREQ / BAUD - 1 ) / 2;
49
  constant HALF_BIT  : natural := FULL_BIT / 2;
50
  constant GAP_WIDTH : natural := FULL_BIT * 4;
51
 
52
  signal i_free     : std_logic;
53
  signal i_ready    : std_logic;
54
  signal i_sda_mstr : std_logic;
55
  signal i_scl_mstr : std_logic;
56
  signal i_scl_cntr : natural;
57
  signal i_bit_cntr_mstr : natural range 0 to 7;
58
  signal i_ack_mstr : std_logic;
59
  signal i_mstr_rd_data : std_logic_vector( 7 downto 0 );
60
 
61
  signal i_mstr_ad  : std_logic_vector( 7 downto 0 ); --latched address and data
62
  alias  fld_rd_wr  : std_logic is i_mstr_ad( 0 ); --1 - read, 0 - write
63
 
64
  type i2c_master_state is ( mstr_idle, mstr_start_cnt , mstr_active , mstr_wait_first_half , mstr_wait_second_half ,
65
                             mstr_wait_full , mstr_wait_ack , mstr_wait_ack_second_half , mstr_wait_ack_third_half ,
66
                             mstr_wait_ack_fourth_half , mstr_rd_wait_low , mstr_rd_wait_half , mstr_rd_read , mstr_stop ,
67
                             mstr_rd_wait_ack_bit , mstr_rd_wait_ack , mstr_rd_get_ack , mstr_restart , mstr_gap , mstr_stop_1 ,
68
                             mstr_rd_wait_last_half , mstr_restart_clk_high );
69
 
70
  signal stm_mstr : i2c_master_state;
71
 
72
  signal i_in_state : natural;
73
 
74
BEGIN
75
  sda     <= i_sda_mstr;
76
  scl     <= i_scl_mstr;
77
  free    <= i_free;
78
  ready   <= i_ready;
79
  rec_ack <= not i_ack_mstr;
80
 
81
  core_state <= conv_std_logic_vector( i_in_state , 6 );
82
 
83
  i2c_master:
84
  process( sys_clk , sys_rst )
85
    begin
86
      if ( sys_rst = '1' ) then
87
        stm_mstr   <= mstr_idle;
88
        i_free     <= '0';
89
        i_ready    <= '0';
90
        i_sda_mstr <= 'Z';
91
        i_scl_mstr <= 'Z';
92
        i_scl_cntr <= 0;
93
        i_bit_cntr_mstr <= 7;
94
        i_ack_mstr <= '1';
95
        i_mstr_rd_data <= ( others => '0' );
96
        mstr_dout  <= ( others => '0' );
97
        i_mstr_ad  <= ( others => '0' );
98
        i_in_state <= 0;
99
      elsif rising_edge( sys_clk ) then
100
          case stm_mstr is
101
          -------------------  
102
          when mstr_idle =>
103
            i_free <= '1';
104
            i_ready <= '0';
105
            i_sda_mstr <= 'Z';
106
            i_scl_mstr <= 'Z';
107
            if ( start = '1' ) then
108
              stm_mstr <= mstr_start_cnt;
109
              i_free <= '0';
110
            else
111
              stm_mstr <= mstr_idle;
112
            end if;
113
          -------------------
114
          when mstr_start_cnt =>
115
            i_sda_mstr <= '0';
116
            i_scl_mstr <= '1';
117
            if ( i_scl_cntr < HALF_BIT ) then
118
              i_scl_cntr <= i_scl_cntr + 1;
119
              stm_mstr <= mstr_start_cnt;
120
            else
121
              i_scl_cntr <= 0;
122
              stm_mstr <= mstr_active;
123
              i_scl_mstr <= '0';
124
            end if;
125
          -------------------
126
          when mstr_active =>
127
            i_ready <= '1';
128
            i_scl_mstr <= '0';
129
            i_sda_mstr <= '0';
130
            i_bit_cntr_mstr <= 7;
131
            i_in_state <= 1;
132
            if ( read = '1' ) then
133
              stm_mstr <= mstr_rd_wait_low;
134
              i_ready <= '0';
135
              i_in_state <= 3;
136
            elsif ( write = '1' ) then
137
              i_in_state <= 2;
138
              i_mstr_ad <= mstr_din;
139
              i_ready <= '0';
140
              stm_mstr <= mstr_wait_first_half;
141
            elsif ( stop = '1' ) then
142
              i_in_state <= 4;
143
              i_ready <= '0';
144
              stm_mstr <= mstr_stop_1;
145
            elsif ( start = '1' ) then
146
              i_in_state <= 5;
147
              i_ready <= '0';
148
              stm_mstr <= mstr_restart;
149
            end if;
150
          --------------------
151
          --####################
152
          --##### WRITE ########
153
          --####################
154
          when mstr_wait_first_half =>
155
            if ( i_scl_cntr < HALF_BIT ) then
156
              i_scl_mstr <= '0';
157
              i_scl_cntr <= i_scl_cntr + 1;
158
            else
159
              i_scl_cntr <= 0;
160
              stm_mstr <= mstr_wait_second_half;
161
              i_sda_mstr <= i_mstr_ad( i_bit_cntr_mstr );
162
            end if;
163
          --------------------
164
          when mstr_wait_second_half =>
165
            if ( i_scl_cntr < HALF_BIT ) then
166
              i_scl_cntr <= i_scl_cntr + 1;
167
              stm_mstr <= mstr_wait_second_half;
168
            else
169
              i_scl_cntr <= 0;
170
              stm_mstr <= mstr_wait_full;
171
            end if;
172
          ---------------------
173
          when mstr_wait_full =>
174
            if ( i_scl_cntr < FULL_BIT ) then
175
              i_scl_mstr <= '1';
176
              i_scl_cntr <= i_scl_cntr + 1;
177
              stm_mstr <= mstr_wait_full;
178
            else
179
              i_scl_cntr <= 0;
180
              if ( i_bit_cntr_mstr >= 1 ) then
181
                i_bit_cntr_mstr <= i_bit_cntr_mstr - 1;
182
                stm_mstr <= mstr_wait_first_half;
183
              elsif ( i_bit_cntr_mstr = 0 ) then
184
                --i_sda_mstr <= 'Z';              
185
                stm_mstr <= mstr_wait_ack;
186
              end if;
187
            end if;
188
          --------------------
189
          --####################
190
          --#### ACKNOWLEDGE ###
191
          --####################
192
          when mstr_wait_ack =>
193
            i_scl_mstr <= '0';
194
            if ( i_scl_cntr < HALF_BIT ) then
195
              i_scl_cntr <= i_scl_cntr + 1;
196
            else
197
              i_scl_cntr <= 0;
198
              i_sda_mstr <= 'Z';
199
              stm_mstr <= mstr_wait_ack_second_half;
200
            end if;
201
          --------------------
202
          when mstr_wait_ack_second_half =>
203
            if ( i_scl_cntr < HALF_BIT ) then
204
              i_scl_cntr <= i_scl_cntr + 1;
205
            else
206
              i_scl_cntr <= 0;
207
              i_sda_mstr <= 'Z';
208
              stm_mstr <= mstr_wait_ack_third_half;
209
            end if;
210
          --------------------  
211
          when mstr_wait_ack_third_half =>
212
            i_scl_mstr <= '1';
213
            if ( i_scl_cntr < HALF_BIT ) then
214
              i_scl_cntr <= i_scl_cntr + 1;
215
            else
216
              i_scl_cntr <= 0;
217
              i_sda_mstr <= 'Z';
218
              i_ack_mstr <= to_x01( sda );
219
              stm_mstr <= mstr_wait_ack_fourth_half;
220
            end if;
221
          --------------------
222
          when mstr_wait_ack_fourth_half =>
223
            if ( i_scl_cntr < HALF_BIT ) then
224
              i_scl_cntr <= i_scl_cntr + 1;
225
            else
226
              i_scl_cntr <= 0;
227
              i_sda_mstr <= 'Z';
228
              stm_mstr <= mstr_active;
229
            end if;
230
          --------------------
231
          --####################
232
          --###### READ ########
233
          --####################
234
          when mstr_rd_wait_low =>
235
            i_scl_mstr <= '0';
236
            i_sda_mstr <= 'Z';
237
            if ( i_scl_cntr < FULL_BIT ) then
238
              i_scl_cntr <= i_scl_cntr + 1;
239
              stm_mstr <= mstr_rd_wait_low;
240
            else
241
              i_scl_cntr <= 0;
242
              stm_mstr <= mstr_rd_wait_half;
243
            end if;
244
          --------------------
245
          when mstr_rd_wait_half =>
246
            i_scl_mstr <= '1';
247
            if ( i_scl_cntr < HALF_BIT ) then
248
              i_scl_cntr <= i_scl_cntr + 1;
249
              stm_mstr <= mstr_rd_wait_half;
250
            else
251
              i_scl_cntr <= 0;
252
              i_mstr_rd_data <= i_mstr_rd_data( 6 downto 0 ) & to_x01( sda );
253
              stm_mstr <= mstr_rd_read;
254
            end if;
255
          --------------------- 
256
          when mstr_rd_read =>
257
            i_scl_mstr <= '1';
258
            if ( i_scl_cntr < HALF_BIT ) then
259
              i_scl_cntr <= i_scl_cntr + 1;
260
              stm_mstr <= mstr_rd_read;
261
            else
262
              i_scl_cntr <= 0;
263
              if ( i_bit_cntr_mstr > 0 ) then
264
                i_bit_cntr_mstr <= i_bit_cntr_mstr - 1;
265
                i_scl_mstr <= '0';
266
                stm_mstr <= mstr_rd_wait_low;
267
              else
268
                i_mstr_ad <= ( others => '0' );
269
                mstr_dout <= i_mstr_rd_data;
270
                stm_mstr <= mstr_rd_wait_ack;
271
              end if;
272
            end if;
273
          ---------------------
274
          --#######################
275
          --### SEND ACKNOWELEDGE #
276
          --#######################
277
          when mstr_rd_wait_ack =>
278
            i_scl_mstr <= '0';
279
            if ( i_scl_cntr < HALF_BIT ) then
280
              i_scl_cntr <= i_scl_cntr + 1;
281
              stm_mstr <= mstr_rd_wait_ack;
282
            else
283
              i_scl_cntr <= 0;
284
              i_sda_mstr <= not send_ack;
285
              stm_mstr <= mstr_rd_get_ack;
286
            end if;
287
          ----------------------              
288
          when mstr_rd_get_ack =>
289
            i_scl_mstr <= '0';
290
            if ( i_scl_cntr < HALF_BIT ) then
291
              i_scl_cntr <= i_scl_cntr + 1;
292
              stm_mstr <= mstr_rd_get_ack;
293
            else
294
              i_scl_cntr <= 0;
295
              --i_ack_mstr <= sda;
296
              stm_mstr <= mstr_rd_wait_ack_bit;
297
            end if;
298
          ----------------------
299
          when mstr_rd_wait_ack_bit =>
300
            i_scl_mstr <= '1';
301
            if ( i_scl_cntr < FULL_BIT ) then
302
              i_scl_cntr <= i_scl_cntr + 1;
303
              stm_mstr <= mstr_rd_wait_ack_bit;
304
            else
305
              i_scl_cntr <= 0;
306
              stm_mstr <= mstr_rd_wait_last_half;
307
            end if;
308
          ---------------------- 
309
          when mstr_rd_wait_last_half =>
310
            i_scl_mstr <= '0';
311
            if ( i_scl_cntr < HALF_BIT ) then
312
              i_scl_cntr <= i_scl_cntr + 1;
313
              stm_mstr <= mstr_rd_wait_last_half;
314
            else
315
              i_scl_cntr <= 0;
316
              i_sda_mstr <= 'Z';
317
              stm_mstr <= mstr_active;
318
            end if;
319
          --######################
320
          --######## STOP ########
321
          --###################### 
322
          when mstr_stop_1 =>
323
            i_scl_mstr <= '0';
324
            i_sda_mstr <= '0';
325
            if ( i_scl_cntr < HALF_BIT ) then
326
              i_scl_cntr <= i_scl_cntr + 1;
327
              stm_mstr <= mstr_stop_1;
328
            else
329
              i_scl_cntr <= 0;
330
              stm_mstr <= mstr_stop;
331
            end if;
332
          ----------------------                                     
333
          when mstr_stop =>
334
            i_scl_mstr <= '1';
335
            i_sda_mstr <= '0';
336
            if ( i_scl_cntr < HALF_BIT ) then
337
              i_scl_cntr <= i_scl_cntr + 1;
338
              stm_mstr <= mstr_stop;
339
            else
340
              i_scl_cntr <= 0;
341
              i_sda_mstr <= '1';
342
              stm_mstr <= mstr_gap;
343
            end if;
344
          ---------------------  
345
          when mstr_gap =>
346
            if ( i_scl_cntr < GAP_WIDTH ) then
347
              i_scl_cntr <= i_scl_cntr + 1;
348
              stm_mstr <= mstr_gap;
349
            else
350
              i_scl_cntr <= 0;
351
              i_in_state <= 0;
352
              stm_mstr <= mstr_idle;
353
            end if;
354
          --#####################
355
          --###### RESTART ######        
356
          --#####################
357
          when mstr_restart =>
358
            i_scl_mstr <= '0';
359
            i_sda_mstr <= '1';
360
            i_ready <= '0';
361
            if ( i_scl_cntr < FULL_BIT ) then
362
              i_scl_cntr <= i_scl_cntr + 1;
363
              stm_mstr <= mstr_restart;
364
            else
365
              i_scl_cntr <= 0;
366
              i_sda_mstr <= '1';
367
              stm_mstr <= mstr_restart_clk_high;
368
            end if;
369
          ----------------------
370
          when mstr_restart_clk_high =>
371
            i_scl_mstr <= '1';
372
            i_sda_mstr <= '1';
373
            i_ready <= '0';
374
            if ( i_scl_cntr < HALF_BIT ) then
375
              stm_mstr <= mstr_restart_clk_high;
376
              i_scl_cntr <= i_scl_cntr + 1;
377
            else
378
              i_scl_cntr <= 0;
379
              stm_mstr <= mstr_start_cnt;
380
            end if;
381
          when others => stm_mstr <= mstr_idle;
382
          end case;
383
      end if;
384
    end process i2c_master;
385
END ARCHITECTURE arc;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.