FP_Setup_Type.vhd


1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity FP_Setup is
7
  generic
8
  (  ClockDiv    : integer := 7              -- Frequenzen: FP_DClk = Clock / ClockDiv
9
  );
10
  port
11
  (  Clock      : in std_logic;
12
    FP_DIn      : in std_logic;              -- SPI Data in
13
    FP_DClk      : out std_logic;            -- SPI Clock
14
    FP_DStb      : out std_logic;            -- SPI Data strobe
15
    FP_DOut      : out std_logic;            -- SPI Data out
16
    CY7_DIn      : in std_logic;              -- SPI Data in
17
    CY7_DClk    : in std_logic;              -- SPI Clock
18
    CY7_DStb    : in std_logic;              -- SPI Data strobe
19
    CY7_DOut    : out std_logic;            -- SPI Data out
20
    SampleRate    : out std_logic_vector (4 downto 0);  -- -> I2S_Master.vhd
21
    NoOfChannels  : out std_logic_vector (4 downto 0);  -- 0..31: 1..32 Channels used
22
    SelChannel    : out std_logic_vector (4 downto 0);  -- Listen to Channel 1..32
23
    SelMono      : out std_logic;            -- Listen to Channel Mono
24
    SetupChanged  : out std_logic              -- SampleRate or NoOfChannels changed
25
  );
26
end FP_Setup ;
27
28
architecture Default of FP_Setup is
29
30
  type   SLV_CY7_Bytes is array(integer range <>) of std_logic_vector(7 downto 0);
31
  signal Init        : boolean;
32
  signal ClockCount    : integer range 0 to ClockDiv;
33
  signal SPI_Status    : integer range 0 to 24;        -- 24 Data Bits + Strobe
34
  signal MuxCount      : std_logic_vector(2 downto 0);      -- Multiplex 8 7-Segment Digits
35
  signal StateTa1      : integer range 0 to 2;          -- 0: Ruhe, 1: Ta gedrückt, 2: Sw gedreht
36
  signal InputShift    : std_logic_vector(5 downto 0);
37
  signal InputReg      : std_logic_vector(5 downto 0);      -- Bit 5..0: Sw1, Sw2, Ta1, Ta2
38
  signal InputReg2    : std_logic_vector(5 downto 0);      -- Bit 5..0: Sw1, Sw2, Ta1, Ta2
39
  signal CY7_ClkDly    : std_logic_vector(1 to 2);              -- 
40
  signal CY7_DInDly    : std_logic_vector(1 to 2);              -- 
41
  signal CY7_StbDly    : std_logic_vector(1 to 2);              -- 
42
  signal CY7_InShift    : std_logic_vector(31 downto 0);    --
43
  signal CY7_InReg    : std_logic_vector(31 downto 0);    --
44
  signal CY7_OutShift    : std_logic_vector(31 downto 0);    --
45
  -- Einstellungen:
46
  signal SRate      : std_logic_vector(4 downto 0);      -- -> I2S_Master.vhd
47
  signal NChannels    : std_logic_vector(4 downto 0);      -- 0..31: Max. 32 Channels used
48
  signal SChannel      : std_logic_vector(4 downto 0);      -- 0..31: Listen to Channel 1..32
49
  signal SMono      : std_logic;              -- Listen to Channel Mono
50
  -- Für die Anzeige:
51
  signal NumVal32      : std_logic_vector(7 downto 0);      -- NChannels + 1, SChannel + 1, binär
52
  signal BCD_Val32    : std_logic_vector(7 downto 0);      -- NChannels + 1, SChannel + 1, BCD
53
  signal BCD_ValSR    : std_logic_vector(15 downto 0);    -- Sample Rate BCD
54
  signal DP_SR      : integer range 2 to 5;          -- Position des Dezimalpunkts SR
55
  signal BCD7SegIn    : std_logic_vector(3 downto 0);      -- Eingabe 7-Segment Encoder
56
  signal BCD7SegOut    : std_logic_vector(7 downto 0);      -- Ausgabe 7-Segment Encoder
57
58
begin
59
60
  CY7_Communication : process (Clock) begin
61
    -- Datenblatt: At both low and high speed in Mode 0, data on RXD0
62
    -- is sampled two CLKOUT cycles before the rising clock edge on TXD0.
63
    if Clock = '1' and Clock'event then
64
      CY7_ClkDly <= CY7_DClk & CY7_ClkDly(1);
65
      CY7_DInDly <= CY7_DIn & CY7_DInDly(1);
66
      CY7_StbDly <= CY7_DStb & CY7_StbDly(1);
67
      if CY7_ClkDly = "10" then
68
        CY7_InShift <= CY7_DInDly(2) & CY7_InShift(CY7_InShift'high downto 1);
69
      end if;
70
      if CY7_StbDly = "10"  then
71
        CY7_InReg <= CY7_InShift;
72
        CY7_OutShift <= CY7_InShift;
73
      end if;
74
      if CY7_ClkDly = "10" then
75
        CY7_OutShift <= '0' & CY7_OutShift(CY7_OutShift'high downto 1);
76
      end if;
77
      CY7_DOut <= CY7_OutShift(0);
78
    end if;
79
  end process CY7_Communication;
80
81
  SPI_and_Settings : process (Clock) begin
82
    if Clock = '1' and Clock'event then
83
      if not Init then
84
        NChannels <= (others => '1');
85
        Init <= true;
86
      end if;
87
      ClockCount <= ClockCount + 1;
88
      if ClockCount = ClockDiv / 2 then
89
        FP_DStb <= '0';
90
        FP_DClk <= '1';
91
      end if;
92
      if ClockCount = 0 then
93
        SetupChanged <= '0';
94
        if InputReg(5) = '0' then
95
          -- Taste Sw1 (Kanäle) gedrückt: Umschalten Mono/Stero bei Listen to Channel?
96
          if StateTa1 < 2 then
97
            StateTa1 <= 1;
98
          end if;
99
        else
100
          if StateTa1 = 1 then
101
            SMono <= not SMono;
102
          end if;
103
          StateTa1 <= 0;
104
        end if;
105
        if SPI_Status = 24 then
106
          -- Restart SPI-Tx
107
          SPI_Status <= 0;
108
          FP_DStb <= '1';
109
          MuxCount <= MuxCount + 1;          -- Mux Digit 0..7
110
        else
111
          -- Continue SPI-Tx
112
          SPI_Status <= SPI_Status + 1;
113
          FP_DClk <= '0';
114
          InputShift <= InputShift(4 downto 0) & FP_DIn;
115
          if SPI_Status = 8 then
116
            -- 1 Byte data input
117
            InputReg <= InputShift;
118
            InputReg2 <= InputReg;
119
            if InputReg(4) = '0' then
120
              -- Taste Sw2 (Sample Rate) gedrückt
121
              case InputReg2(1 downto 0) & InputReg(1 downto 0) is
122
                -- Sample Rate
123
                when "0100" | "1011" => if SRate > 0 then
124
                              SRate <= SRate - 1;
125
                              SetupChanged <= '1';
126
                              if SRate = 4 then
127
                                -- 128 kHz überspringen
128
                                SRate <= "00001";
129
                              elsif SRate(1 downto 0) = "00" then
130
                                -- 8, 16, 32, 64 kHz nicht mit 22 MHz Oszillator
131
                                SRate <= SRate - 2;
132
                              end if;
133
                            end if;
134
                when "0001" | "1110" => if SRate < 18 then
135
                              SRate <= SRate + 1;
136
                              SetupChanged <= '1';
137
                              if SRate = 1 then
138
                                -- 128 kHz überspringen
139
                                SRate <= "00100";
140
                              elsif SRate(1 downto 0) = "10" then
141
                                -- 8, 16, 32, 64 kHz nicht mit 22 MHz Oszillator
142
                                SRate <= SRate + 2;
143
                              end if;
144
                            end if;
145
                when others => null;
146
              end case;
147
            end if;
148
            if InputReg(5) = '0' then
149
              -- Taste Sw1 (Kanäle) gedrückt
150
              case InputReg2(3 downto 2) & InputReg(3 downto 2) is
151
                -- Number of Channels
152
                when "0100" | "1011" => if NChannels < 31 then 
153
                              NChannels <= NChannels + 1;
154
                              SetupChanged <= '1';
155
                            end if;
156
                            StateTa1 <= 2;        -- Keine Mono/Stereo-Umschaltung
157
                when "0001" | "1110" => if NChannels > 0 then 
158
                              NChannels <= NChannels - 1;
159
                              SetupChanged <= '1';
160
                              if SChannel > NChannels then 
161
                                SChannel <= NChannels;
162
                              end if;
163
                            end if;
164
                            StateTa1 <= 2;        -- Keine Mono/Stereo-Umschaltung
165
                when others => null;
166
              end case;
167
            else
168
              -- Taste Sw1 (Kanäle) gelöst
169
              case InputReg2(3 downto 2) & InputReg(3 downto 2) is
170
                -- Selected Channel
171
                when "0100" | "1011" =>  if SChannel < NChannels then 
172
                              SChannel <= SChannel + 1;
173
                            end if;
174
                when "0001" | "1110" => if SChannel > 0 then 
175
                              SChannel <= SChannel - 1;
176
                            end if;
177
                when others => null;
178
              end case;
179
            end if;
180
            if SChannel > NChannels then 
181
              SChannel <= NChannels;
182
            end if;
183
          end if;
184
        end if;
185
      end if;
186
    end if;
187
  end process SPI_and_Settings;
188
189
  with conv_integer(SRate) select
190
  BCD_ValSR <=  x"1920" when 0,
191
          x"1764" when 1,
192
          x"f960" when 4,
193
          x"f882" when 5,
194
          x"f640" when 6,
195
          x"f480" when 8,
196
          x"f441" when 9,
197
          x"f320" when 10,
198
          x"f240" when 12,
199
          x"2205" when 13,
200
          x"f160" when 14,
201
          x"f120" when 16,
202
          x"1102" when 17,
203
          x"ff80" when others;
204
205
  with conv_integer(SRate) select
206
    DP_SR <=   3 when 13 | 17,
207
          4 when others;
208
  
209
  NumVal32 <= "000" & NChannels + 1 when MuxCount < 4
210
       else "000" & SChannel + 1;
211
  
212
  BCD_Val32 <= NumVal32 +  0 when NumVal32 < 10
213
      else NumVal32 +  6 when NumVal32 < 20
214
      else NumVal32 + 12 when NumVal32 < 30
215
      else NumVal32 + 18;
216
217
  BCD7SegIn <= BCD_Val32(3 downto 0)   when MuxCount = 1 or MuxCount = 7
218
      else BCD_ValSR(15 downto 12) when MuxCount = 2
219
      else BCD_ValSR(11 downto 8)  when MuxCount = 3
220
      else BCD_ValSR(7 downto 4)   when MuxCount = 4
221
      else BCD_ValSR(3 downto 0)   when MuxCount = 5
222
      else x"f" when BCD_Val32(7 downto 4) = 0  -- 0 & 6
223
      else BCD_Val32(7 downto 4);          -- 0 & 6
224
225
  with conv_integer(BCD7SegIn) select
226
    BCD7SegOut <=  x"fc" when 0,
227
            x"60" when 1,
228
            x"da" when 2,
229
            x"f2" when 3,
230
            x"66" when 4,
231
            x"b6" when 5,
232
            x"be" when 6,
233
            x"e0" when 7,
234
            x"fe" when 8,
235
            x"f6" when 9,
236
            x"00" when others;
237
238
  FP_DOut <=  SMono when (MuxCount = 7) and (SPI_Status = 9) else                -- Dez. Punkt für SelMono
239
        '1' when (MuxCount = DP_SR) and (SPI_Status = 9) else              -- Dez. Punkt für Sample Rate
240
        BCD7SegOut(SPI_Status - 9) when (SPI_Status >= 9) and (SPI_Status <= 16) else  --  8..15: Segm.-LEDs
241
        '0' when SPI_Status - 17 = not MuxCount else                  -- 16..23: Anode driver on
242
        '1';                                      --  0..7 and Anode driver off 
243
244
  SampleRate <= SRate;
245
  NoOfChannels <= NChannels;
246
  SelChannel <= SChannel;
247
  SelMono <= SMono;
248
249
end Default;