OpenCores
URL https://opencores.org/ocsvn/mips_enhanced/mips_enhanced/trunk

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gleichmann/] [multiio/] [multiio_ea.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
--------------------------------------------------------------------
2
--  Entity:         MultiIO_APB
3
--  File:           MultiIO_APB.vhd
4
--  Author:         Thomas Ameseder, Gleichmann Electronics
5
--  Based on an orginal version by Manfred.Helzle@embedd.it
6
--  
7
--  Description:    APB Multiple digital I/O for minimal User Interface
8
--------------------------------------------------------------------
9
--  Functionality:
10
--  8 LEDs,         active low or high, r/w
11
--  dual 7Segment,  active low or high, w only
12
--  8 DIL Switches, active low or high, r only
13
--  8 Buttons,      active low or high, r only, with IRQ enables
14
--------------------------------------------------------------------
15
 
16
library ieee;
17
use ieee.std_logic_1164.all;
18
 
19
library grlib;
20
use grlib.amba.all;
21
use grlib.stdlib.all;
22
use grlib.devices.all;
23
 
24
library gleichmann;
25
use gleichmann.spi.all;
26
use gleichmann.i2c.all;
27
use gleichmann.miscellaneous.all;
28
use gleichmann.ge_clkgen.all;
29
use gleichmann.multiio.all;
30
 
31
--  pragma translate_off
32
use std.textio.all;
33
--  pragma translate_on
34
 
35
 
36
entity MultiIO_APB is
37
  generic (
38
    hpe_version: integer := 0;          -- adapt multiplexing for different boards
39
    pindex : integer := 0;              -- Leon-Index
40
    paddr  : integer := 0;              -- Leon-Address
41
    pmask  : integer := 16#FFF#;        -- Leon-Mask
42
    pirq   : integer := 0;              -- Leon-IRQ
43
 
44
    clk_freq_in : integer := 25_000_000;  -- Leons clock to calculate timings
45
 
46
    led7act   : std_logic := '0';       -- active level for 7Segment
47
    ledact    : std_logic := '0';       -- active level for LEDs
48
    switchact : std_logic := '1';       -- active level for LED's
49
    buttonact : std_logic := '1';       -- active level for LED's
50
 
51
    n_switches  : integer := 8;   -- number of switches that are driven
52
    n_leds      : integer := 8    -- number of LEDs that are driven
53
 
54
    );
55
 
56
  port (
57
    rst_n       : in  std_ulogic;        -- global Reset, active low
58
    clk         : in  std_ulogic;        -- global Clock
59
    apbi        : in  apb_slv_in_type;   -- APB-Input
60
    apbo        : out apb_slv_out_type;  -- APB-Output
61
    MultiIO_in  : in  MultiIO_in_type;   -- MultIO-Inputs
62
    MultiIO_out : out MultiIO_out_type   -- MultiIO-Outputs
63
    );
64
end entity;
65
 
66
 
67
architecture Implementation of MultiIO_APB is  ----------------------
68
 
69
  constant VERSION  : std_logic_vector(31 downto 0) := x"EA_07_12_06";
70
  constant REVISION : integer                       := 1;
71
  constant MUXMAX   : integer                       := 7;
72
 
73
  constant VCC : std_logic_vector(31 downto 0) := (others => '1');
74
  constant GND : std_logic_vector(31 downto 0) := (others => '0');
75
 
76
  signal Enable1ms  : boolean;
77
  signal MUXCounter : integer range 0 to MUXMAX-1;
78
 
79
  signal clkgen_mclk   : std_ulogic;
80
  signal clkgen_bclk   : std_ulogic;
81
  signal clkgen_sclk   : std_ulogic;
82
  signal clkgen_lrclk : std_ulogic;
83
 
84
  type state_t is (WAIT_FOR_SYNC,READY,WAIT_FOR_ACK);
85
  signal state,next_state : state_t;
86
  signal Strobe,next_Strobe                        : std_ulogic;
87
 
88
  -- status signals of the i2s core for upper-level state machine
89
  signal SampleAck, WaitForSample : std_ulogic;
90
  signal samplereg : std_ulogic_vector(N_CODECI2SBITS-1 downto 0);
91
 
92
  constant pconfig : apb_config_type := (
93
 
94
    1 => apb_iobar(paddr, pmask)
95
    );
96
 
97
  type MultiIOregisters is
98
    record
99
      ledreg  : std_logic_vector(31 downto 0);    -- LEDs
100
      led7reg : std_logic_vector(31 downto 0);    -- Dual 7Segment LEDs
101
      codecreg : std_logic_vector(31 downto 0);
102
      codecreg2 : std_logic_vector(31 downto 0);
103
 
104
      -- Switches in
105
      sw_inreg  : std_logic_vector(31 downto 0);
106
      -- ASCII value of input button
107
      btn_inreg : std_logic_vector(31 downto 0);
108
 
109
      irqenareg : std_logic_vector(31 downto 0);  -- IRQ enables for Buttons
110
      btn_irqs  : std_logic_vector(31 downto 0);  -- IRQs from each Button
111
 
112
      new_data : std_ulogic;
113
--      new_data_valid : std_ulogic;
114
      lcdreg : std_logic_vector(31 downto 0);  -- LCD instruction
115
 
116
      --cb1_in_reg : std_logic_vector(31 downto 0);
117
      --cb1_out_reg : std_logic_vector(31 downto 0);
118
 
119
      -- cb3_in_reg : std_logic_vector(31 downto 0);
120
      --cb4_in2_reg : std_logic_vector(31 downto 0);
121
      -- cb3_out_reg : std_logic_vector(31 downto 0);
122
      --cb4_out2_reg : std_logic_vector(31 downto 0);
123
 
124
      exp_in_reg : std_logic_vector(31 downto 0);
125
      exp_out_reg : std_logic_vector(31 downto 0);
126
 
127
      hsc_out_reg : std_logic_vector(31 downto 0);
128
      hsc_in_reg  : std_logic_vector(31 downto 0);
129
    end record;
130
 
131
  signal r, rin : MultiIOregisters;     -- register sets
132
 
133
  signal Key           : std_logic_vector(7 downto 0);  -- ASCII value of button
134
  -- character representation of the key (for simulation purposes)
135
  signal KeyVal        : character;
136
 
137
  signal OldColumnRow1 : std_logic_vector(6 downto 0);  -- for key debounce
138
  signal OldColumnRow2 : std_logic_vector(6 downto 0);  -- for key debounce
139
 
140
begin
141
 
142
  reg_rw : process(MUXCounter, MultiIO_in, apbi, key, r, rst_n)
143
    variable readdata : std_logic_vector(31 downto 0);  -- system bus width
144
    variable irqs     : std_logic_vector(31 downto 0);  -- system IRQs width
145
    variable v        : MultiIOregisters;               -- register set
146
  begin
147
    v := r;
148
 
149
    --  reset registers
150
    if rst_n = '0' then
151
      -- lower half of LEDs on
152
      v.ledreg := (others => '0');
153
      v.ledreg(3 downto 0) := "1111";
154
 
155
      v.led7reg := (others => '0');
156
      v.led7reg(15 downto 0) := X"38_4F";            -- show "L3" Leon3 on 7Segments
157
 
158
      v.codecreg := (others => '0');
159
      v.codecreg2 := (others => '0');
160
      v.irqenareg := (others => '0');   -- IRQs disable
161
      v.btn_inreg := (others => '0');
162
      v.sw_inreg  := (others => '0');
163
 
164
      -- new data flag off
165
      v.new_data := '0';
166
--      v.new_data_valid := '0';
167
      v.lcdreg := (others => '0');
168
 
169
      -- v.cb3_in_reg := (others => '0');
170
      --v.cb4_in2_reg := (others => '0');
171
      -- v.cb3_out_reg := (others => '0');
172
      --v.cb4_out2_reg := (others => '0');
173
 
174
      v.exp_in_reg := (others => '0');
175
      v.exp_out_reg := (others => '0');
176
 
177
      v.hsc_in_reg := (others => '0');
178
      v.hsc_out_reg := (others => '0');
179
    end if;
180
 
181
    --  get switches and buttons
182
    if switchact = '1' then
183
      v.sw_inreg(N_SWITCHES-1 downto 0) := MultiIO_in.switch_in;
184
    else
185
      v.sw_inreg(N_SWITCHES-1 downto 0) := not MultiIO_in.switch_in;
186
    end if;
187
 
188
    v.btn_inreg(7 downto 0) := key;
189
 
190
    v.btn_irqs := (others => '0');
191
 
192
    ---------------------------------------------------------------------------
193
    -- TO BE ALTERED
194
    ---------------------------------------------------------------------------
195
    --  set local button-IRQs
196
    for i in 0 to v.btn_irqs'left loop
197
      -- detect low-to-high transition
198
      if (v.btn_inreg(i) = '1') and (r.btn_inreg(i) = '0') then
199
        -- set local IRQs if IRQ enabled
200
        v.btn_irqs(i) := v.btn_inreg(i) and r.irqenareg(i);
201
      else
202
        -- clear local IRQs
203
        v.btn_irqs(i) := '0';
204
      end if;
205
    end loop;
206
    ---------------------------------------------------------------------------
207
 
208
    --  read registers
209
    readdata := (others => 'X');
210
 
211
    case conv_integer(apbi.paddr(6 downto 2)) is
212
      when 0 => readdata := r.ledreg;   -- LEDs
213
      when 1 => readdata := r.led7reg;  -- seven segment
214
      when 2 => readdata := r.codecreg;  -- codec command register
215
      when 3 => readdata := r.codecreg2;  -- codec i2s register
216
      when 4 => readdata := r.sw_inreg;   -- switches
217
      when 5 => readdata := r.btn_inreg;  -- buttons
218
      when 6 => readdata := r.irqenareg;  -- IRQ enables
219
      when 7 => readdata := conv_std_logic_vector(pirq, 32);  -- IRQ#
220
      when 8 => readdata := version;      -- version
221
      when 9 => readdata := r.lcdreg;   -- LCD data
222
      when 10 => readdata := r.exp_out_reg;  -- expansion connector out
223
      when 11 => readdata := r.exp_in_reg;  -- expansion connector in
224
      when 12 => readdata := r.hsc_out_reg;
225
      when 13 => readdata := r.hsc_in_reg;
226
      --when 14 => readdata := r.cb4_out1_reg;  -- childboard4 connector out
227
      --when 15 => readdata := r.cb4_out2_reg;  -- childboard4 connector out
228
      -- when 14 => readdata := r.cb3_in_reg;  -- childboard3 connector in
229
      -- when 15 => readdata := r.cb3_out_reg;  -- childboard3 connector out
230
      --when 14 => readdata := r.cb1_out_reg;  -- childboard1 connector out
231
      --when 15 => readdata := r.cb1_in_reg;  -- childboard1 connector in
232
      when others => null;
233
    end case;
234
 
235
    --  write registers
236
    if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
237
      case conv_integer(apbi.paddr(6 downto 2)) is
238
        when 0 => v.ledreg :=
239
                    GND(31 downto N_LEDS) &
240
                    apbi.pwdata(N_LEDS-1 downto 0);        -- write LEDs
241
        when 1 => v.led7reg :=
242
                    GND(31 downto N_SEVSEGBITS) &
243
                    apbi.pwdata(N_SEVSEGBITS-1 downto 0);  -- write 7Segment
244
        when 2 => v.codecreg :=
245
                    GND(31 downto N_CODECBITS) &
246
                    apbi.pwdata(N_CODECBITS-1 downto 0);
247
        when 3 => v.codecreg2 :=
248
                    GND(31 downto N_CODECI2SBITS) &
249
                    apbi.pwdata(N_CODECI2SBITS-1 downto 0);
250
        when 6 => v.irqenareg :=
251
                    GND(31 downto N_BUTTONS) &
252
                    apbi.pwdata(N_BUTTONS-1 downto 0);
253
        when 9 => v.lcdreg :=
254
                    GND(31 downto N_LCDBITS) &
255
                    apbi.pwdata(N_LCDBITS-1 downto 0);
256
                  -- signal that new data has arrived
257
--                  v.new_data_valid := '0';
258
                  v.new_data := '1';
259
        when 10 => v.exp_out_reg :=
260
                    GND(31 downto N_EXPBITS/2) &
261
                    -- bit(N_EXPBITS) holds enable signal
262
                    apbi.pwdata(N_EXPBITS/2-1 downto 0);
263
        when 12 => v.hsc_out_reg :=
264
                     GND(31 downto N_HSCBITS) &
265
                     apbi.pwdata(N_HSCBITS-1 downto 0);
266
        --when 14 => v.cb4_out1_reg :=
267
        --             apbi.pwdata(31 downto 0);
268
        -- when 15 => v.cb3_out_reg :=
269
        --              apbi.pwdata(31 downto 0);
270
        --when 14 => v.exp_out_reg :=
271
        --            GND(31 downto 13) &
272
        --            -- bit(N_EXPBITS) holds enable signal
273
        --            apbi.pwdata(12 downto 0);
274
        when others => null;
275
      end case;
276
    end if;
277
 
278
    --  set PIRQ
279
    irqs := (others => '0');
280
    for i in 0 to v.btn_irqs'left loop
281
      -- set IRQ if button-i pressed and IRQ enabled
282
      irqs(pirq) := irqs(pirq) or r.btn_irqs(i);
283
    end loop;
284
 
285
    if ledact = '1' then
286
      MultiIO_out.led_out <= r.ledreg(N_LEDS-1 downto 0);      -- not inverted
287
    else
288
      MultiIO_out.led_out <= not r.ledreg(N_LEDS-1 downto 0);  -- inverted
289
    end if;
290
 
291
    -- disable seven segment and LC display by default
292
--    MultiIO_out.lcd_enable <= '0';
293
    MultiIO_out.lcd_rw     <= r.lcdreg(8);
294
    MultiIO_out.lcd_regsel <= r.lcdreg(9);
295
 
296
    -- reset new lcd data flag
297
    -- will be enabled when new data are written to the LCD register
298
    if MUXCounter = 4 then
299
      v.new_data := '0';
300
--      v.serviced := '1';
301
    end if;
302
 
303
    -- register inputs from expansion connector
304
    v.exp_in_reg(N_EXPBITS/2-1 downto 0) := MultiIO_in.exp_in;
305
 
306
    MultiIO_out.exp_out <= r.exp_out_reg(N_EXPBITS/2-1 downto 0);
307
 
308
    -- high-speed connector
309
    v.hsc_in_reg(N_HSCBITS-1 downto 0) := MultiIO_in.hsc_in;
310
    MultiIO_out.hsc_out <= r.hsc_out_reg(N_HSCBITS-1 downto 0);
311
 
312
    -- configure control port of audio codec for SPI mode
313
    MultiIO_out.codec_mode <= '1';
314
 
315
    apbo.prdata <= readdata;            -- output data to Leon
316
    apbo.pirq   <= irqs;                -- output IRQs to Leon
317
    apbo.pindex <= pindex;              -- output index to Leon
318
 
319
    rin <= v;                           -- update registers
320
 
321
  end process;
322
 
323
 
324
  apbo.pconfig <= pconfig;              -- output config to Leon
325
 
326
 
327
  regs : process(clk)                   -- update registers
328
  begin
329
    if rising_edge(clk) then
330
      r <= rin;
331
    end if;
332
  end process;
333
 
334
 
335
  KeyBoard : process(clk, rst_n)
336
    variable ColumnStrobe : std_logic_vector(2 downto 0);
337
    variable FirstTime    : boolean;
338
    variable NewColumnRow : std_logic_vector(6 downto 0);
339
  begin
340
    if rst_n = '0' then
341
      MultiIO_out.column_out <= (others => '0');  -- all column off
342
      Key                    <= X"40";  -- default '@' after Reset and no key pressed
343
      OldColumnRow1          <= "1111111";
344
      OldColumnRow2          <= "1110011";
345
      ColumnStrobe           := "001";
346
      FirstTime              := true;
347
    elsif rising_edge(clk) then
348
      if Enable1ms then
349
        if MultiIO_in.row_in = "0000" then        -- no key pressed
350
          ColumnStrobe           := ColumnStrobe(1) & ColumnStrobe(0) & ColumnStrobe(2);  -- rotate column
351
          MultiIO_out.column_out <= ColumnStrobe;
352
 
353
          if not FirstTime then
354
            Key <= X"3F";               -- no key pressed '?'
355
          end if;
356
 
357
        else                            -- key pressed
358
          OldColumnRow2 <= OldColumnRow1;
359
 
360
          -- check whether button inputs produce a high or a
361
          -- low level, then assign these inputs in order that
362
          -- they can be decoded into ASCII format
363
          if buttonact = '1' then
364
            NewColumnRow := ColumnStrobe & MultiIO_in.row_in;
365
          else
366
            NewColumnRow := ColumnStrobe & not MultiIO_in.row_in;
367
          end if;
368
 
369
          OldColumnRow1 <= NewColumnRow;
370
 
371
          if (ColumnStrobe & MultiIO_in.row_in = OldColumnRow1) and
372
            (OldColumnRow1 = OldColumnRow2)
373
          then                          -- debounced
374
            FirstTime := false;         -- 1st valid key pressed
375
 
376
            case OldColumnRow2 is       -- decode keys into ascii characters
377
              when "0010001" => Key <= x"31";  -- 1
378
              when "0010010" => Key <= x"34";  -- 4
379
              when "0010100" => Key <= x"37";  -- 7
380
              when "0011000" => Key <= x"43";  -- C
381
              when "0100001" => Key <= x"32";  -- 2
382
              when "0100010" => Key <= x"35";  -- 5
383
              when "0100100" => Key <= x"38";  -- 8
384
              when "0101000" => Key <= x"30";  -- 0
385
              when "1000001" => Key <= x"33";  -- 3
386
              when "1000010" => Key <= x"36";  -- 6
387
              when "1000100" => Key <= x"39";  -- 9
388
              when "1001000" => Key <= x"45";  -- E
389
              when others => Key    <= x"39";  -- ?    -- more than one key pressed
390
            end case;
391
          else
392
            Key <= x"3D";  -- '='    -- bouncing
393
          end if;  -- debounce
394
        end if;  -- MultiIO_in.row_in
395
      end if;  -- Enable1ms
396
    end if;  -- rst_n
397
  end process KeyBoard;
398
 
399
  Multiplex3Sources : if hpe_version = midi generate
400
    Multiplex : process(MUXCounter, r)
401
    begin
402
      -- disable LED output by default
403
      MultiIO_out.led_enable <= '0' xnor ledact;
404
      -- disable 7-segment display by default
405
      MultiIO_out.led_ca_out <= "00" xnor (led7act & led7act);
406
 
407
      -- set enable signal in the middle of LCD timeslots
408
      if MUXCounter = 3 then
409
        MultiIO_out.lcd_enable <= '1';
410
      else
411
        MultiIO_out.lcd_enable <= '0';
412
      end if;
413
 
414
      case MUXCounter is
415
        when 0 | 1 =>
416
          -- output logical value according to active level of the 7segment display
417
          MultiIO_out.led_a_out  <= r.led7reg(MUXCounter*8 + 0) xnor led7act;
418
          MultiIO_out.led_b_out  <= r.led7reg(MUXCounter*8 + 1) xnor led7act;
419
          MultiIO_out.led_c_out  <= r.led7reg(MUXCounter*8 + 2) xnor led7act;
420
          MultiIO_out.led_d_out  <= r.led7reg(MUXCounter*8 + 3) xnor led7act;
421
          MultiIO_out.led_e_out  <= r.led7reg(MUXCounter*8 + 4) xnor led7act;
422
          MultiIO_out.led_f_out  <= r.led7reg(MUXCounter*8 + 5) xnor led7act;
423
          MultiIO_out.led_g_out  <= r.led7reg(MUXCounter*8 + 6) xnor led7act;
424
          MultiIO_out.led_dp_out <= r.led7reg(MUXCounter*8 + 7) xnor led7act;
425
          -- selectively enable the current digit
426
          for i in 0 to 1 loop
427
            if i = MUXCounter then
428
              MultiIO_out.led_ca_out(i) <= '1' xnor led7act;
429
            else
430
              MultiIO_out.led_ca_out(i) <= '0' xnor led7act;
431
            end if;
432
          end loop;  -- i
433
        when 2 | 3 | 4 =>
434
          MultiIO_out.led_a_out  <= r.lcdreg(0);
435
          MultiIO_out.led_b_out  <= r.lcdreg(1);
436
          MultiIO_out.led_c_out  <= r.lcdreg(2);
437
          MultiIO_out.led_d_out  <= r.lcdreg(3);
438
          MultiIO_out.led_e_out  <= r.lcdreg(4);
439
          MultiIO_out.led_f_out  <= r.lcdreg(5);
440
          MultiIO_out.led_g_out  <= r.lcdreg(6);
441
          MultiIO_out.led_dp_out <= r.lcdreg(7);
442
        when 5 | 6 =>
443
          MultiIO_out.led_enable <= '1' xnor ledact;
444
          MultiIO_out.led_a_out  <= r.ledreg(0) xnor ledact;
445
          MultiIO_out.led_b_out  <= r.ledreg(1) xnor ledact;
446
          MultiIO_out.led_c_out  <= r.ledreg(2) xnor ledact;
447
          MultiIO_out.led_d_out  <= r.ledreg(3) xnor ledact;
448
          MultiIO_out.led_e_out  <= r.ledreg(4) xnor ledact;
449
          MultiIO_out.led_f_out  <= r.ledreg(5) xnor ledact;
450
          MultiIO_out.led_g_out  <= r.ledreg(6) xnor ledact;
451
          MultiIO_out.led_dp_out <= r.ledreg(7) xnor ledact;
452
        when others =>
453
          null;
454
      end case;
455
    end process Multiplex;
456
  end generate Multiplex3Sources;
457
 
458
  Multiplex2Sources : if hpe_version /= midi generate
459
    Multiplex : process(MUXCounter, r)
460
    begin
461
      -- disable LED output by default
462
      MultiIO_out.led_enable <= '0' xnor ledact;
463
      -- disable 7-segment display by default
464
      MultiIO_out.led_ca_out <= "00" xnor (led7act & led7act);
465
 
466
      -- set enable signal in the middle of LCD timeslots
467
      if MUXCounter = 3 then
468
        MultiIO_out.lcd_enable <= '1';
469
      else
470
        MultiIO_out.lcd_enable <= '0';
471
      end if;
472
 
473
      case MUXCounter is
474
        when 0 | 1 =>
475
          -- output logical value according to active level of the 7segment display
476
          MultiIO_out.led_a_out  <= r.led7reg(MUXCounter*8 + 0) xnor led7act;
477
          MultiIO_out.led_b_out  <= r.led7reg(MUXCounter*8 + 1) xnor led7act;
478
          MultiIO_out.led_c_out  <= r.led7reg(MUXCounter*8 + 2) xnor led7act;
479
          MultiIO_out.led_d_out  <= r.led7reg(MUXCounter*8 + 3) xnor led7act;
480
          MultiIO_out.led_e_out  <= r.led7reg(MUXCounter*8 + 4) xnor led7act;
481
          MultiIO_out.led_f_out  <= r.led7reg(MUXCounter*8 + 5) xnor led7act;
482
          MultiIO_out.led_g_out  <= r.led7reg(MUXCounter*8 + 6) xnor led7act;
483
          MultiIO_out.led_dp_out <= r.led7reg(MUXCounter*8 + 7) xnor led7act;
484
          -- selectively enable the current digit
485
          for i in 0 to 1 loop
486
            if i = MUXCounter then
487
              MultiIO_out.led_ca_out(i) <= '1' xnor led7act;
488
            else
489
              MultiIO_out.led_ca_out(i) <= '0' xnor led7act;
490
            end if;
491
          end loop;  -- i
492
 
493
        when others =>
494
          MultiIO_out.led_a_out  <= r.lcdreg(0);
495
          MultiIO_out.led_b_out  <= r.lcdreg(1);
496
          MultiIO_out.led_c_out  <= r.lcdreg(2);
497
          MultiIO_out.led_d_out  <= r.lcdreg(3);
498
          MultiIO_out.led_e_out  <= r.lcdreg(4);
499
          MultiIO_out.led_f_out  <= r.lcdreg(5);
500
          MultiIO_out.led_g_out  <= r.lcdreg(6);
501
          MultiIO_out.led_dp_out <= r.lcdreg(7);
502
      end case;
503
    end process Multiplex;
504
  end generate Multiplex2Sources;
505
 
506
 
507
  -- generate prescaler signal every 100 ms
508
  -- control MUXCounter according to input and board type
509
  Count1ms : process(clk, rst_n)
510
    constant divider100ms        : integer := clk_freq_in / 10_000;
511
    variable frequency_counter : integer range 0 to Divider100ms;
512
  begin
513
    if rst_n = '0' then
514
      frequency_counter := Divider100ms;
515
      Enable1ms         <= false;
516
      MUXCounter        <= 0;
517
    elsif rising_edge(clk) then
518
      if frequency_counter = 0 then  -- 1-ms counter has expired
519
        frequency_counter := Divider100ms;
520
        Enable1ms         <= true;
521
 
522
        if (hpe_version = midi) then
523
          -- skip LCD control sequence and go to
524
          -- LED control
525
          if (MUXCounter = 1 and r.new_data = '0') then
526
            MUXCounter <= 5;
527
          -- overflow at maximum counter value for Hpe_midi
528
          elsif MUXCounter = MUXMAX-1 then
529
            MUXCounter <= 0;
530
          else
531
            MUXCounter <= MUXCounter + 1;
532
          end if;
533
        elsif (hpe_version /= midi) then
534
          -- skip LCD control sequence and go back to
535
          -- 7-segment control
536
          if (MUXCounter = 1 and r.new_data = '0') then
537
            MUXCounter <= 0;
538
          -- overflow at maximum counter value for Hpe_mini
539
          elsif MUXCounter = MUXMAX-3 then
540
            MUXCounter <= 0;
541
          else
542
            MUXCounter <= MUXCounter + 1;
543
          end if;
544
        end if;
545
 
546
      else
547
        frequency_counter := frequency_counter - 1;
548
        Enable1ms         <= false;
549
      end if;
550
    end if;
551
  end process;
552
 
553
  ---------------------------------------------------------------------------------------
554
  -- AUDIO CODEC SECTION
555
  ---------------------------------------------------------------------------------------
556
 
557
  tlv320aic23b_audio : if hpe_version = mini_altera generate
558
 
559
    -- audio clock generation
560
    clk_gen : ClockGenerator
561
      port map (
562
        Clk     => clk,
563
        Reset   => rst_n,
564
        omclk   => clkgen_mclk,
565
        obclk   => clkgen_bclk,
566
        osclk   => clkgen_sclk,
567
        olrcout => clkgen_lrclk);
568
 
569
    -- drive clock signals by clock generator
570
    MultiIO_out.CODEC_SCLK   <= clkgen_sclk;
571
    MultiIO_out.CODEC_MCLK   <= clkgen_mclk;
572
    MultiIO_out.CODEC_BCLK   <= clkgen_bclk;
573
    MultiIO_out.CODEC_LRCIN  <= clkgen_lrclk;
574
    MultiIO_out.CODEC_LRCOUT <= clkgen_lrclk;
575
 
576
    -- SPI control interface
577
    spi_xmit_1 : spi_xmit
578
      generic map (
579
        data_width => N_CODECBITS)
580
      port map (
581
        clk_i      => clkgen_SCLK,
582
        rst_i      => rst_n,
583
        data_i     => r.codecreg(N_CODECBITS-1 downto 0),
584
        CODEC_SDIN => MultiIO_out.CODEC_SDIN,
585
        CODEC_CS   => MultiIO_out.CODEC_CS);
586
 
587
    -- I2C data interface
588
    ParToI2s_1 : ParToI2s
589
      generic map (
590
        SampleSize_g => N_CODECI2SBITS)
591
      port map (
592
        Clk_i           => clk,
593
        Reset_i         => rst_n,
594
        SampleLeft_i    => SampleReg,
595
        SampleRight_i   => SampleReg,
596
        StrobeLeft_i    => Strobe,
597
        StrobeRight_i   => Strobe,
598
        SampleAck_o     => SampleAck,
599
        WaitForSample_o => WaitForSample,
600
        SClk_i          => clkgen_sclk,
601
        LRClk_i         => clkgen_lrclk,
602
        SdnyData_o      => MultiIO_out.CODEC_DIN);
603
 
604
    audio_ctrl_sm : process(SampleAck, WaitForSample, state)
605
    begin
606
      next_state  <= state;
607
      next_Strobe <= '0';
608
      case state is
609
        when WAIT_FOR_SYNC =>
610
          if WaitForSample = '1' then
611
            next_state <= READY;
612
          end if;
613
        when READY =>
614
          next_state  <= WAIT_FOR_ACK;
615
          next_Strobe <= '1';
616
        when WAIT_FOR_ACK =>
617
          if SampleAck = '1' then
618
            next_state <= READY;
619
          end if;
620
        when others =>
621
          next_state <= WAIT_FOR_SYNC;
622
      end case;
623
    end process;
624
 
625
    audio_ctrl_reg : process(clk, rst_n)
626
    begin
627
      if rst_n = '0' then               -- asynchronous reset
628
        state     <= WAIT_FOR_SYNC;
629
        Strobe    <= '0';
630
        SampleReg <= (others => '0');
631
      elsif clk'event and clk = '1' then
632
        state  <= next_state;
633
        Strobe <= next_Strobe;
634
        if (next_Strobe) = '1' then
635
--        if Mode = '0' then
636
--          SampleReg <= std_ulogic_vector(unsigned(AudioSample)- X"80");
637
--        else
638
--          SampleReg <= AudioSample;
639
--        end if;
640
          SampleReg <= std_ulogic_vector(r.codecreg2(N_CODECI2SBITS-1 downto 0));
641
        end if;
642
      end if;
643
    end process;
644
 
645
  end generate tlv320aic23b_audio;
646
 
647
 
648
  ---------------------------------------------------------------------------------------
649
  -- DEBUG SECTION
650
  ---------------------------------------------------------------------------------------
651
 
652
--  pragma translate_off
653
  KeyVal <=
654
    ascii2char(conv_integer(Key)) when
655
    (conv_integer(Key) >= 16#30#) and (conv_integer(Key) <= 16#46#)
656
    else 'U';
657
 
658
  bootmsg : report_version
659
    generic map ("MultiIO_APB6:" & tost(pindex) &
660
                 ", Human Interface Controller rev " & tost(REVISION) &
661
                 ", IRQ " & tost(pirq));
662
--  pragma translate_on
663
 
664
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.