VICON: Sistema de Visión configurable V1.0
Trabajo Fin de Master Carlos Manuel Gomez Jimenez
Loading...
Searching...
No Matches
mt9v111.vhd
Go to the documentation of this file.
1
5
6library IEEE;
7use IEEE.STD_LOGIC_1164.ALL;
8use IEEE.NUMERIC_STD.ALL;
9use work.sim_utils_pkg.all;
10
12 generic (
13 I2C_ADDR : std_logic_vector(6 downto 0) := "1011100";
14 IMG_WIDTH : integer := 640;
15 IMG_HEIGHT : integer := 480
16 );
17 port (
18 pixclk : out std_logic;
19 fval : out std_logic;
20 lval : out std_logic;
21 dout : out std_logic_vector(7 downto 0);
22 scl : in std_logic;
23 sda : inout std_logic
24 );
26
27architecture Behavioral of mt9v111_agent is
28
29 constant PIX_PERIOD : time := 37 ns;
30 signal clk_int : std_logic := '0';
31
32 type reg_map_t is array (0 to 255) of std_logic_vector(15 downto 0);
33
34 signal regs_core : reg_map_t := (
35 16#00# => x"823A",
36 16#0D# => x"0008",
37 others => x"CACA"
38 );
39
40 signal regs_ifp : reg_map_t := (
41 16#01# => x"0001",
42 others => x"0FE0"
43 );
44
45 -- Registro base para lectura: el master primero escribe addr_reg en modo
46 -- write, luego hace Repeated START en modo read. Guardamos addr_reg entre
47 -- las dos fases en esta señal compartida.
48 signal read_reg_addr : integer range 0 to 255 := 0;
49 signal debug_state : string(1 to 20) := (others => ' ');
50 signal s_reg_addr : integer range 0 to 255;
51begin
52
53 clk_int <= not clk_int after PIX_PERIOD / 2;
54 pixclk <= clk_int;
55 fval <= '0';
56 lval <= '0';
57 dout <= (others => '0');
58
59 ---------------------------------------------------------------------------
60 -- Proceso I2C esclavo continuo.
61 --
62 -- Secuencia WRITE:
63 -- S + ADDR_WR + ACK + REG_ADDR + ACK + DATA_H + ACK + DATA_L + ACK + [más regs] + P
64 --
65 -- Secuencia READ (el master hace dos transacciones seguidas):
66 -- 1ª: S + ADDR_WR + ACK + REG_ADDR + ACK (establece el registro a leer)
67 -- 2ª: Sr + ADDR_RD + ACK + [agente envía DATA_H + master ACK + DATA_L + master ACK/NACK] + P
68 ---------------------------------------------------------------------------
69 i2c_slave : process
70 variable v_addr_byte : std_logic_vector(7 downto 0);
71 variable v_rw : std_logic := '0';
72 variable v_reg_addr : integer range 0 to 255;
73 variable v_reg_inc : integer range 0 to 255;
74 variable v_data_h : std_logic_vector(7 downto 0);
75 variable v_data_l : std_logic_vector(7 downto 0);
76 variable v_data_16 : std_logic_vector(15 downto 0);
77 variable v_stop_seen : boolean;
78 variable v_start_seen : boolean;
79 variable v_mack : std_logic;
80 variable v_send_byte : std_logic_vector(7 downto 0);
81
82 begin
83 sda <= 'Z';
84
85
86 loop
87
88
89 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
90 ---------------------- START
91 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
92
93
94 debug_state <= "ESPERANDO_START (0)";
95 wait until falling_edge(sda) and scl = '1';
96 debug_state <= "START DETECTED (3) ";
97
98 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
99 ---------------------- SLAVE ADDR + W
100 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
101
102
103 for i in 7 downto 0 loop
104 wait until rising_edge(scl);
105 v_addr_byte(i) := sda;
106 end loop;
107
108 debug_state <= "LEYENDO_ADDR (34)"; -- No se verá si pasa la condicion de direccion.
109
110 if v_addr_byte(7 downto 1) = I2C_ADDR then
111
112 debug_state <= "ADDR_OK (34)";
113 wait until falling_edge(scl);
114 debug_state <= "ADDR_SACK (36)";
115 sda <= '0';
116 wait until rising_edge(scl);
117 debug_state <= "SACK_READ (38)";
118 sda <= 'Z';
119 wait until falling_edge(scl);
120 debug_state <= "READING REG_ADDR(42)";
121
122 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
123 ---------------------- REGISTER ADDRESS
124 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
125
126
127 for i in 7 downto 0 loop
128 wait until rising_edge(scl);
129 v_addr_byte(i) := sda;
130 end loop;
131
132 debug_state <= "SAVE REG_ADDR (70)";
133 v_reg_addr := to_integer(unsigned(v_addr_byte));
134 s_reg_addr <= v_reg_addr;
135 v_reg_inc := v_reg_addr;
136 read_reg_addr <= v_reg_addr;
137 wait until falling_edge(scl);
138
139 debug_state <= "REG_ADDR_SACK (72)";
140 sda <= '0';
141 wait until rising_edge(scl);
142 debug_state <= "SACK_READ (74)";
143 sda <= 'Z';
144
145 wait until falling_edge(scl);
146 v_stop_seen := false;
147
148 v_rw := '0';
149
150 while not v_stop_seen loop
151
152 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
153 ---------------------- DATA HIGH (DEFAULT WRITE OP)
154 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
155
156
157 debug_state <= "LEYENDO/ESCR_DATA_H ";
158 for i in 7 downto 0 loop
159 if v_rw = '0' then
160 wait until rising_edge(scl);
161 debug_state <= "DATAH CLK NUM i=" & integer'image(i);
162 v_data_h(i) := sda;
163 wait until rising_edge(sda) or falling_edge(sda) or falling_edge(scl);
164 if scl = '1' then
165 if sda = '1' then
166 v_stop_seen := true;
167 debug_state <= "STOP_DETECTADO ";
168 exit;
169
170 elsif sda = '0' then
171 v_start_seen := true;
172 debug_state <= "START_DETECTADO ";
173 exit;
174
175 end if;
176 else
177 debug_state <= "MAS_DATOS ";
178 end if;
179
180 else
181 if i /= 7 then
182 wait until falling_edge(scl);
183 end if;
184 debug_state <= "RDATAH CLK NUM i=" & integer'image(i);
185 s_reg_addr <= v_reg_inc;
186 sda <= regs_core(v_reg_inc)(8 + i);
187
188 if i = 0 then
189 wait until falling_edge(scl);
190 end if;
191 end if;
192
193
194
195 end loop;
196
197
198
199 if v_stop_seen then
200 exit;
201 end if;
202
203 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
204 ---------------------- IF REPEATED START, NEXT AND READ REG_ADDR + R (READ OP)
205 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
206
207 if v_start_seen then
208 v_start_seen := false;
209 debug_state <= "READING REG_ADDR(42)";
210
211 for i in 7 downto 0 loop
212 wait until rising_edge(scl);
213 debug_state <= "ADDR_R CLK NUM i=" & integer'image(i);
214 v_addr_byte(i) := sda;
215
216 wait until rising_edge(sda) or falling_edge(sda) or falling_edge(scl);
217
218 if scl = '1' then
219 if sda = '1' then
220 v_stop_seen := true;
221 debug_state <= "STOP_DETECTADO ";
222 exit;
223
224 elsif sda = '0' then
225 v_start_seen := true;
226 debug_state <= "START_DETECTADO ";
227 exit;
228
229 end if;
230 else
231 debug_state <= "MAS_DATOS ";
232 end if;
233
234 end loop;
235
236
237
238 if v_addr_byte(0) = '1' then
239 v_rw := '1';
240 else
241 v_rw := '0'; --No debería pasar, porque sería mandar un Repeated START en modo write, pero lo manejamos igual por si acaso
242 end if;
243 debug_state <= "TEST PROBE ";
244
245 --wait until falling_edge(scl);
246 wait for 0.4 us;
247 debug_state <= "ADDR_READ_SACK (72)";
248 sda <= '0';
249 wait until rising_edge(scl);
250 debug_state <= "SACK_READ (74)";
251 sda <= 'Z';
252 wait until falling_edge(scl);
253
254 next; -- Aquí volvemos a empezar el loop de lectura de datos, pero con v_rw = '1' para indicar que ahora es una lectura.
255
256 end if;
257
258 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
259 ---------------------- IF NOT REPEATED START, ES DATO HIGH DE UNA ESCRITURA, CONTINUAMOS LEYENDO/ESCRIBIENDO DATA LOW
260 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
261
262 if v_rw = '0' then
263
264 debug_state <= "SAVE REG_V_MSB (106)";
265
266 debug_state <= "ACK_DATA_H ";
267
268 debug_state <= "REGV_SACK (108)";
269 sda <= '0';
270
271 wait until rising_edge(scl);
272 debug_state <= "SACK_READ (110)";
273 sda <= 'Z';
274 else
275 sda <= 'Z';
276 wait until rising_edge(scl);
277 if sda = '0' then
278 debug_state <= "2ACK_DATA_H ";
279 else
280 exit;
281 end if;
282
283
284 end if;
285
286 wait until falling_edge(scl);
287
288 --------------------------------------------------------------------------------------------------------------------------------------------------------------
289 ---------------------- LEEMOS/ESCRIBIMOS DATA LOW
290 ---------------------------------------------------------------------------------------------------------------------------------------------------------------
291
292 debug_state <= "LEYENDO_DATA_L ";
293
294 for i in 7 downto 0 loop
295 if v_rw = '0' then
296 wait until rising_edge(scl);
297
298 v_data_l(i) := sda;
299 debug_state <= "DATAL CLK NUM i=" & integer'image(i);
300
301 wait until rising_edge(sda) or falling_edge(sda) or falling_edge(scl);
302
303 if scl = '1' then
304 if sda = '1' then
305 v_stop_seen := true;
306 debug_state <= "STOP_DETECTADO ";
307 exit;
308
309 elsif sda = '0' then
310 -- SDA bajó = START
311 v_start_seen := true;
312 debug_state <= "START_DETECTADO ";
313 exit;
314
315 end if;
316 else
317 debug_state <= "MAS_DATOS ";
318 end if;
319 else
320 if i /= 7 then
321 wait until falling_edge(scl);
322 end if;
323 debug_state <= "R2DATAH CLK NUM i=" & integer'image(i);
324 sda <= regs_core(v_reg_inc)(i);
325 if i = 0 then
326 wait until falling_edge(scl);
327 end if;
328 end if;
329
330 end loop;
331
332 if v_rw = '0' then
333
334 debug_state <= "SAVE REG_V_MSB (106)";
335
336 debug_state <= "ACK_DATA_H ";
337
338 debug_state <= "REGV_SACK (108)";
339 sda <= '0';
340
341 wait until rising_edge(scl);
342 debug_state <= "SACK_READ (110)";
343 sda <= 'Z';
344 else
345 sda <= 'Z';
346 debug_state <= "AAAAAAAAAAA ";
347 wait until rising_edge(scl);
348 if sda = '0' then
349 debug_state <= "2ACK_DATA_H ";
350 else
351 exit;
352 end if;
353
354
355 end if;
356
357
358 wait until falling_edge(scl); -- SCL baja después de leer ACK
359 debug_state <= " (148)";
360
361 v_data_16 := v_data_h & v_data_l;
362 regs_core(v_reg_inc) <= v_data_16;
363
364 if v_reg_inc = 255 then
365 v_reg_inc := 0;
366 else
367 v_reg_inc := v_reg_inc + 1;
368 end if;
369
370 s_reg_addr <= v_reg_inc;
371 end loop;
372 end if;
373
374 end loop; -- loop exterior
375
376 end process i2c_slave;
377
378end Behavioral;
std_logic := '0' clk_int
Definition mt9v111.vhd:30
( 0 to 255) std_logic_vector( 15 downto 0) reg_map_t
Definition mt9v111.vhd:32
string( 1 to 20) :=( others => ' ') debug_state
Definition mt9v111.vhd:49
time := 37 ns PIX_PERIOD
Definition mt9v111.vhd:29
integer range 0 to 255:= 0 read_reg_addr
Definition mt9v111.vhd:48
reg_map_t :=( 16#01#=> x"0001", others => x"0FE0") regs_ifp
Definition mt9v111.vhd:43
reg_map_t :=( 16#00#=> x"823A", 16#0D#=> x"0008", others => x"CACA") regs_core
Definition mt9v111.vhd:38
integer range 0 to 255 s_reg_addr
Definition mt9v111.vhd:50
IMG_WIDTH integer := 640
Definition mt9v111.vhd:14
IMG_HEIGHT integer := 480
Definition mt9v111.vhd:16
out pixclk std_logic
Definition mt9v111.vhd:18
in scl std_logic
Definition mt9v111.vhd:22
I2C_ADDR std_logic_vector( 6 downto 0) := "1011100"
Definition mt9v111.vhd:13
out dout std_logic_vector( 7 downto 0)
Definition mt9v111.vhd:21
out lval std_logic
Definition mt9v111.vhd:20
inout sda std_logic
Definition mt9v111.vhd:24
out fval std_logic
Definition mt9v111.vhd:19