1 | library IEEE;
|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
3 | use IEEE.NUMERIC_STD.ALL;
|
4 |
|
5 |
|
6 | entity SpectrumAnalyzer is
|
7 |
|
8 | Port ( CLOCK_50 : in STD_LOGIC; --Board Clock
|
9 | DOUT : out STD_LOGIC; --ADC Channel selection
|
10 | ADC_IN : in STD_LOGIC; -- ADC Data
|
11 | CS : out STD_LOGIC; -- Chip Select ADC
|
12 | SCLK : out STD_LOGIC; -- SERIAL CLOCK FOR ADC
|
13 | LEDS : out STD_LOGIC_VECTOR(7 downto 0); -- Debugging with LEDS
|
14 |
|
15 | DispDataOUT : out STD_LOGIC_VECTOR(15 downto 0);
|
16 | DispRD : out STD_LOGIC;
|
17 | DispCS : out STD_LOGIC;
|
18 | DispWR : out STD_LOGIC;
|
19 | DispDC : out STD_LOGIC );
|
20 | end SpectrumAnalyzer;
|
21 |
|
22 |
|
23 |
|
24 | architecture Behavioral of SpectrumAnalyzer is
|
25 |
|
26 | TYPE STATE_TYPE is (default, Start, DB11, DB10, DB9, DB8, DB7, DB6, DB5, DB4, DB3, DB2, DB1, DB0); -- ADC STATE MACHINE
|
27 | signal ADC_DATA : STATE_TYPE :=default; --ADC Daten state machine
|
28 |
|
29 | TYPE SPEICHER is array (0 to 1023) of std_logic_vector(11 downto 0);
|
30 | signal FRAME : SPEICHER; --array für bilddarstellung
|
31 |
|
32 | TYPE STATE_TYPE2 is (ONE, TWO, THREE, FOUR, FIVE); --haupt state machine
|
33 | signal STATE_MACHINE : STATE_TYPE2 := ONE;
|
34 |
|
35 | signal framedatumzaehler: integer range 0 to 1023:=0; --zählt hoch, bis FRAME mit adc werten voll ist
|
36 |
|
37 | --display initialisierung
|
38 | -- MSB <= [D15....D0, RD, CS, WR, D/C] =>LSB
|
39 | type disp_init is array (0 to 76) of std_logic_vector(19 downto 0);
|
40 | signal disp_init_array: disp_init:=(
|
41 |
|
42 | "00000000000001111100", -- adress register 7
|
43 | "00000000000001111000", --CS low
|
44 | "00000000000001111100", -- reg R07h angesprochen
|
45 |
|
46 | "00000000001000011101", -- write 21h into register 7h
|
47 | "00000000001000011001", -- cs low
|
48 | "00000000001000011101", --21h in register 7h geschrieben
|
49 | --next
|
50 |
|
51 | "00000000000000001100", -- adress 00h
|
52 | "00000000000000001000",
|
53 | "00000000000000001100", --00h adressed
|
54 |
|
55 | "00000000000000011101", --write 1h in 00h
|
56 | "00000000000000011001",
|
57 | "00000000000000011101", --1h written
|
58 | --next
|
59 |
|
60 | "00000000000001111100", --set R07h at 0023h
|
61 | "00000000000001111000", --CS low
|
62 | "00000000000001111100",
|
63 |
|
64 | "00000000001000111101",
|
65 | "00000000001000111001", --
|
66 | "00000000001000111101", --0023h in R07h written
|
67 | -- next
|
68 |
|
69 | "00000000000100001100", --set R10h at 000h
|
70 | "00000000000100001000",
|
71 | "00000000000100001100",
|
72 |
|
73 | "00000000000000001101",
|
74 | "00000000000000001001",
|
75 | "00000000000000001101", --00h in R10h written
|
76 | --next
|
77 |
|
78 | "00000000000000000000", --dummy data --24
|
79 | -- 30ms warten....zähler in state machine einbauen
|
80 | --next
|
81 |
|
82 | "00000000000001111100", --set R07h at 0033h
|
83 | "00000000000001111000",
|
84 | "00000000000001111100",
|
85 |
|
86 | "00000000001100111101",
|
87 | "00000000001100111001",
|
88 | "00000000001100111101",--0033h in R07h written
|
89 | -- next
|
90 |
|
91 | "00000000000100011100", --entry mode setting R11h
|
92 | "00000000000100011000",
|
93 | "00000000000100011100",
|
94 |
|
95 | "01101000001100001101", -- write data in r11h
|
96 | "01101000001100001001",
|
97 | "01101000001100001101",
|
98 | -- next
|
99 |
|
100 | "00000000000000101100", --lcd driver AC setting R02h
|
101 | "00000000000000101000",
|
102 | "00000000000000101100",
|
103 |
|
104 | "00000000000000001101",
|
105 | "00000000000000001001",
|
106 | "00000000000000001101",-- write data 0000000
|
107 | -- next
|
108 | ---write ram data
|
109 |
|
110 | --testweise ein pixel setzen
|
111 | "00000000010011101100", --set RAM adress R4Eh (X_POS)
|
112 | "00000000010011101000",
|
113 | "00000000010011101100",
|
114 |
|
115 | "00000000000011101101",
|
116 | "00000000000011101001",
|
117 | "00000000000011101101",--10dec in RAM adress R4Eh
|
118 | -- next
|
119 |
|
120 | "00000000010011111100", --set RAM adress R4Fh (Y_POS)
|
121 | "00000000010011111000",
|
122 | "00000000010011111100",
|
123 |
|
124 | "00000000000011101101",
|
125 | "00000000000011101001",
|
126 | "00000000000011101101",-- 10dec in RAM adress R4Fh
|
127 | -- next
|
128 |
|
129 | "00000000001000101100", --adress GRAM Data R22h
|
130 | "00000000001000101000",
|
131 | "00000000001000101100",
|
132 |
|
133 | "11111000000000001101",-- start with first pixel
|
134 | "11111000000000001001",
|
135 | "11111000000000001101",
|
136 | -- next
|
137 |
|
138 | "00000111111000001101", -- start with second pixel
|
139 | "00000111111000001001",
|
140 | "00000111111000001101",
|
141 | -- next
|
142 |
|
143 | "00000000000111111101", -- start with third pixel
|
144 | "00000000000111111001",
|
145 | "00000000000111111101",
|
146 |
|
147 | "11111000000000001101",-- start with first pixel
|
148 | "11111000000000001001",
|
149 | "11111000000000001101",
|
150 | -- next
|
151 |
|
152 | "00000111111000001101", -- start with second pixel
|
153 | "00000111111000001001",
|
154 | "00000111111000001101",
|
155 | -- next
|
156 |
|
157 | "00000000000111111101", -- start with third pixel
|
158 | "00000000000111111001",
|
159 | "00000000000111111101",
|
160 |
|
161 | "00000000000000000000"); --dummy data --76
|
162 |
|
163 |
|
164 |
|
165 | signal lcd_init_counter : integer range 0 to 76:=0;
|
166 | signal lcd_wait30ms : integer range 0 to 100000:=1;
|
167 | signal DispDat: std_logic_vector(19 downto 0); --signal from array to pins
|
168 |
|
169 |
|
170 | signal CS_sig : std_logic:='1'; --chip select
|
171 | signal subcounter: integer range 0 to 16:=0; --50MHz/16 = 3.125 MHz -> 195,3 kHz für Datenaustakten bei 16 bit pro datenaustaktung
|
172 | signal SCLK_sig: std_logic:='1'; -- serial clock
|
173 | signal counthilo: integer range 0 to 32:=0; -- Taktflankenzähler für ADC
|
174 | signal DATEN: std_logic_vector(11 downto 0):="000000000000"; --ADC Daten
|
175 | signal DIN : std_logic:='0'; --ADC input
|
176 | signal DATAREADY: std_logic:='0'; -- ist high, wenn Datum eingelesen wurde
|
177 | signal CLOCK_sig: std_logic; -- signal des board clocks
|
178 | signal DOUT_sig : std_logic:='0'; -- channel output
|
179 |
|
180 | begin
|
181 |
|
182 |
|
183 | process (CLOCK_sig)
|
184 | begin
|
185 |
|
186 | if CLOCK_sig='1' AND CLOCK_sig'Event then
|
187 |
|
188 | if subcounter<15 then
|
189 | subcounter<=subcounter+1;
|
190 | else
|
191 | subcounter<=0;
|
192 | end if;
|
193 |
|
194 |
|
195 | case ADC_DATA is
|
196 |
|
197 | when default => CS_sig<='1';
|
198 | SCLK_sig<='1';
|
199 | counthilo<=0;
|
200 | ADC_DATA<=Start;
|
201 |
|
202 | when Start => CS_sig<='0';
|
203 | if subcounter=0 then --vereinfachter Übergang
|
204 | ADC_DATA<=DB11;
|
205 | end if;
|
206 |
|
207 | when DB11 => if subcounter=0 then
|
208 | SCLK_sig<= not SCLK_sig;
|
209 | counthilo<=counthilo+1;
|
210 | end if;
|
211 | if counthilo=10 AND subcounter=0 then
|
212 | Daten(11)<=DIN;
|
213 | ADC_DATA<=DB10;
|
214 | end if;
|
215 |
|
216 | when DB10=> if subcounter=0 then
|
217 | SCLK_sig<= not SCLK_sig;
|
218 | counthilo<=counthilo+1;
|
219 | end if;
|
220 | if counthilo=12 AND subcounter=0 then
|
221 | Daten(10)<=DIN;
|
222 | ADC_Data<=DB9;
|
223 | end if;
|
224 |
|
225 | when DB9 => if subcounter=0 then
|
226 | SCLK_sig<= not SCLK_sig;
|
227 | counthilo<=counthilo+1;
|
228 | end if;
|
229 | if counthilo=14 AND subcounter=0 then
|
230 | Daten(9)<=DIN;
|
231 | ADC_Data<=DB8;
|
232 | end if;
|
233 |
|
234 | when DB8 => if subcounter=0 then
|
235 | SCLK_sig<= not SCLK_sig;
|
236 | counthilo<=counthilo+1;
|
237 | end if;
|
238 | if counthilo=16 AND subcounter=0 then
|
239 | Daten(8)<=DIN;
|
240 | ADC_DATA<=DB7;
|
241 | end if;
|
242 |
|
243 | when DB7 => if subcounter=0 then
|
244 | SCLK_sig<= not SCLK_sig;
|
245 | counthilo<=counthilo+1;
|
246 | end if;
|
247 | if counthilo=18 AND subcounter=0 then
|
248 | Daten(7)<=DIN;
|
249 | ADC_Data<=DB6;
|
250 | end if;
|
251 |
|
252 | when DB6 => if subcounter=0 then
|
253 | SCLK_sig<= not SCLK_sig;
|
254 | counthilo<=counthilo+1;
|
255 | end if;
|
256 | if counthilo=20 AND subcounter=0 then
|
257 | Daten(6)<=DIN;
|
258 | ADC_Data<=DB5;
|
259 | end if;
|
260 |
|
261 | when DB5 => if subcounter=0 then
|
262 | SCLK_sig<= not SCLK_sig;
|
263 | counthilo<=counthilo+1;
|
264 | end if;
|
265 | if counthilo=22 AND subcounter=0 then
|
266 | Daten(5)<=DIN;
|
267 | ADC_DATA<=DB4;
|
268 | end if;
|
269 |
|
270 | when DB4 => if subcounter=0 then
|
271 | SCLK_sig<= not SCLK_sig;
|
272 | counthilo<=counthilo+1;
|
273 | end if;
|
274 | if counthilo=24 AND subcounter=0 then
|
275 | Daten(4)<=DIN;
|
276 | ADC_Data<=DB3;
|
277 | end if;
|
278 |
|
279 | when DB3 => if subcounter=0 then
|
280 | SCLK_sig<= not SCLK_sig;
|
281 | counthilo<=counthilo+1;
|
282 | end if;
|
283 | if counthilo=26 AND subcounter=0 then
|
284 | Daten(3)<=DIN;
|
285 | ADC_Data<=DB2;
|
286 | end if;
|
287 |
|
288 | when DB2 => if subcounter=0 then
|
289 | SCLK_sig<= not SCLK_sig;
|
290 | counthilo<=counthilo+1;
|
291 | end if;
|
292 | if counthilo=28 AND subcounter=0 then
|
293 | Daten(2)<=DIN;
|
294 | ADC_DATA<=DB1;
|
295 | end if;
|
296 |
|
297 | when DB1 => if subcounter=0 then
|
298 | SCLK_sig<= not SCLK_sig;
|
299 | counthilo<=counthilo+1;
|
300 | end if;
|
301 | if counthilo=30 AND subcounter=0 then
|
302 | Daten(1)<=DIN;
|
303 | ADC_Data<=DB0;
|
304 | end if;
|
305 |
|
306 | when DB0 => if subcounter=0 AND counthilo<32 then
|
307 | SCLK_sig<= not SCLK_sig;
|
308 | counthilo<=counthilo+1;
|
309 | end if;
|
310 | if counthilo=32 AND subcounter=0 then
|
311 | Daten(0)<=DIN;
|
312 | ADC_Data<=DB11;
|
313 | DATAREADY<='1';
|
314 | counthilo<=1;
|
315 | SCLK_sig<= not SCLK_sig;
|
316 | end if;
|
317 |
|
318 | end case;
|
319 |
|
320 |
|
321 | if subcounter=0 then -- langsamere schleife für statemachine
|
322 |
|
323 | case STATE_MACHINE is
|
324 |
|
325 | when ONE => framedatumzaehler<=0;
|
326 | lcd_init_counter<=0;
|
327 | lcd_wait30ms<=0;
|
328 |
|
329 | STATE_MACHINE<=THREE;
|
330 |
|
331 |
|
332 |
|
333 |
|
334 | when TWO => if DATAREADY='1' then
|
335 | FRAME(framedatumzaehler)<=Daten; --daten von adc in frame speichern
|
336 | DATAREADY<='0';
|
337 | end if;
|
338 | if framedatumzaehler<1023 then
|
339 | framedatumzaehler<=framedatumzaehler+1;
|
340 | else
|
341 | STATE_MACHINE<=THREE; --wenn frame mit adc werten voll -> next state
|
342 | end if;
|
343 |
|
344 |
|
345 | when THREE =>
|
346 | if lcd_init_counter<24 then
|
347 | -- MSB <= [D15....D0, RD, CS, WR, D/C] =>LSB
|
348 | DispDat(19 downto 0) <=disp_init_array(lcd_init_counter);
|
349 |
|
350 | elsif lcd_init_counter=24 then --wait 30ms
|
351 |
|
352 | if lcd_wait30ms<90000 then
|
353 | lcd_wait30ms<=lcd_wait30ms+1;
|
354 | else
|
355 | lcd_init_counter<=lcd_init_counter+1;
|
356 | end if;
|
357 |
|
358 | elsif lcd_init_counter>24 then
|
359 |
|
360 | DispDat(19 downto 0) <= disp_init_array(lcd_init_counter);
|
361 |
|
362 |
|
363 | if lcd_init_counter=76 then
|
364 | STATE_MACHINE<=FOUR;
|
365 | end if;
|
366 |
|
367 | end if;
|
368 | lcd_init_counter<=lcd_init_counter+1;
|
369 |
|
370 |
|
371 | when FOUR =>
|
372 |
|
373 |
|
374 |
|
375 |
|
376 | when FIVE => STATE_MACHINE<=FIVE;
|
377 |
|
378 |
|
379 | end case;
|
380 |
|
381 | end if;
|
382 |
|
383 |
|
384 | end if;
|
385 |
|
386 |
|
387 | end process;
|
388 |
|
389 | CLOCK_sig <= CLOCK_50;
|
390 | DOUT <= DOUT_sig;
|
391 | DIN <= ADC_IN;
|
392 | CS<= CS_sig;
|
393 | SCLK <= SCLK_sig;
|
394 |
|
395 | DispDataOUT <= DispDat(19 downto 4);
|
396 | DispRD <= DispDat (3);
|
397 | DispCS <= DispDat (2);
|
398 | DispWR <= DispDat (1);
|
399 | DispDC <= DispDat (0);
|
400 |
|
401 | LEDS(7) <= DispDat(7);
|
402 | LEDS(6) <= DispDat(6);
|
403 | LEDS(5) <= DispDat(5);
|
404 | LEDS(4) <= DispDat(4);
|
405 | LEDS(3) <= DispDat(3);
|
406 | LEDS(2) <= DispDat(2);
|
407 | LEDS(1) <= DispDat(1);
|
408 | LEDS(0) <= DispDat(0);
|
409 |
|
410 | end Behavioral;
|