diff options
author | Pacien TRAN-GIRARD | 2014-04-11 19:29:53 +0200 |
---|---|---|
committer | Pacien TRAN-GIRARD | 2014-04-11 19:29:53 +0200 |
commit | 12bbdb42cdcf5e6e39832d75fbbd31e3781d550a (patch) | |
tree | 21d9d8fdb7a949c8050de38c237386d0066ca146 /FPGA/vhdl/i2c_master.vhd | |
download | fpga-home-automation-12bbdb42cdcf5e6e39832d75fbbd31e3781d550a.tar.gz |
Import fichiers projet Quartus
Diffstat (limited to 'FPGA/vhdl/i2c_master.vhd')
-rw-r--r-- | FPGA/vhdl/i2c_master.vhd | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/FPGA/vhdl/i2c_master.vhd b/FPGA/vhdl/i2c_master.vhd new file mode 100644 index 0000000..99b179b --- /dev/null +++ b/FPGA/vhdl/i2c_master.vhd | |||
@@ -0,0 +1,255 @@ | |||
1 | library ieee; | ||
2 | use ieee.std_logic_1164.all; | ||
3 | use ieee.numeric_std.all; | ||
4 | |||
5 | entity i2C_master is | ||
6 | generic ( | ||
7 | system_frequency : real := 50.0E6; -- 50 MHz | ||
8 | i2c_rate : real := 20.0E3 -- 20 kHz | ||
9 | ); | ||
10 | port ( | ||
11 | clk : in std_logic; | ||
12 | resetn : in std_logic; | ||
13 | go : in std_logic; | ||
14 | ready : out std_logic; | ||
15 | data_in : in std_logic_vector(23 downto 0); -- adress & command & data | ||
16 | ack : out std_logic; | ||
17 | -- i2c | ||
18 | i2c_scl : out std_logic; -- A6 | ||
19 | i2c_sda : inout std_logic -- B6 | ||
20 | ); | ||
21 | end entity; | ||
22 | |||
23 | architecture rtl of i2c_master is | ||
24 | constant mod_ctr_tempo : positive := integer(system_frequency/(2.0*i2c_rate)); | ||
25 | constant mod_ctr_bit : positive := 35; | ||
26 | type state is (wait_for_go, wait_for_i2clk, tx); | ||
27 | signal current_state : state; | ||
28 | signal next_state : state; | ||
29 | signal sdo : std_logic; | ||
30 | signal ctr_tempo : natural range 0 to mod_ctr_tempo-1; | ||
31 | signal end_tempo : std_logic; | ||
32 | signal ctr_bit : natural range 0 to mod_ctr_bit-1; | ||
33 | signal ack1 : std_logic; | ||
34 | signal ack2 : std_logic; | ||
35 | signal ack3 : std_logic; | ||
36 | signal reg_data : std_logic_vector(data_in'range); | ||
37 | signal cmd_data : std_logic_vector(1 downto 0); | ||
38 | signal cmd_bit : std_logic_vector(1 downto 0); | ||
39 | signal cmd_ack1 : std_logic_vector(1 downto 0); | ||
40 | signal cmd_ack2 : std_logic_vector(1 downto 0); | ||
41 | signal cmd_ack3 : std_logic_vector(1 downto 0); | ||
42 | signal sclk : std_logic; | ||
43 | signal i2c_clk : std_logic; | ||
44 | signal ready_i : std_logic; | ||
45 | |||
46 | begin | ||
47 | i2c_sda <= 'Z' when sdo = '1' | ||
48 | else '0'; | ||
49 | i2c_scl <= '1' when sclk='1' | ||
50 | else not i2c_clk when (ctr_bit>=4 and ctr_bit <= 30) | ||
51 | else '0'; | ||
52 | ack <= ack1 or ack2 or ack3; | ||
53 | end_tempo <= '0' when ctr_tempo< mod_ctr_tempo-1 else '1'; | ||
54 | |||
55 | process(resetn, clk) is | ||
56 | begin | ||
57 | if resetn = '0' then | ||
58 | i2c_clk <= '0'; | ||
59 | ctr_tempo <= 0; | ||
60 | ctr_bit <= 0; | ||
61 | reg_data <= (others => '0'); | ||
62 | --sclk <= '1'; | ||
63 | ACK1 <= '0'; | ||
64 | ACK2 <= '0'; | ||
65 | ACK3 <= '0'; | ||
66 | ready <= '1'; | ||
67 | current_state <= wait_for_go; | ||
68 | elsif rising_edge(clk) then | ||
69 | current_state <= next_state; | ||
70 | ready <= ready_i; | ||
71 | |||
72 | -- temporisation et i2_clk | ||
73 | if current_state = wait_for_go then | ||
74 | ctr_tempo <= 0; | ||
75 | i2c_clk <= '0'; | ||
76 | elsif end_tempo='0' then | ||
77 | ctr_tempo <= ctr_tempo +1; | ||
78 | else | ||
79 | ctr_tempo <= 0; | ||
80 | i2c_clk <= not i2c_clk; | ||
81 | end if; | ||
82 | -- reg_data | ||
83 | case cmd_data is | ||
84 | when "10" => reg_data <= data_in; | ||
85 | when "11" => reg_data <= reg_data(22 downto 0)&'0'; | ||
86 | when others => null; | ||
87 | end case; | ||
88 | -- ctr_bit | ||
89 | case cmd_bit is | ||
90 | when "10" => ctr_bit <= 0; | ||
91 | when "11" => if ctr_bit<mod_ctr_bit-1 then ctr_bit <= ctr_bit+1; | ||
92 | else ctr_bit <= 0; | ||
93 | end if; | ||
94 | when others => null; | ||
95 | end case; | ||
96 | -- ack1 | ||
97 | case cmd_ack1 is | ||
98 | when "10" => ack1 <= '0'; | ||
99 | when "11" => ack1 <= '1'; | ||
100 | when others => null; | ||
101 | end case; | ||
102 | -- ack2 | ||
103 | case cmd_ack2 is | ||
104 | when "10" => ack2 <= '0'; | ||
105 | when "11" => ack2 <= '1'; | ||
106 | when others => null; | ||
107 | end case; | ||
108 | -- ack1 | ||
109 | case cmd_ack3 is | ||
110 | when "10" => ack3 <= '0'; | ||
111 | when "11" => ack3 <= '1'; | ||
112 | when others => null; | ||
113 | end case; | ||
114 | end if; | ||
115 | end process; | ||
116 | -------------------------------- | ||
117 | -- FSM | ||
118 | ------------------------------- | ||
119 | process(current_state, end_tempo, i2c_clk, go,reg_data(23), i2c_sda,ctr_bit) is | ||
120 | begin | ||
121 | next_state <= current_state; | ||
122 | ready_i <= '0'; | ||
123 | cmd_ack1 <= "00"; | ||
124 | cmd_ack2 <= "00"; | ||
125 | cmd_ack3 <= "00"; | ||
126 | cmd_bit <= "00"; | ||
127 | cmd_data <= "00"; | ||
128 | sdo <= '1'; | ||
129 | sclk <= '0'; | ||
130 | case current_state is | ||
131 | when wait_for_go => if go = '1' then next_state <=wait_for_i2clk; | ||
132 | end if; | ||
133 | ready_i <= '1'; | ||
134 | cmd_bit <= "10"; | ||
135 | cmd_data <= "10"; | ||
136 | sclk <= '1'; | ||
137 | when wait_for_i2clk => if i2c_clk='0' and end_tempo='1' then next_state <=tx; | ||
138 | end if; | ||
139 | cmd_ack1 <= "10"; | ||
140 | cmd_ack2 <= "10"; | ||
141 | cmd_ack3 <= "10"; | ||
142 | sclk <= '1'; | ||
143 | when tx => if ctr_bit< mod_ctr_bit-1 then | ||
144 | if i2c_clk='0' and end_tempo='1'then | ||
145 | cmd_bit <= "11"; | ||
146 | end if; | ||
147 | elsif end_tempo='1'then | ||
148 | next_state <= wait_for_go; | ||
149 | end if; | ||
150 | case ctr_bit is | ||
151 | when 0 => sdo <= '1'; sclk <= '1'; | ||
152 | -- start | ||
153 | when 1 => sdo <= '0'; sclk <= '0'; | ||
154 | when 2 => sdo <= '0'; sclk <= '0'; | ||
155 | -- slave address | ||
156 | when 3 => sdo <= reg_data(23); | ||
157 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
158 | end if; | ||
159 | when 4 => sdo <= reg_data(23); | ||
160 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
161 | end if; | ||
162 | when 5 => sdo <= reg_data(23); | ||
163 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
164 | end if; | ||
165 | when 6 => sdo <= reg_data(23); | ||
166 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
167 | end if; | ||
168 | when 7 => sdo <= reg_data(23); | ||
169 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
170 | end if; | ||
171 | when 8 => sdo <= reg_data(23); | ||
172 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
173 | end if; | ||
174 | when 9 => sdo <= reg_data(23); | ||
175 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
176 | end if; | ||
177 | when 10 => sdo <= reg_data(23); | ||
178 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
179 | end if; | ||
180 | when 11 => sdo <= '1'; -- ack | ||
181 | |||
182 | -- command | ||
183 | when 12 => sdo <= reg_data(23); | ||
184 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
185 | end if; | ||
186 | if i2c_sda='1' then cmd_ack1 <= "11" ; | ||
187 | else cmd_ack1 <= "10" ; | ||
188 | end if; | ||
189 | when 13 => sdo <= reg_data(23); | ||
190 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
191 | end if; | ||
192 | when 14 => sdo <= reg_data(23); | ||
193 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
194 | end if; | ||
195 | when 15 => sdo <= reg_data(23); | ||
196 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
197 | end if; | ||
198 | when 16 => sdo <= reg_data(23); | ||
199 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
200 | end if; | ||
201 | when 17 => sdo <= reg_data(23); | ||
202 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
203 | end if; | ||
204 | when 18 => sdo <= reg_data(23); | ||
205 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
206 | end if; | ||
207 | when 19 => sdo <= reg_data(23); | ||
208 | if i2c_clk='0' and end_tempo='1'then cmd_data <= "11"; | ||
209 | end if; | ||
210 | when 20 => sdo <= '1'; -- ack | ||
211 | -- data | ||
212 | when 21 => sdo <= reg_data(23); | ||
213 |