diff options
Diffstat (limited to 'FPGA/vhdl/i2c_master.vhd')
-rw-r--r-- | FPGA/vhdl/i2c_master.vhd | 526 |
1 files changed, 271 insertions, 255 deletions
diff --git a/FPGA/vhdl/i2c_master.vhd b/FPGA/vhdl/i2c_master.vhd index 99b179b..bc0381e 100644 --- a/FPGA/vhdl/i2c_master.vhd +++ b/FPGA/vhdl/i2c_master.vhd | |||
@@ -1,255 +1,271 @@ | |||
1 | library ieee; | 1 | library ieee; |
2 | use ieee.std_logic_1164.all; | 2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; | 3 | use ieee.numeric_std.all; |
4 | 4 | ||
5 | entity i2C_master is | 5 | entity i2C_master is |
6 | generic ( | 6 | generic ( |
7 | system_frequency : real := 50.0E6; -- 50 MHz | 7 | system_frequency : real := 50.0E6; -- 50 MHz |
8 | i2c_rate : real := 20.0E3 -- 20 kHz | 8 | i2c_rate : real := 20.0E3 -- 20 kHz |
9 | ); | 9 | ); |
10 | port ( | 10 | port ( |
11 | clk : in std_logic; | 11 | clk : in std_logic; |
12 | resetn : in std_logic; | 12 | resetn : in std_logic; |
13 | go : in std_logic; | 13 | go : in std_logic; |
14 | ready : out std_logic; | 14 | ready : out std_logic; |
15 | data_in : in std_logic_vector(23 downto 0); -- adress & command & data | 15 | data_in : in std_logic_vector(23 downto 0); -- adress & command & data |
16 | ack : out std_logic; | 16 | ack : out std_logic; |
17 | -- i2c | 17 | -- i2c |
18 | i2c_scl : out std_logic; -- A6 | 18 | i2c_scl : out std_logic; -- A6 |
19 | i2c_sda : inout std_logic -- B6 | 19 | i2c_sda : inout std_logic -- B6 |
20 | ); | 20 | ); |
21 | end entity; | 21 | end entity; |
22 | 22 | ||
23 | architecture rtl of i2c_master is | 23 | architecture rtl of i2c_master is |
24 | constant mod_ctr_tempo : positive := integer(system_frequency/(2.0*i2c_rate)); | 24 | constant mod_ctr_tempo : positive := integer(system_frequency/(i2c_rate)); |
25 | constant mod_ctr_bit : positive := 35; | 25 | constant mod_ctr_bit : positive := 35; |
26 | type state is (wait_for_go, wait_for_i2clk, tx); | 26 | type state is (wait_for_go, wait_for_i2clk, tx, wait_for_not_go); |
27 | signal current_state : state; | 27 | signal current_state : state; |
28 | signal next_state : state; | 28 | signal next_state : state; |
29 | signal sdo : std_logic; | 29 | signal sdo : std_logic; |
30 | signal ctr_tempo : natural range 0 to mod_ctr_tempo-1; | 30 | signal ctr_tempo : natural range 0 to mod_ctr_tempo-1; |
31 | signal end_tempo : std_logic; | 31 | signal end_tempo : std_logic; |
32 | signal ctr_bit : natural range 0 to mod_ctr_bit-1; | 32 | signal ctr_bit : natural range 0 to mod_ctr_bit-1; |
33 | signal ack1 : std_logic; | 33 | signal ack1 : std_logic; |
34 | signal ack2 : std_logic; | 34 | signal ack2 : std_logic; |
35 | signal ack3 : std_logic; | 35 | signal ack3 : std_logic; |
36 | signal reg_data : std_logic_vector(data_in'range); | 36 | signal reg_data : std_logic_vector(data_in'range); |
37 | signal cmd_data : std_logic_vector(1 downto 0); | 37 | signal cmd_data : std_logic_vector(1 downto 0); |
38 | signal cmd_bit : 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); | 39 | signal cmd_ack1 : std_logic_vector(1 downto 0); |
40 | signal cmd_ack2 : 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); | 41 | signal cmd_ack3 : std_logic_vector(1 downto 0); |
42 | signal sclk : std_logic; | 42 | signal sclk : std_logic; |
43 | signal i2c_clk : std_logic; | 43 | signal i2c_clk : std_logic; |
44 | signal ready_i : std_logic; | 44 | signal ready_i : std_logic; |
45 | 45 | ||
46 | begin | 46 | begin |
47 | i2c_sda <= 'Z' when sdo = '1' | 47 | i2c_sda <= 'Z' when sdo = '1' |
48 | else '0'; | 48 | else '0'; |
49 | i2c_scl <= '1' when sclk='1' | 49 | i2c_scl <= '1' when sclk='1' |
50 | else not i2c_clk when (ctr_bit>=4 and ctr_bit <= 30) | 50 | else not i2c_clk when (ctr_bit>=3 and ctr_bit <= 30) |
51 | else '0'; | 51 | else '0'; |
52 | ack <= ack1 or ack2 or ack3; | 52 | ack <= ack1 or ack2 or ack3; |
53 | end_tempo <= '0' when ctr_tempo< mod_ctr_tempo-1 else '1'; | 53 | end_tempo <= '0' when ctr_tempo< mod_ctr_tempo-1 else '1'; |
54 | 54 | ||
55 | process(resetn, clk) is | 55 | process(resetn, clk) is |
56 | begin | 56 | begin |
57 | if resetn = '0' then | 57 | if resetn = '0' then |
58 | i2c_clk <= '0'; | 58 | i2c_clk <= '0'; |
59 | ctr_tempo <= 0; | 59 | ctr_tempo <= 0; |
60 | ctr_bit <= 0; | 60 | ctr_bit <= 0; |
61 | reg_data <= (others => '0'); | 61 | reg_data <= (others => '0'); |
62 | --sclk <= '1'; | 62 | --sclk <= '1'; |
63 | ACK1 <= '0'; | 63 | ACK1 <= '0'; |
64 | ACK2 <= '0'; | 64 | ACK2 <= '0'; |
65 | ACK3 <= '0'; | 65 | ACK3 <= '0'; |
66 | ready <= '1'; | 66 | ready <= '1'; |
67 | current_state <= wait_for_go; | 67 | current_state <= wait_for_go; |
68 | elsif rising_edge(clk) then | 68 | elsif rising_edge(clk) then |
69 | current_state <= next_state; | 69 | current_state <= next_state; |
70 | ready <= ready_i; | 70 | ready <= ready_i; |
71 | 71 | ||
72 | -- temporisation et i2_clk | 72 | -- temporisation et i2_clk |
73 | if current_state = wait_for_go then | 73 | if current_state = wait_for_go then |
74 | ctr_tempo <= 0; | 74 | ctr_tempo <= 0; |
75 | i2c_clk <= '0'; | 75 | i2c_clk <= '0'; |
76 | elsif end_tempo='0' then | 76 | elsif end_tempo='0' then |
77 | ctr_tempo <= ctr_tempo +1; | 77 | ctr_tempo <= ctr_tempo +1; |
78 | else | 78 | else |
79 | ctr_tempo <= 0; | 79 | ctr_tempo <= 0; |
80 | i2c_clk <= not i2c_clk; | 80 | i2c_clk <= not i2c_clk; |
81 | end if; | 81 | end if; |
82 | -- reg_data | 82 | -- reg_data |
83 | case cmd_data is | 83 | case cmd_data is |
84 | when "10" => reg_data <= data_in; | 84 | when "10" => reg_data <= data_in; |
85 | when "11" => reg_data <= reg_data(22 downto 0)&'0'; | 85 | when "11" => reg_data <= reg_data(22 downto 0)&'0'; |
86 | when others => null; | 86 | when others => null; |
87 | end case; | 87 | end case; |
88 | -- ctr_bit | 88 | -- ctr_bit |
89 | case cmd_bit is | 89 | case cmd_bit is |
90 | when "10" => ctr_bit <= 0; | 90 | when "10" => ctr_bit <= 0; |
91 | when "11" => if ctr_bit<mod_ctr_bit-1 then ctr_bit <= ctr_bit+1; | 91 | when "11" => if ctr_bit<mod_ctr_bit-1 then ctr_bit <= ctr_bit+1; |
92 | else ctr_bit <= 0; | 92 | else ctr_bit <= 0; |
93 | end if; | 93 | end if; |
94 | when others => null; | 94 | when others => null; |
95 | end case; | 95 | end case; |
96 | -- ack1 | 96 | -- ack1 |
97 | case cmd_ack1 is | 97 | case cmd_ack1 is |
98 | when "10" => ack1 <= '0'; | 98 | when "10" => ack1 <= '0'; |
99 | when "11" => ack1 <= '1'; | 99 | when "11" => ack1 <= '1'; |
100 | when others => null; | 100 | when others => null; |
101 | end case; | 101 | end case; |
102 | -- ack2 | 102 | -- ack2 |
103 | case cmd_ack2 is | 103 | case cmd_ack2 is |
104 | when "10" => ack2 <= '0'; | 104 | when "10" => ack2 <= '0'; |
105 | when "11" => ack2 <= '1'; | 105 | when "11" => ack2 <= '1'; |
106 | when others => null; | 106 | when others => null; |
107 | end case; | 107 | end case; |
108 | -- ack1 | 108 | -- ack1 |
109 | case cmd_ack3 is | 109 | case cmd_ack3 is |
110 | when "10" => ack3 <= '0'; | 110 | when "10" => ack3 <= '0'; |
111 | when "11" => ack3 <= '1'; | 111 | when "11" => ack3 <= '1'; |
112 | when others => null; | 112 | when others => null; |
113 | end case; | 113 | end case; |
114 | end if; | 114 | end if; |
115 | end process; | 115 | end process; |
116 | -------------------------------- | 116 | -------------------------------- |
117 | -- FSM | 117 | -- FSM |
118 | ------------------------------- | 118 | ------------------------------- |
119 | process(current_state, end_tempo, i2c_clk, go,reg_data(23), i2c_sda,ctr_bit) is | 119 | process(current_state, end_tempo, i2c_clk, go,reg_data(23), i2c_sda,ctr_bit) is |
120 | begin | 120 | begin |
121 | next_state <= current_state; | 121 | next_state <= current_state; |
122 | ready_i <= '0'; | 122 | ready_i <= '0'; |
123 | cmd_ack1 <= "00"; | 123 | cmd_ack1 <= "00"; |
124 | cmd_ack2 <= "00"; | 124 | cmd_ack2 <= "00"; |
125 | cmd_ack3 <= "00"; | 125 | cmd_ack3 <= "00"; |
126 | cmd_bit <= "00"; | 126 | cmd_bit <= "00"; |
127 | cmd_data <= "00"; | 127 | cmd_data <= "00"; |
128 | sdo <= '1'; | 128 | sdo <= '1'; |
129 | sclk <= '0'; | 129 | sclk <= '0'; |
130 | case current_state is | 130 | case current_state is |
131 | when wait_for_go => if go = '1' then next_state <=wait_for_i2clk; | 131 | when wait_for_not_go => if go = '0' then next_state <=wait_for_go; |
132 | end if; | 132 | end if; |
133 | ready_i <= '1'; | 133 | ready_i <= '1'; |
134 | cmd_bit <= "10"; | 134 | cmd_bit <= "10"; |
135 | cmd_data <= "10"; | 135 | cmd_data <= "10"; |
136 | sclk <= '1'; | 136 | sclk <= '1'; |
137 | when wait_for_i2clk => if i2c_clk='0' and end_tempo='1' then next_state <=tx; | 137 | when wait_for_go => if go = '1' then next_state <=wait_for_i2clk; |
138 | end if; | 138 | end if; |
139 | cmd_ack1 <= "10"; | 139 | ready_i <= '1'; |
140 | cmd_ack2 <= "10"; | 140 | cmd_bit <= "10"; |
141 | cmd_ack3 <= "10"; | 141 | cmd_data <= "10"; |
142 | sclk <= '1'; | 142 | sclk <= '1'; |
143 | when tx => if ctr_bit< mod_ctr_bit-1 then | 143 | when wait_for_i2clk => if end_tempo='1' then next_state <=tx; cmd_bit <= "11"; |
144 | if i2c_clk='0' and end_tempo='1'then | 144 | end if; |
145 |