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

Subversion Repositories opb_usblite

[/] [opb_usblite/] [trunk/] [pcores/] [opb_usblite_v1_00_a/] [hdl/] [vhdl/] [usb_init.vhdl] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rehnmaak
--
2
--  USB 2.0 Initialization, handshake and reset detection.
3
--
4
--  This entity provides the following functions:
5
--
6
--    * USB bus attachment: At powerup and after a RESET signal, switch to
7
--      non-driving mode, wait for 17 ms, then attach to the USB bus. This
8
--      should ensure that the host notices our reattachment and initiates
9
--      a reset procedure.
10
--
11
--    * High speed handshake (if HSSUPPORT enabled): attempt to enter
12
--      high speed mode after a bus reset.
13
--
14
--    * Monitor the linestate for reset and/or suspend signalling.
15
--
16
--  The low-level interface connects to an UTMI compliant USB PHY such as
17
--  the SMSC GT3200. The UTMI interface must be configured for 60 MHz operation
18
--  with an 8-bit data bus.
19
--
20
 
21
library ieee;
22
use ieee.std_logic_1164.all, ieee.numeric_std.all;
23
 
24
entity usb_init is
25
 
26
    generic (
27
 
28
        -- Support high speed mode.
29
        HSSUPPORT : boolean := false );
30
 
31
    port (
32
 
33
        -- 60 MHz UTMI clock.
34
        CLK :           in std_logic;
35
 
36
        -- Synchronous reset; triggers detach and reattach to the USB bus.
37
        RESET :         in std_logic;
38
 
39
        -- High for one clock if a reset signal is detected on the USB bus.
40
        I_USBRST :      out std_logic;
41
 
42
        -- High when attached to the host in high speed mode.
43
        I_HIGHSPEED :   out std_logic;
44
 
45
        -- High when suspended.
46
        -- Reset of this signal is asynchronous.
47
        -- This signal may be used to drive (inverted) the UTMI SuspendM pin.
48
        I_SUSPEND :     out std_logic;
49
 
50
        -- High to tell usb_packet that it must drive a continuous K state.
51
        P_CHIRPK :      out std_logic;
52
 
53
        -- Connect to the UTMI Reset signal.
54
        PHY_RESET :     out std_logic;
55
 
56
        -- Connect to the UTMI LineState signal.
57
        PHY_LINESTATE : in std_logic_vector(1 downto 0);
58
 
59
        -- Cconnect to the UTMI OpMode signal.
60
        PHY_OPMODE :    out std_logic_vector(1 downto 0);
61
 
62
        -- Connect to the UTMI XcvrSelect signal (0 = high speed, 1 = full speed).
63
        PHY_XCVRSELECT : out std_logic;
64
 
65
        -- Connect to the UTMI TermSelect signal (0 = high speed, 1 = full speed).
66
        PHY_TERMSELECT : out std_logic );
67
 
68
end entity usb_init;
69
 
70
architecture usb_init_arch of usb_init is
71
 
72
    -- Time from bus idle until device suspend (3 ms).
73
    constant TIME_SUSPEND : unsigned(19 downto 0) := to_unsigned(180000, 20);
74
 
75
    -- Time from start of SE0 until detection of reset signal (2.5 us + 10%).
76
    constant TIME_RESET :   unsigned(7 downto 0)  := to_unsigned(165, 8);
77
 
78
    -- Time to wait for good SE0 when waking up from suspend (6 ms).
79
    constant TIME_SUSPRST:  unsigned(19 downto 0) := to_unsigned(360000, 20);
80
 
81
    -- Duration of chirp K from device during high speed detection (1 ms + 10%).
82
    constant TIME_CHIRPK :  unsigned(19 downto 0) := to_unsigned(66000, 20);
83
 
84
    -- Minimum duration of chirp J/K during high speed detection (2.5 us + 10%).
85
    constant TIME_FILT :    unsigned(7 downto 0)  := to_unsigned(165, 8);
86
 
87
    -- Time to wait for chirp until giving up (1.1 ms).
88
    constant TIME_WTFS :    unsigned(19 downto 0) := to_unsigned(66000, 20);
89
 
90
    -- Time to wait after reverting to full-speed before sampling the bus (100 us).
91
    constant TIME_WTRSTHS : unsigned(19 downto 0) := to_unsigned(6000, 20);
92
 
93
    -- State machine
94
    type t_state is (
95
        ST_INIT, ST_FSRESET, ST_FULLSPEED, ST_SUSPEND, ST_SUSPRESET,
96
        ST_SENDCHIRP, ST_RECVCHIRP, ST_HIGHSPEED, ST_HSREVERT );
97
    signal s_state :        t_state := ST_INIT;
98
 
99
    -- Timers.
100
    signal s_timer1 :       unsigned(7 downto 0);
101
    signal s_timer2 :       unsigned(19 downto 0) := to_unsigned(0, 20);
102
 
103
    -- Count J/K chirps.
104
    signal s_chirpcnt :     unsigned(2 downto 0);
105
 
106
    -- High if the device is operating in high speed (or suspended from high speed).
107
    signal s_highspeed :    std_logic := '0';
108
 
109
    -- High if the device is currently suspended.
110
    -- Reset of this signal is asynchronous.
111
    signal s_suspend :      std_logic := '0';
112
 
113
    -- Input registers.
114
    signal s_linestate :    std_logic_vector(1 downto 0);
115
 
116
    -- Output registers.
117
    signal s_reset :        std_logic := '1';
118
    signal s_opmode :       std_logic_vector(1 downto 0) := "01";
119
    signal s_xcvrselect :   std_logic := '1';
120
    signal s_termselect :   std_logic := '1';
121
    signal s_chirpk :       std_logic := '0';
122
 
123
begin
124
 
125
    I_USBRST    <= s_reset;
126
    I_HIGHSPEED <= s_highspeed;
127
    I_SUSPEND   <= s_suspend;
128
    P_CHIRPK    <= s_chirpk;
129
    PHY_RESET   <= s_reset;
130
    PHY_OPMODE  <= s_opmode;
131
    PHY_XCVRSELECT <= s_xcvrselect;
132
    PHY_TERMSELECT <= s_termselect;
133
 
134
    -- Synchronous process.
135
    process is
136
        variable v_clrtimer1 : std_logic;
137
        variable v_clrtimer2 : std_logic;
138
    begin
139
        wait until rising_edge(CLK);
140
 
141
        -- By default, do not clear the timers.
142
        v_clrtimer1 := '0';
143
        v_clrtimer2 := '0';
144
 
145
        -- Register linestate input.
146
        s_linestate <= PHY_LINESTATE;
147
 
148
        -- Default assignments to registers.
149
        s_reset     <= '0';
150
        s_chirpk    <= '0';
151
 
152
        if RESET = '1' then
153
 
154
            -- Reset PHY.
155
            s_reset      <= '1';
156
            s_opmode     <= "01";
157
            s_xcvrselect <= '1';
158
            s_termselect <= '1';
159
 
160
            -- Go to ST_INIT state and wait until bus attachment.
161
            v_clrtimer1  := '1';
162
            v_clrtimer2  := '1';
163
            s_highspeed  <= '0';
164
            s_state      <= ST_INIT;
165
 
166
        else
167
 
168
            case s_state is
169
 
170
                when ST_INIT =>
171
                    -- Wait before attaching to bus.
172
                    s_opmode     <= "01";   -- non-driving
173
                    s_xcvrselect <= '1';    -- full speed
174
                    s_termselect <= '1';    -- full speed
175
                    v_clrtimer1  := '1';
176
                    if s_timer2 = to_unsigned(0, s_timer2'length) - 1 then
177
                        -- Timer2 overflows after ~ 17 ms; attach to bus.
178
                        v_clrtimer2 := '1';
179
                        s_state     <= ST_FULLSPEED;
180
                    end if;
181
 
182
                when ST_FSRESET =>
183
                    -- Waiting for end of reset before full speed operation.
184
                    s_highspeed  <= '0';
185
                    s_opmode     <= "00";   -- normal
186
                    s_xcvrselect <= '1';    -- full speed
187
                    s_termselect <= '1';    -- full speed
188
                    v_clrtimer1  := '1';
189
                    v_clrtimer2  := '1';
190
                    if s_linestate /= "00" then
191
                        -- Reset signal ended.
192
                        s_state     <= ST_FULLSPEED;
193
                    end if;
194
 
195
                when ST_FULLSPEED =>
196
                    -- Operating in full speed.
197
                    s_highspeed  <= '0';
198
                    s_opmode     <= "00";   -- normal
199
                    s_xcvrselect <= '1';    -- full speed
200
                    s_termselect <= '1';    -- full speed
201
                    if s_linestate /= "00" then
202
                        -- Bus not in SE0 state; clear reset timer.
203
                        v_clrtimer1 := '1';
204
                    end if;
205
                    if s_linestate /= "01" then
206
                        -- Bus not in J state; clear suspend timer.
207
                        v_clrtimer2 := '1';
208
                    end if;
209
                    if s_timer1 = TIME_RESET then
210
                        -- Bus has been in SE0 state for TIME_RESET;
211
                        -- this is a reset signal.
212
                        s_reset     <= '1';
213
                        if HSSUPPORT then
214
                            s_state     <= ST_SENDCHIRP;
215
                        else
216
                            s_state     <= ST_FSRESET;
217
                        end if;
218
                    elsif s_timer2 = TIME_SUSPEND then
219
                        -- Bus has been idle for TIME_SUSPEND;
220
                        -- go to suspend state.
221
                        s_state     <= ST_SUSPEND;
222
                    end if;
223
 
224
                when ST_SUSPEND =>
225
                    -- Suspended; waiting for resume signal.
226
                    -- Possibly our clock will be disabled; wake up
227
                    -- is initiated by the asynchronous reset of s_suspend.
228
                    s_opmode     <= "00";   -- normal   
229
                    s_xcvrselect <= '1';    -- full speed
230
                    s_termselect <= '1';    -- full speed
231
                    v_clrtimer1  := '1';
232
                    v_clrtimer2  := '1';
233
                    if s_linestate /= "01" then
234
                        -- Bus not in J state; resume.
235
                        if HSSUPPORT and s_highspeed = '1' then
236
                            -- High speed resume protocol.
237
                            if s_linestate = "10" then
238
                                -- Bus in K state; resume to high speed.
239
                                s_state     <= ST_HIGHSPEED;
240
                            elsif s_linestate = "00" then
241
                                -- Bus in SE0 state; start reset detection.
242
                                s_state     <= ST_SUSPRESET;
243
                            end if;
244
                        else
245
                            -- Resume to full speed.
246
                            s_state     <= ST_FULLSPEED;
247
                        end if;
248
                    end if;
249
 
250
                when ST_SUSPRESET =>
251
                    -- Wake up in SE0 state; wait for proper reset signal.
252
                    s_opmode     <= "00";   -- normal   
253
                    s_xcvrselect <= '1';    -- full speed
254
                    s_termselect <= '1';    -- full speed
255
                    if s_linestate /= "00" then
256
                        -- Bus not in SE0 state; clear reset timer.
257
                        v_clrtimer1 := '1';
258
                    end if;
259
                    if s_timer1 = TIME_RESET then
260
                        -- Bus has been in SE0 state for TIME_RESET;
261
                        -- this is a reset signal.
262
                        s_reset     <= '1';
263
                        v_clrtimer2 := '1';
264
                        s_state     <= ST_SENDCHIRP;
265
                    end if;
266
                    if s_timer2 = TIME_SUSPRST then
267
                        -- Still no proper reset signal; go back to sleep.
268
                        s_state     <= ST_SUSPEND;
269
                    end if;
270
 
271
                when ST_SENDCHIRP =>
272
                    -- Sending chirp K for a duration of TIME_CHIRPK.
273
                    s_highspeed  <= '0';
274
                    s_opmode     <= "10";   -- disable bit stuffing
275
                    s_xcvrselect <= '0';    -- high speed
276
                    s_termselect <= '1';    -- full speed
277
                    s_chirpk     <= '1';    -- send chirp K
278
                    v_clrtimer1  := '1';
279
                    if s_timer2 = TIME_CHIRPK then
280
                        -- end of chirp K
281
                        v_clrtimer2 := '1';
282
                        s_chirpcnt  <= "000";
283
                        s_state     <= ST_RECVCHIRP;
284
                    end if;
285
 
286
                when ST_RECVCHIRP =>
287
                    -- Waiting for K-J-K-J-K-J chirps.
288
                    -- Note: DO NOT switch Opmode to normal yet; there
289
                    -- may be pending bits in the transmission buffer.
290
                    s_opmode     <= "10";   -- disable bit stuffing
291
                    s_xcvrselect <= '0';    -- high speed
292
                    s_termselect <= '1';    -- full speed
293
                    if ( s_chirpcnt(0) = '0' and s_linestate /= "10" ) or
294
                       ( s_chirpcnt(0) = '1' and s_linestate /= "01" ) then
295
                        -- Not the linestate we want.
296
                        v_clrtimer1 := '1';
297
                    end if;
298
                    if s_timer2 = TIME_WTFS then
299
                        -- High speed detection failed; go to full speed.
300
                        v_clrtimer1 := '1';
301
                        v_clrtimer2 := '1';
302
                        s_state     <= ST_FSRESET;
303
                    elsif s_timer1 = TIME_FILT then
304
                        -- We got the chirp we wanted.
305
                        if s_chirpcnt = 5 then
306
                            -- This was the last chirp;
307
                            -- we got a successful high speed handshake.
308
                            v_clrtimer2 := '1';
309
                            s_state     <= ST_HIGHSPEED;
310
                        end if;
311
                        s_chirpcnt  <= s_chirpcnt + 1;
312
                        v_clrtimer1 := '1';
313
                    end if;
314
 
315
                when ST_HIGHSPEED =>
316
                    -- Operating in high speed.
317
                    s_highspeed  <= '1';
318
                    s_opmode     <= "00";   -- normal
319
                    s_xcvrselect <= '0';    -- high speed
320
                    s_termselect <= '0';    -- high speed
321
                    if s_linestate /= "00" then
322
                        -- Bus not idle; clear revert timer.
323
                        v_clrtimer2 := '1';
324
                    end if;
325
                    if s_timer2 = TIME_SUSPEND then
326
                        -- Bus has been idle for TIME_SUSPEND;
327
                        -- revert to full speed.
328
                        v_clrtimer2 := '1';
329
                        s_state     <= ST_HSREVERT;
330
                    end if;
331
 
332
                when ST_HSREVERT =>
333
                    -- Revert to full speed and wait for 100 us.
334
                    s_opmode     <= "00";   -- normal
335
                    s_xcvrselect <= '1';    -- full speed
336
                    s_termselect <= '1';    -- full speed
337
                    if s_timer2 = TIME_WTRSTHS then
338
                        v_clrtimer2 := '1';
339
                        if s_linestate = "00" then
340
                            -- Reset from high speed.
341
                            s_reset     <= '1';
342
                            s_state     <= ST_SENDCHIRP;
343
                        else
344
                            -- Suspend from high speed.
345
                            s_state     <= ST_SUSPEND;
346
                        end if;
347
                    end if;
348
 
349
            end case;
350
 
351
        end if;
352
 
353
        -- Increment or clear timer1.
354
        if v_clrtimer1 = '1' then
355
            s_timer1 <= to_unsigned(0, s_timer1'length);
356
        else
357
            s_timer1 <= s_timer1 + 1;
358
        end if;
359
 
360
        -- Increment or clear timer2.
361
        if v_clrtimer2 = '1' then
362
            s_timer2 <= to_unsigned(0, s_timer2'length);
363
        else
364
            s_timer2 <= s_timer2 + 1;
365
        end if;
366
 
367
    end process;
368
 
369
    -- Drive the s_suspend flipflop (synchronous set, asynchronous reset).
370
    process (CLK, PHY_LINESTATE) is
371
    begin
372
        if PHY_LINESTATE /= "01" then
373
            -- The bus is not in full speed idle state;
374
            -- reset the s_suspend flipflop.
375
            s_suspend   <= '0';
376
        elsif rising_edge(CLK) then
377
            if s_state = ST_SUSPEND then
378
                -- Bus is idle and FSM is in suspend state;
379
                -- enable the s_suspend flipflop.
380
                s_suspend   <= '1';
381
            end if;
382
        end if;
383
    end process;
384
 
385
end architecture usb_init_arch;
386
 

powered by: WebSVN 2.1.0

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