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

Subversion Repositories iicmb

[/] [iicmb/] [trunk/] [src/] [bus_state.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sshuv2
 
2
--==============================================================================
3
--                                                                             |
4
--    Project: IIC Multiple Bus Controller (IICMB)                             |
5
--                                                                             |
6
--    Module:  I2C Bus busy state monitoring.                                  |
7
--    Version:                                                                 |
8
--             1.0,   April 29, 2016                                           |
9
--                                                                             |
10
--    Author:  Sergey Shuvalkin, (sshuv2@opencores.org)                        |
11
--                                                                             |
12
--==============================================================================
13
--==============================================================================
14
-- Copyright (c) 2016, Sergey Shuvalkin                                        |
15
-- All rights reserved.                                                        |
16
--                                                                             |
17
-- Redistribution and use in source and binary forms, with or without          |
18
-- modification, are permitted provided that the following conditions are met: |
19
--                                                                             |
20
-- 1. Redistributions of source code must retain the above copyright notice,   |
21
--    this list of conditions and the following disclaimer.                    |
22
-- 2. Redistributions in binary form must reproduce the above copyright        |
23
--    notice, this list of conditions and the following disclaimer in the      |
24
--    documentation and/or other materials provided with the distribution.     |
25
--                                                                             |
26
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
27
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   |
28
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  |
29
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE    |
30
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         |
31
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        |
32
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    |
33
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     |
34
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     |
35
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  |
36
-- POSSIBILITY OF SUCH DAMAGE.                                                 |
37
--==============================================================================
38
 
39
 
40
library ieee;
41
use ieee.std_logic_1164.all;
42
 
43
 
44
--==============================================================================
45
entity bus_state is
46
  generic
47
  (
48
    g_f_clk   :       real     := 100000.0;  -- Frequency of 'clk' input (in kHz)
49
    g_f_scl   :       real     :=    100.0   -- Frequency of 'scl' input (in kHz)
50
  );
51
  port
52
  (
53
    ------------------------------------
54
    clk       : in    std_logic;             -- Clock
55
    s_rst     : in    std_logic;             -- Synchronous reset (active high)
56
    ------------------------------------
57
    ------------------------------------
58
    busy      :   out std_logic;             -- Bus busy indication (busy = high)
59
    scl_d     :   out std_logic;             -- Delayed I2C Clock signal
60
    ------------------------------------
61
    ------------------------------------
62
    -- Filtered I2C bus signals:
63
    scl       : in    std_logic;             -- I2C Clock input
64
    sda       : in    std_logic              -- I2C Data input
65
    ------------------------------------
66
  );
67
end entity bus_state;
68
--==============================================================================
69
 
70
--==============================================================================
71
architecture rtl of bus_state is
72
 
73
  ------------------------------------------------------------------------------
74
  function get_t_buf(a : real) return real is
75
  begin
76
    if (a <= 100.0) then
77
      return 4.7;
78
    else
79
      return 1.3;
80
    end if;
81
  end function get_t_buf;
82
  ------------------------------------------------------------------------------
83
 
84
  constant c_t_buf         : real    := get_t_buf(g_f_scl); -- in microseconds
85
  constant c_t_buf_cnt     : integer := integer((g_f_clk*(c_t_buf/1000.0)) + 0.4999); -- in 'clk' cycles
86
  constant c_max_cnt       : integer := c_t_buf_cnt;
87
 
88
  signal   scl_d_y         : std_logic                    := '1';
89
  signal   scl_y           : std_logic;
90
  signal   sda_d_y         : std_logic                    := '1';
91
  signal   sda_y           : std_logic;
92
 
93
  signal   sda_cnt         : integer range 0 to c_max_cnt := 0;
94
 
95
  signal   busy_y          : std_logic                    := '0';
96
 
97
  type state_type is (s_free, s_busy, s_guard);
98
  signal   state           : state_type := s_free;
99
 
100
begin
101
 
102
  scl_y <= to_x01(scl);
103
  sda_y <= to_x01(sda);
104
 
105
  scl_d <= scl_d_y;
106
 
107
  ------------------------------------------------------------------------------
108
  -- Monitoring 'scl_i' and 'sda_i' inputs
109
  process(clk)
110
  begin
111
    if rising_edge(clk) then
112
      if (s_rst = '1') then
113
        scl_d_y <= '1';
114
        sda_d_y <= '1';
115
        sda_cnt <= 0;
116
      else
117
        scl_d_y <= scl_y;
118
        sda_d_y <= sda_y;
119
 
120
        if (sda_d_y /= sda_y) then
121
          sda_cnt <= 1;
122
        elsif (sda_cnt /= c_max_cnt) then
123
          sda_cnt <= sda_cnt + 1;
124
        end if;
125
      end if;
126
    end if;
127
  end process;
128
  ------------------------------------------------------------------------------
129
 
130
  ------------------------------------------------------------------------------
131
  state_proc:
132
  process(clk)
133
  begin
134
    if rising_edge(clk) then
135
      if (s_rst = '1') then
136
        state  <= s_free;
137
        busy_y <= '0';
138
      else
139
        case state is
140
          when s_free =>
141
            busy_y <= '0';
142
            if (scl_y = '1')and(sda_d_y = '1')and(sda_y = '0') then
143
              state  <= s_busy;
144
              busy_y <= '1';
145
            end if;
146
          when s_busy =>
147
            busy_y <= '1';
148
            if (scl_y = '1')and(sda_d_y = '0')and(sda_y = '1') then
149
              state  <= s_guard;
150
            end if;
151
          when s_guard =>
152
            busy_y <= '1';
153
            if (sda_d_y = '1')and(scl_d_y = '1')and(sda_cnt = c_t_buf_cnt) then
154
              state  <= s_free;
155
              busy_y <= '0';
156
            end if;
157
        end case;
158
      end if;
159
    end if;
160
  end process state_proc;
161
  ------------------------------------------------------------------------------
162
 
163
  busy     <= busy_y;
164
 
165
end architecture rtl;
166
--==============================================================================
167
 

powered by: WebSVN 2.1.0

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