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 332

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 322 jshamlet
-- VHDL units : o8_ltc2355_2p
25 191 jshamlet
-- 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 224 jshamlet
--
34
--            : Works best when the clock frequency is 96MHz or lower. Module
35
--            :  will divide the clock by 2 if it is greater than this.
36
--
37 322 jshamlet
-- Register Map:
38
-- Offset  Bitfield Description                        Read/Write
39
--   0x0   AAAAAAAA ADC Channel 1 Data(7:0)              (RO)
40
--   0x1   --AAAAAA ADC Channel 1 Data(13:8)             (RO)
41
--   0x2   AAAAAAAA ADC Channel 2 Data(7:0)              (RO)
42
--   0x3   --AAAAAA ADC Channel 2 Data(13:8) (reduced)   (RO)
43
--   0x4   AAAAAAAA ADC Channel 1 Data(13:6) (reduced)   (RO)
44
--   0x5   AAAAAAAA ADC Channel 2 Data(13:6)             (RO)
45
--   0x6   AAAAAAAA Update / Sample Rate (in uS)         (RW)
46
--   0x7   A------- Force Trigger / Status               (RW)
47
--
48 224 jshamlet
-- Revision History
49
-- Author          Date     Change
50
------------------ -------- ---------------------------------------------------
51 322 jshamlet
-- Seth Henry      12/14/20 Forked
52 191 jshamlet
 
53
library ieee;
54
use ieee.std_logic_1164.all;
55
use ieee.std_logic_unsigned.all;
56
use ieee.std_logic_arith.all;
57
use ieee.std_logic_misc.all;
58
 
59
library work;
60
  use work.open8_pkg.all;
61
 
62
entity o8_ltc2355_2p is
63
generic(
64 224 jshamlet
  Clock_Frequency            : real;
65
  Address                    : ADDRESS_TYPE
66 191 jshamlet
);
67
port(
68 223 jshamlet
  Open8_Bus                  : in  OPEN8_BUS_TYPE;
69 327 jshamlet
  Write_Qual                 : in  std_logic := '1';
70 191 jshamlet
  Rd_Data                    : out DATA_TYPE;
71
  Interrupt                  : out std_logic;
72
  -- ADC IF
73
  ADC_SCLK                   : out std_logic;
74
  ADC_CONV                   : out std_logic;
75
  ADC_DATA1                  : in  std_logic;
76
  ADC_DATA2                  : in  std_logic
77
);
78
end entity;
79
 
80
architecture behave of o8_ltc2355_2p is
81
 
82 224 jshamlet
  alias Clock                is Open8_Bus.Clock;
83
  alias Reset                is Open8_Bus.Reset;
84
  alias uSec_Tick            is Open8_Bus.uSec_Tick;
85 191 jshamlet
 
86 224 jshamlet
  constant Divide_SCLK_by_2  : boolean := (Clock_Frequency > 96000000.0);
87
 
88 191 jshamlet
  constant User_Addr         : std_logic_vector(15 downto 3) := Address(15 downto 3);
89 223 jshamlet
  alias  Comp_Addr           is Open8_Bus.Address(15 downto 3);
90 322 jshamlet
  signal Addr_Match          : std_logic := '0';
91 244 jshamlet
  alias  Reg_Sel_d           is Open8_Bus.Address(2 downto 0);
92 322 jshamlet
  signal Reg_Sel_q           : std_logic_vector(2 downto 0) := (others => '0');
93 244 jshamlet
  signal Wr_En_d             : std_logic := '0';
94
  signal Wr_En_q             : std_logic := '0';
95
  alias  Wr_Data_d           is Open8_Bus.Wr_Data;
96
  signal Wr_Data_q           : DATA_TYPE := x"00";
97
  signal Rd_En_d             : std_logic := '0';
98
  signal Rd_En_q             : std_logic := '0';
99 191 jshamlet
 
100 322 jshamlet
  signal User_Trig           : std_logic := '0';
101 191 jshamlet
 
102 322 jshamlet
  signal Timer_Int           : DATA_TYPE := (others => '0');
103
  signal Timer_Cnt           : DATA_TYPE := (others => '0');
104
  signal Timer_Trig          : std_logic := '0';
105 191 jshamlet
 
106
  type ADC_STATES is ( IDLE, START, CLK_HIGH, CLK_HIGH2, CLK_LOW, CLK_LOW2, UPDATE );
107
  signal ad_state            : ADC_STATES;
108
 
109 322 jshamlet
  signal rx_buffer1          : std_logic_vector(16 downto 0) := (others => '0');
110
  signal rx_buffer2          : std_logic_vector(16 downto 0) := (others => '0');
111
  signal bit_cntr            : std_logic_vector(4 downto 0) := (others => '0');
112 191 jshamlet
  constant BIT_COUNT         : std_logic_vector(4 downto 0) :=
113
                                conv_std_logic_vector(16,5);
114
 
115 322 jshamlet
  signal ADC1_Data           : std_logic_vector(13 downto 0) := (others => '0');
116
  signal ADC2_Data           : std_logic_vector(13 downto 0) := (others => '0');
117
  signal ADC_Ready           : std_logic := '0';
118
 
119 191 jshamlet
begin
120
 
121
  Addr_Match                 <= '1' when Comp_Addr = User_Addr else '0';
122 327 jshamlet
  Wr_En_d                    <= Addr_Match and Write_Qual and Open8_Bus.Wr_En;
123 244 jshamlet
  Rd_En_d                    <= Addr_Match and Open8_Bus.Rd_En;
124 191 jshamlet
 
125
  io_reg: process( Clock, Reset )
126
  begin
127
    if( Reset = Reset_Level )then
128 244 jshamlet
      Reg_Sel_q              <= "000";
129
      Wr_En_q                <= '0';
130 191 jshamlet
      Wr_Data_q              <= x"00";
131 244 jshamlet
      Rd_En_q                <= '0';
132 191 jshamlet
      Rd_Data                <= OPEN8_NULLBUS;
133 244 jshamlet
 
134 191 jshamlet
      User_Trig              <= '0';
135
      Timer_Int              <= x"00";
136
    elsif( rising_edge( Clock ) )then
137 244 jshamlet
      Reg_Sel_q              <= Reg_Sel_d;
138
 
139
      Wr_En_q                <= Wr_En_d;
140
      Wr_Data_q              <= Wr_Data_d;
141
 
142 191 jshamlet
      User_Trig              <= '0';
143 244 jshamlet
      if( Wr_En_q = '1' )then
144 191 jshamlet
        if( Reg_Sel_q = "110" )then
145
          Timer_Int          <= Wr_Data_q;
146
        end if;
147
        if( Reg_Sel_q = "111" )then
148
          User_Trig          <= '1';
149
        end if;
150
      end if;
151
 
152 244 jshamlet
      Rd_En_q                <= Rd_En_d;
153 191 jshamlet
      Rd_Data                <= OPEN8_NULLBUS;
154 244 jshamlet
      if( Rd_En_q = '1' )then
155 191 jshamlet
        case( Reg_Sel_q )is
156
          -- Channel 1, Full resolution, lower byte
157
          when "000" =>
158
            Rd_Data          <= ADC1_Data(7 downto 0);
159
          -- Channel 1, Full resolution, upper byte
160
          when "001" =>
161
            Rd_Data          <= "00" & ADC1_Data(13 downto 8);
162
          -- Channel 2, Full resolution, lower byte
163
          when "010" =>
164
            Rd_Data          <= ADC2_Data(7 downto 0);
165
          -- Channel 2, Full resolution, upper byte
166
          when "011" =>
167
            Rd_Data          <= "00" & ADC2_Data(13 downto 8);
168
          -- Channel 1, 8-bit resolution
169
          when "100" =>
170
            Rd_Data          <= ADC1_Data(13 downto 6);
171
          -- Channel 2, 8-bit resolution
172
          when "101" =>
173
            Rd_Data          <= ADC2_Data(13 downto 6);
174
          -- Self-update rate
175
          when "110" =>
176
            Rd_Data          <= Timer_Int;
177
          -- Interface status
178
          when "111" =>
179
            Rd_Data(7)       <= ADC_Ready;
180
          when others =>
181
            null;
182
        end case;
183
      end if;
184
    end if;
185
  end process;
186
 
187
  Interval_proc: process( Clock, Reset )
188
  begin
189
    if( Reset = Reset_Level )then
190
      Timer_Cnt              <= x"00";
191
      Timer_Trig             <= '0';
192
    elsif( rising_edge(Clock) )then
193
      Timer_Trig             <= '0';
194
      Timer_Cnt              <= Timer_Cnt - uSec_Tick;
195
      if( or_reduce(Timer_Cnt) = '0' )then
196
        Timer_Cnt            <= Timer_Int;
197
        Timer_Trig           <= or_reduce(Timer_Int); -- Only issue output on Int > 0
198
      end if;
199
    end if;
200
  end process;
201
 
202
  ADC_IO_FSM: process( Clock, Reset )
203
  begin
204
    if( Reset = Reset_Level )then
205
      ad_state               <= IDLE;
206
      ADC_Ready              <= '0';
207
 
208
      rx_buffer1             <= (others => '0');
209
      rx_buffer2             <= (others => '0');
210
 
211
      bit_cntr               <= (others => '0');
212
 
213
      ADC1_Data              <= (others => '0');
214
      ADC2_Data              <= (others => '0');
215
 
216
      ADC_SCLK               <= '1';
217
      ADC_CONV               <= '0';
218
 
219
      Interrupt              <= '0';
220
    elsif( rising_edge(Clock) )then
221
      ADC_Ready              <= '0';
222
      ADC_SCLK               <= '1';
223
      ADC_CONV               <= '0';
224
 
225
      Interrupt              <= '0';
226
 
227
      case( ad_state )is
228
        when IDLE =>
229
          ADC_Ready          <= '1';
230
          if( (User_Trig or Timer_Trig) = '1' )then
231
            ad_state         <= START;
232
          end if;
233
 
234
        when START =>
235
          ADC_SCLK           <= '0';
236
          ADC_CONV           <= '1';
237
          bit_cntr           <= BIT_COUNT;
238
          ad_state           <= CLK_HIGH;
239
 
240
        when CLK_HIGH =>
241
          ad_state           <= CLK_LOW;
242
          if( Divide_SCLK_by_2 )then
243
            ad_state         <= CLK_HIGH2;
244
          end if;
245
 
246
        when CLK_HIGH2 =>
247
          ad_state           <= CLK_LOW;
248
 
249
        when CLK_LOW =>
250
          ADC_SCLK           <= '0';
251
          rx_buffer1(conv_integer(bit_cntr)) <= ADC_DATA1;
252
          rx_buffer2(conv_integer(bit_cntr)) <= ADC_DATA2;
253
          bit_cntr           <= bit_cntr - 1;
254
          ad_state           <= CLK_HIGH;
255
          if( bit_cntr = 0 )then
256
            ad_state         <= UPDATE;
257
          elsif( Divide_SCLK_by_2 )then
258
            ad_state         <= CLK_LOW2;
259
          end if;
260
 
261
        when CLK_LOW2 =>
262
          ADC_SCLK           <= '0';
263
          ad_state           <= CLK_HIGH;
264
 
265
        when UPDATE =>
266
          ADC_SCLK           <= '0';
267
          ad_state           <= IDLE;
268
          ADC1_Data          <= rx_buffer1(14 downto 1);
269
          ADC2_Data          <= rx_buffer2(14 downto 1);
270
          Interrupt          <= '1';
271
 
272
        when others =>
273
          null;
274
      end case;
275
 
276
    end if;
277
  end process;
278
 
279 322 jshamlet
end architecture;

powered by: WebSVN 2.1.0

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