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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [o8_ltc2355_2p.vhd] - Blame information for rev 223

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 194 jshamlet
-- Copyright (c)2013, 2020 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 220 jshamlet
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 194 jshamlet
--
24 191 jshamlet
-- VHDL units : ltc2355_2p
25
-- Description: Reads out a pair of LTC2355 14-bit ADCs which are wired with
26
--            :  common clock and CONVERT START inputs. Because they are
27
--            :  synchronized, this entity provides simultaneously updated
28
--            :  parallel data buses.
29
--
30
-- Notes      : Depends on the fact that the two LTC2355 converters are wired
31
--            :  with their SCLK and CONV lines tied together, and DATA1 and
32
--            :  DATA2 independently routed to separate I/O pins.
33
 
34
library ieee;
35
use ieee.std_logic_1164.all;
36
use ieee.std_logic_unsigned.all;
37
use ieee.std_logic_arith.all;
38
use ieee.std_logic_misc.all;
39
 
40
library work;
41
  use work.open8_pkg.all;
42
 
43
entity o8_ltc2355_2p is
44
generic(
45
  Address                    : ADDRESS_TYPE;
46
  Reset_Level                : std_logic;
47
  Sys_Freq                   : real
48
);
49
port(
50
  Clock                      : in  std_logic; -- 96MHz MAX for proper operation
51
  Reset                      : in  std_logic;
52
  uSec_Tick                  : in  std_logic;
53 223 jshamlet
  --
54
  Open8_Bus                  : in  OPEN8_BUS_TYPE;
55 191 jshamlet
  Rd_Data                    : out DATA_TYPE;
56
  Interrupt                  : out std_logic;
57
  -- ADC IF
58
  ADC_SCLK                   : out std_logic;
59
  ADC_CONV                   : out std_logic;
60
  ADC_DATA1                  : in  std_logic;
61
  ADC_DATA2                  : in  std_logic
62
);
63
end entity;
64
 
65
architecture behave of o8_ltc2355_2p is
66
 
67
  constant Divide_SCLK_by_2  : boolean := (Sys_Freq > 96000000.0);
68
 
69
  constant User_Addr         : std_logic_vector(15 downto 3) := Address(15 downto 3);
70 223 jshamlet
  alias  Comp_Addr           is Open8_Bus.Address(15 downto 3);
71
  alias  Reg_Sel             is Open8_Bus.Address(2 downto 0);
72 191 jshamlet
  signal Reg_Sel_q           : std_logic_vector(2 downto 0);
73
  signal Wr_Data_q           : DATA_TYPE;
74
  signal Addr_Match          : std_logic;
75
  signal Wr_En               : std_logic;
76
  signal Rd_En               : std_logic;
77
  signal User_In             : DATA_TYPE;
78
 
79
  signal User_Trig           : std_logic;
80
 
81
  signal Timer_Int           : DATA_TYPE;
82
  signal Timer_Cnt           : DATA_TYPE;
83
  signal Timer_Trig          : std_logic;
84
 
85
  type ADC_STATES is ( IDLE, START, CLK_HIGH, CLK_HIGH2, CLK_LOW, CLK_LOW2, UPDATE );
86
  signal ad_state            : ADC_STATES;
87
 
88
  signal rx_buffer1          : std_logic_vector(16 downto 0);
89
  signal rx_buffer2          : std_logic_vector(16 downto 0);
90
  signal bit_cntr            : std_logic_vector(4 downto 0);
91
  constant BIT_COUNT         : std_logic_vector(4 downto 0) :=
92
                                conv_std_logic_vector(16,5);
93
 
94
  signal ADC1_Data           : std_logic_vector(13 downto 0);
95
  signal ADC2_Data           : std_logic_vector(13 downto 0);
96
  signal ADC_Ready           : std_logic;
97
begin
98
 
99
  Addr_Match                 <= '1' when Comp_Addr = User_Addr else '0';
100
 
101
  io_reg: process( Clock, Reset )
102
  begin
103
    if( Reset = Reset_Level )then
104
      Reg_Sel_q              <= (others => '0');
105
      Wr_Data_q              <= x"00";
106
      Wr_En                  <= '0';
107
      Rd_En                  <= '0';
108
      Rd_Data                <= OPEN8_NULLBUS;
109
      User_Trig              <= '0';
110
      Timer_Int              <= x"00";
111
    elsif( rising_edge( Clock ) )then
112
      Reg_Sel_q              <= Reg_Sel;
113 223 jshamlet
      Wr_Data_q              <= Open8_Bus.Wr_Data;
114
      Wr_En                  <= Addr_Match and Open8_Bus.Wr_En;
115 191 jshamlet
      User_Trig              <= '0';
116
      if( Wr_En = '1' )then
117
        if( Reg_Sel_q = "110" )then
118
          Timer_Int          <= Wr_Data_q;
119
        end if;
120
        if( Reg_Sel_q = "111" )then
121
          User_Trig          <= '1';
122
        end if;
123
      end if;
124
 
125 223 jshamlet
      Rd_En                  <= Addr_Match and Open8_Bus.Rd_En;
126 191 jshamlet
      Rd_Data                <= OPEN8_NULLBUS;
127
 
128
      if( Rd_En = '1' )then
129
        case( Reg_Sel_q )is
130
          -- Channel 1, Full resolution, lower byte
131
          when "000" =>
132
            Rd_Data          <= ADC1_Data(7 downto 0);
133
          -- Channel 1, Full resolution, upper byte
134
          when "001" =>
135
            Rd_Data          <= "00" & ADC1_Data(13 downto 8);
136
          -- Channel 2, Full resolution, lower byte
137
          when "010" =>
138
            Rd_Data          <= ADC2_Data(7 downto 0);
139
          -- Channel 2, Full resolution, upper byte
140
          when "011" =>
141
            Rd_Data          <= "00" & ADC2_Data(13 downto 8);
142
          -- Channel 1, 8-bit resolution
143
          when "100" =>
144
            Rd_Data          <= ADC1_Data(13 downto 6);
145
          -- Channel 2, 8-bit resolution
146
          when "101" =>
147
            Rd_Data          <= ADC2_Data(13 downto 6);
148
          -- Self-update rate
149
          when "110" =>
150
            Rd_Data          <= Timer_Int;
151
          -- Interface status
152
          when "111" =>
153
            Rd_Data(7)       <= ADC_Ready;
154
          when others =>
155
            null;
156
        end case;
157
      end if;
158
    end if;
159
  end process;
160
 
161
  Interval_proc: process( Clock, Reset )
162
  begin
163
    if( Reset = Reset_Level )then
164
      Timer_Cnt              <= x"00";
165
      Timer_Trig             <= '0';
166
    elsif( rising_edge(Clock) )then
167
      Timer_Trig             <= '0';
168
      Timer_Cnt              <= Timer_Cnt - uSec_Tick;
169
      if( or_reduce(Timer_Cnt) = '0' )then
170
        Timer_Cnt            <= Timer_Int;
171
        Timer_Trig           <= or_reduce(Timer_Int); -- Only issue output on Int > 0
172
      end if;
173
    end if;
174
  end process;
175
 
176
  ADC_IO_FSM: process( Clock, Reset )
177
  begin
178
    if( Reset = Reset_Level )then
179
      ad_state               <= IDLE;
180
      ADC_Ready              <= '0';
181
 
182
      rx_buffer1             <= (others => '0');
183
      rx_buffer2             <= (others => '0');
184
 
185
      bit_cntr               <= (others => '0');
186
 
187
      ADC1_Data              <= (others => '0');
188
      ADC2_Data              <= (others => '0');
189
 
190
      ADC_SCLK               <= '1';
191
      ADC_CONV               <= '0';
192
 
193
      Interrupt              <= '0';
194
    elsif( rising_edge(Clock) )then
195
      ADC_Ready              <= '0';
196
      ADC_SCLK               <= '1';
197
      ADC_CONV               <= '0';
198
 
199
      Interrupt              <= '0';
200
 
201
      case( ad_state )is
202
        when IDLE =>
203
          ADC_Ready          <= '1';
204
          if( (User_Trig or Timer_Trig) = '1' )then
205
            ad_state         <= START;
206
          end if;
207
 
208
        when START =>
209
          ADC_SCLK           <= '0';
210
          ADC_CONV           <= '1';
211
          bit_cntr           <= BIT_COUNT;
212
          ad_state           <= CLK_HIGH;
213
 
214
        when CLK_HIGH =>
215
          ad_state           <= CLK_LOW;
216
          if( Divide_SCLK_by_2 )then
217
            ad_state         <= CLK_HIGH2;
218
          end if;
219
 
220
        when CLK_HIGH2 =>
221
          ad_state           <= CLK_LOW;
222
 
223
        when CLK_LOW =>
224
          ADC_SCLK           <= '0';
225
          rx_buffer1(conv_integer(bit_cntr)) <= ADC_DATA1;
226
          rx_buffer2(conv_integer(bit_cntr)) <= ADC_DATA2;
227
          bit_cntr           <= bit_cntr - 1;
228
          ad_state           <= CLK_HIGH;
229
          if( bit_cntr = 0 )then
230
            ad_state         <= UPDATE;
231
          elsif( Divide_SCLK_by_2 )then
232
            ad_state         <= CLK_LOW2;
233
          end if;
234
 
235
        when CLK_LOW2 =>
236
          ADC_SCLK           <= '0';
237
          ad_state           <= CLK_HIGH;
238
 
239
        when UPDATE =>
240
          ADC_SCLK           <= '0';
241
          ad_state           <= IDLE;
242
          ADC1_Data          <= rx_buffer1(14 downto 1);
243
          ADC2_Data          <= rx_buffer2(14 downto 1);
244
          Interrupt          <= '1';
245
 
246
        when others =>
247
          null;
248
      end case;
249
 
250
    end if;
251
  end process;
252
 
253
end architecture;

powered by: WebSVN 2.1.0

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