Belle II KLM Scint Firmware  1
Module_ADC_MCP3221_I2C_new.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 13:09:20 04/12/2013
6 -- Design Name:
7 -- Module Name: Module_ADC_MCP3221_I2C - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 -- History: Wicked Minds Electronics, 2012may15, Stripped down. Added IDLE.
20 -- Felix Bertram, 2002jan11, Created.
21 -- Source: http://www.fpgarelated.com/usenet/fpga/show/43649-1.php
22 --
23 -- #### Deficiencies:
24 -- 1. Needs refactoring. Design is full of nested priority encoders that may not be necessary. (CK)
25 -- 2. Relies on clock of f/11 created using bit 10 of 16 bit counter, and this
26 -- disagrees with comment of "--~97.66kHz." Yet another comment suggests that the
27 -- input clock is 40 MHz, even though it was previously 63.6 MHz and is now 127.2 MHz. (CK)
28 -- Datasheet says:
29 -- ------------------------------------------------------
30 -- Parameter | Sym. | Min. | Typ. | Max. | Units
31 -- ------------------------------------------------------
32 -- Clock Frequency |f SCL | 0 | — | 100 | kHz
33 -- Clock High Time |T HIGH | 4000 | — | — | ns
34 -- Clock Low Time |T LOW | 4700 | — | — | ns
35 -- ------------------------------------------------------
36 -- 3. Unnecessary use of constants for some sort of binary encoding, even though only
37 -- of the 8 possibilities is actually used. Should be generic (CK)
38 ----------------------------------------------------------------------------------
39 library IEEE;
40 use IEEE.STD_LOGIC_1164.ALL;
41 
42 -- Uncomment the following library declaration if using
43 -- arithmetic functions with Signed or Unsigned values
44 use IEEE.NUMERIC_STD.ALL;
45 
46 -- Uncomment the following library declaration if instantiating
47 -- any Xilinx primitives in this code.
48 --library UNISIM;
49 --use UNISIM.VComponents.all;
50 
52  port(
53  clock : in std_logic; --40MHz clock on Univ. Eval RevA board
54  reset : in std_logic;
55 
56  -- debugmode : in std_logic;
57 
58  sda : inout std_logic;
59  scl : out std_logic;
60 
61  runADC : in std_logic;
62  ADCOutput : OUT std_logic_vector(11 downto 0) --12 bit
63 
64  );
65 
66 end Module_ADC_MCP3221_I2C_new;
67 
68 architecture Behavioral of Module_ADC_MCP3221_I2C_new is
69 
70 
71 
72  --=============================================================================
73 
74  ---==================================
75 -- Part# Address
76 -- MCP3221A0T 000
77 -- MCP3221A1T 001
78 -- MCP3221A2T 010
79 -- MCP3221A3T 011
80 -- MCP3221A4T 100
81 -- MCP3221A5T 101
82 -- MCP3221A6T 110
83 -- MCP3221A7T 111
84 ---==================================
85 -- constant DevCode : std_logic_vector(3 downto 0):= "1001";
86  constant DevCode : std_logic_vector(3 downto 0):= "1001";
87 
88  constant AddrBitA0T : std_logic_vector(2 downto 0):= "000";
89  constant AddrBitA1T : std_logic_vector(2 downto 0):= "001";
90  constant AddrBitA2T : std_logic_vector(2 downto 0):= "010";
91  constant AddrBitA3T : std_logic_vector(2 downto 0):= "011";
92  constant AddrBitA4T : std_logic_vector(2 downto 0):= "100";
93  constant AddrBitA5T : std_logic_vector(2 downto 0):= "101";
94  constant AddrBitA6T : std_logic_vector(2 downto 0):= "110";
95  constant AddrBitA7T : std_logic_vector(2 downto 0):= "111";
96 
97  ----------------------------------------------------------------
98  constant DeviceAddress : STD_LOGIC_VECTOR(6 DOWNTO 0) := DevCode & AddrBitA7T;
99 -- constant DeviceAddress : STD_LOGIC_VECTOR(6 DOWNTO 0) := DevCode & AddrBitA5T;
100  signal dataToWrite : std_logic_vector(7 downto 0) := DeviceAddress & '1'; --read mode
101  signal dataToRead : std_logic_vector(7 downto 0);
102 
103  --=============================================================================
104  signal idxBit : unsigned(3 downto 0);
105  signal idxCyc : unsigned(1 downto 0);
106 
107  signal readyForNextState : std_logic;
108  signal readUpperByte : std_logic;
109 
110  signal clkCounter : unsigned(10 downto 0);
111  signal clkdiv2048 : std_logic;
112  -- signal dbgcntr : unsigned(15 downto 0);
113 
114  type I2C_STATE_TYPE is
115  (
116  st_idle,
117  st_start,
118 
119  st_read_byte,
120  st_write_byte,
121  st_wait_for_ack,
122  st_send_ack,
123  st_send_no_ack,
124 
125  st_stop
126  );
127 
128  signal state : I2C_STATE_TYPE := st_idle;
129 
130  signal upperDataByte, LowerDataByte :std_logic_vector(7 downto 0);
131 
132  signal i_runADC : std_logic;
133 
134 
135 
136 begin
137 
138  process (clock)
139  begin
140  if rising_edge(clock) then
141  clkCounter <= clkCounter + 1;
142  -- dbgcntr <= dbgcntr+1;
143  end if;
144  end process;
145  clkdiv2048 <= clkCounter(10);
146 
147  process (clock, reset)
148  begin
149  if reset='1' then
150  i_runADC <= '0';
151  elsif rising_edge(clock) then
152  if runADC= '1' and state = st_idle then
153  i_runADC <= '1';
154  elsif i_runADC = '1' and state = st_stop then
155  i_runADC <= '0';
156  end if;
157  end if;
158  end process;
159 
160  process (clkdiv2048, reset)
161  begin
162  if reset='1' then
163  idxCyc <= "00";
164  idxbit <= "0000";
165  state <= st_idle;
166  readyForNextState <= '1';
167  elsif rising_edge(clkdiv2048) then
168  if readyForNextState = '1' then
169  --idle ==> start
170  if state = st_idle and i_runADC = '1' then
171  --if state = st_idle then
172  state <= st_start;
173  readyForNextState <= '0';
174  idxCyc <= "00";
175  --start ==> write
176  elsif state = st_start then
177  state <= st_write_byte;
178  readyForNextState <= '0';
179  idxCyc <= "00";
180  idxBit <= "0000";
181  --write ==> wait for ack
182  elsif state = st_write_byte then
183  state <= st_wait_for_ack;
184  readyForNextState <= '0';
185  idxCyc <= "00";
186  idxBit <= "0000";
187 
188  --wait for ack ==> read upper byte
189  elsif state = st_wait_for_ack then
190  state <= st_read_byte;
191 
192  readyForNextState <= '0';
193  idxCyc <= "00";
194  idxBit <= "0000";
195 
196  --read upper byte ==>send ack
197  elsif state = st_read_byte and readUpperByte='1' then
198  upperDataByte <= dataToRead;
199  state <= st_send_ack;
200  readUpperByte<='0';
201  readyForNextState <= '0';
202  idxCyc <= "00";
203  idxBit <= "0000";
204 
205  --send ack ==> read lower byte
206  elsif state = st_send_ack then
207 
208  state <= st_read_byte;
209  readyForNextState <= '0';
210  idxCyc <= "00";
211  idxBit <= "0000";
212 
213  --read lower byte ==> send no ack
214  elsif state = st_read_byte and readUpperByte= '0' then
215  lowerDataByte <= dataToRead;
216  state <= st_send_no_ack;
217  readUpperByte <= '1';
218  readyForNextState <= '0';
219  idxCyc <= "00";
220  idxBit <= "0000";
221 
222  --send no ack ==> stop
223  elsif state = st_send_no_ack then
224  state <= st_stop;
225  readyForNextState <= '0';
226  idxCyc <= "00";
227  idxBit <= "0000";
228 
229  --stop ==> idle
230  elsif state = st_stop then
231  state <= st_idle;
232  readyForNextState <= '0';
233  idxCyc <= "00";
234  idxBit <= "0000";
235  end if;
236 
237 
238  else --if readyForNextState = '0'
239 
240  case state is
241  when st_start =>
242  if idxCyc= 0 then
243  scl<= '0';
244  idxCyc<= idxCyc + 1;
245  elsif idxCyc= 1 then
246  sda<= '1';
247  idxCyc<= idxCyc + 1;
248  elsif idxCyc= 2 then
249  scl<= '1';
250  idxCyc<= idxCyc + 1;
251  elsif idxCyc= 3 then
252  sda<= '0';
253  readyForNextState <= '1';
254  end if;
255 
256  when st_write_byte =>
257  if idxBit < 8 then
258  if idxCyc = 0 then
259  scl <= '0';
260  idxCyc <= idxCyc + 1;
261  elsif idxCyc= 1 then
262  sda <= DataToWrite(to_integer(7 - idxBit));
263  idxCyc <= idxCyc + 1;
264  elsif idxCyc= 2 then
265  scl <= '1';
266  idxCyc <= idxCyc + 1;
267  elsif idxCyc= 3 then
268  idxCyc <= "00";
269  idxBit <= idxBit + 1;
270  end if;
271  else
272  --wait for state change
273  readyForNextState <= '1';
274  end if;
275 
276  when st_read_byte =>
277  if idxBit < 8 then
278  if idxCyc = 0 then
279  scl <= '0';
280  sda <= 'Z';
281  idxCyc <= idxCyc + 1;
282  elsif idxCyc= 1 then
283 
284  idxCyc <= idxCyc + 1;
285  elsif idxCyc= 2 then
286  scl <= '1';
287  idxCyc <= idxCyc + 1;
288  elsif idxCyc= 3 then
289  dataToRead(to_integer(7 - idxBit)) <= sda;
290  idxCyc <= "00";
291  idxBit <= idxBit + 1;
292  end if;
293  else --idxBit = 8
294  --wait for state change
295  readyForNextState <= '1';
296  end if;
297 
298  when st_wait_for_ack =>
299  if idxCyc= 0 then
300  scl<= '0';
301  idxCyc<= idxCyc + 1;
302  elsif idxCyc= 1 then
303  sda<= 'Z';
304  --sda<= '1';
305  idxCyc<= idxCyc + 1;
306  elsif idxCyc= 2 then
307  scl<= '1';
308  --sda<='Z';
309  idxCyc<= idxCyc + 1;
310  elsif idxCyc= 3 then
311  -- if sda = '0' then
312  -- else
313  -- end if;
314  readyForNextState <= '1';
315  end if;
316 
317  when st_send_ack =>
318  if idxCyc= 0 then
319  scl<= '0';
320  idxCyc<= idxCyc + 1;
321  elsif idxCyc= 1 then
322  sda<= '0';
323  idxCyc<= idxCyc + 1;
324  elsif idxCyc= 2 then
325  scl<= '1';
326  --sda<= '0';
327  idxCyc<= idxCyc + 1;
328  elsif idxCyc= 3 then
329  scl <= '1';
330  --sda <= 'Z';
331  readyForNextState <= '1';
332  end if;
333 
334  when st_send_no_ack =>
335  if idxCyc= 0 then
336  scl<= '0';
337  idxCyc<= idxCyc + 1;
338  elsif idxCyc= 1 then
339  sda<= '1';
340  idxCyc<= idxCyc + 1;
341  elsif idxCyc= 2 then
342  scl<= '1';
343  --sda<= '1';
344  idxCyc<= idxCyc + 1;
345  elsif idxCyc= 3 then
346  readyForNextState <= '1';
347  end if;
348 
349  when st_stop =>
350  if idxCyc= 0 then
351  scl<= '0';
352  idxCyc<= idxCyc + 1;
353  elsif idxCyc= 1 then
354  sda<= '0';
355  idxCyc<= idxCyc + 1;
356  elsif idxCyc= 2 then
357  scl<= '1';
358  idxCyc<= idxCyc + 1;
359  elsif idxCyc= 3 then
360  sda<= '1';
361  readyForNextState <= '1';
362  end if;
363 
364  when st_idle =>
365  scl<= '1';
366  sda<= '1';
367  readyForNextState <= '1';
368  end case;
369  end if; --end of "if readyForNextState"
370  end if; --end of "reset"
371  end process;
372 
373 
374 
375  process(clock)
376  begin
377  if rising_edge(clock) then
378  ADCOutput <= upperDataByte(3 downto 0) & lowerDataByte;
379  -- if debugmode = '0' then
380  -- ADCOutput <= upperDataByte(3 downto 0) & lowerDataByte;
381  -- else
382  -- ADCOutput <= std_logic_vector(dbgcntr(15 downto 4));
383  -- end if;
384  end if;
385  end process;
386 
387 end Behavioral;
388 
389 
390 
391 
392 
393 
394 
395 
396 
397 
398 
399 
400 
401 
402 
403 
404 
405 
406 
407 
408 
409 
410 
411