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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [usb/] [slave/] [current/] [host/] [usbhost.tcl] - Blame information for rev 825

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

Line No. Rev Author Line
1 786 skrzyp
# {{{  Banner                                           
2
 
3
#===============================================================================
4
#
5
#    usbhost.tcl
6
#
7
#    Support for USB testing
8
#
9
#===============================================================================
10
## ####ECOSGPLCOPYRIGHTBEGIN####                                            
11
## -------------------------------------------                              
12
## This file is part of eCos, the Embedded Configurable Operating System.   
13
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
14
##
15
## eCos is free software; you can redistribute it and/or modify it under    
16
## the terms of the GNU General Public License as published by the Free     
17
## Software Foundation; either version 2 or (at your option) any later      
18
## version.                                                                 
19
##
20
## eCos is distributed in the hope that it will be useful, but WITHOUT      
21
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
22
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
23
## for more details.                                                        
24
##
25
## You should have received a copy of the GNU General Public License        
26
## along with eCos; if not, write to the Free Software Foundation, Inc.,    
27
## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
28
##
29
## As a special exception, if other files instantiate templates or use      
30
## macros or inline functions from this file, or you compile this file      
31
## and link it with other works to produce a work based on this file,       
32
## this file does not by itself cause the resulting work to be covered by   
33
## the GNU General Public License. However the source code for this file    
34
## must still be made available in accordance with section (3) of the GNU   
35
## General Public License v2.                                               
36
##
37
## This exception does not invalidate any other reasons why a work based    
38
## on this file might be covered by the GNU General Public License.         
39
## -------------------------------------------                              
40
## ####ECOSGPLCOPYRIGHTEND####                                              
41
#===============================================================================
42
######DESCRIPTIONBEGIN####
43
#
44
# Author(s):    bartv
45
# Date:         2001-07-04
46
# Purpose:      To provide higher-level utility commands for performing
47
#               USB testing, and to iterate through the various test scripts
48
#               specified on the command line.
49
#
50
#####DESCRIPTIONEND####
51
#===============================================================================
52
#
53
 
54
# }}}
55
 
56
# {{{  Endpoint data                                    
57
 
58
# Given the raw endpoint data provided by the C code, turn
59
# it something more usable from inside Tcl scripts.
60
namespace eval usbtest {
61
    array set control {}
62
 
63
    variable bulk_in_endpoints [list]
64
    array set bulk_in {}
65
    variable bulk_out_endpoints [list]
66
    array set bulk_out {}
67
 
68
    variable isochronous_in_endpoints [list]
69
    array set isochronous_in {}
70
    variable isochronous_out_endpoints [list]
71
    array set isochronous_out {}
72
 
73
    variable interrupt_in_endpoints [list]
74
    array set interrupt_in {}
75
    variable interrupt_out_endpoints [list]
76
    array set interrupt_out {}
77
 
78
    for { set i 0 } { $i < $usbtest::endpoint_count } { incr i } {
79
        switch -- $usbtest::endpoint_data($i,type) {
80
            "control" {
81
                set usbtest::control(min_size) $usbtest::endpoint_data($i,min_size)
82
                set usbtest::control(max_size) $usbtest::endpoint_data($i,max_size)
83
            }
84
 
85
            "bulk" {
86
                set number $usbtest::endpoint_data($i,number)
87
                if { "in" == $usbtest::endpoint_data($i,direction) } {
88
                    lappend usbtest::bulk_in_endpoints $number
89
                    set usbtest::bulk_in($number,min_size)              $usbtest::endpoint_data($i,min_size)
90
                    set usbtest::bulk_in($number,max_size)              $usbtest::endpoint_data($i,max_size)
91
                    set usbtest::bulk_in($number,max_in_padding)        $usbtest::endpoint_data($i,max_in_padding)
92
                    set usbtest::bulk_in($number,devtab)                $usbtest::endpoint_data($i,devtab)
93
                } else {
94
                    lappend usbtest::bulk_out_endpoints $number
95
                    set usbtest::bulk_out($number,min_size)             $usbtest::endpoint_data($i,min_size)
96
                    set usbtest::bulk_out($number,max_size)             $usbtest::endpoint_data($i,max_size)
97
                    set usbtest::bulk_out($number,devtab)               $usbtest::endpoint_data($i,devtab)
98
                }
99
            }
100
 
101
            "isochronous" {
102
                set number $usbtest::endpoint_data($i,number)
103
                if { "in" == $usbtest::endpoint_data($i,direction) } {
104
                    lappend usbtest::isochronous_in_endpoints $number
105
                    set usbtest::isochronous_in($number,min_size)       $usbtest::endpoint_data($i,min_size)
106
                    set usbtest::isochronous_in($number,max_size)       $usbtest::endpoint_data($i,max_size)
107
                    set usbtest::isochronous_in($number,devtab)         $usbtest::endpoint_data($i,devtab)
108
                } else {
109
                    lappend usbtest::isochronous_out_endpoints $number
110
                    set usbtest::isochronous_out($number,min_size)      $usbtest::endpoint_data($i,min_size)
111
                    set usbtest::isochronous_out($number,max_size)      $usbtest::endpoint_data($i,max_size)
112
                    set usbtest::isochronous_out($number,devtab)        $usbtest::endpoint_data($i,devtab)
113
                }
114
            }
115
 
116
            "interrupt" {
117
                set number $usbtest::endpoint_data($i,number)
118
                if { "in" == $usbtest::endpoint_data($i,direction) } {
119
                    lappend usbtest::interrupt_in_endpoints $number
120
                    set usbtest::interrupt_in($number,min_size)         $usbtest::endpoint_data($i,min_size)
121
                    set usbtest::interrupt_in($number,max_size)         $usbtest::endpoint_data($i,max_size)
122
                    set usbtest::interrupt_in($number,devtab)           $usbtest::endpoint_data($i,devtab)
123
                } else {
124
                    lappend usbtest::interrupt_out_endpoints $number
125
                    set usbtest::interrupt_out($number,min_size)        $usbtest::endpoint_data($i,min_size)
126
                    set usbtest::interrupt_out($number,max_size)        $usbtest::endpoint_data($i,max_size)
127
                    set usbtest::interrupt_out($number,devtab)          $usbtest::endpoint_data($i,devtab)
128
                }
129
            }
130
 
131
            default {
132
                puts stderr "Internal error: invalid endpoint type $usbtest::endpoint_data($i,type)"
133
                exit 1
134
            }
135
        }
136
    }
137
}
138
 
139
# }}}
140
# {{{  Constants                                        
141
 
142
# The C code expects to receive certain data as simple numbers,
143
# corresponding to #define's in common.c and elsewhere. Strictly
144
# speaking it would be better to pass strings to the C code and
145
# have it do the translation, thus ensuring that these constants
146
# exist in only one place.
147
 
148
namespace eval usbtest {
149
 
150
    variable _USB_DIR_IN        0x0080
151
    variable _DATA_NONE              0
152
    variable _DATA_BYTE_FILL         1
153
    variable _DATA_WORD_FILL         2
154
    variable _DATA_BYTE_GEN          3
155
    variable _DATA_WORD_GEN          4
156
    variable _IO_MECHANISM_USB       1
157
    variable _IO_MECHANISM_DEV       2
158
}
159
 
160
# It is also desirable to have some constants corresponding
161
# to common random number generators.
162
namespace eval usbtest {
163
    variable MULTIPLIER        1103515245
164
    variable INCREMENT              12345
165
}
166
 
167
# }}}
168
# {{{  Argument processing                              
169
 
170
# ----------------------------------------------------------------------------
171
# Given a list of arguments of the form "xyzzy=123" or "xyzzy 123", and
172
# an array arguments containing entries such as arguments(xyzzy) and
173
# already filled in with default values, update the array using the
174
# actual arguments
175
namespace eval usbtest {
176
 
177
    proc process_arguments { list array_ref } {
178
        upvar $array_ref array
179
        array set defined_args [list]
180
 
181
        set listlen [llength $list]
182
        for { set index 0 } { $index < $listlen } { incr index } {
183
            set arg [lindex $list $index]
184
            set found 0
185
            foreach name [array names array] {
186
                set len [string length $name]
187
                if { [string equal -length $len $name $arg] } {
188
                    # Partial match found.
189
                    if { [string equal $name $arg] } {
190
                        # Exact match found, The value must be the next arg.
191
                        if { [info exists defined_args($name)] } {
192
                            error "Argument $name should be specified only once"
193
                        }
194
                        incr index
195
                        if { $index >= $listlen } {
196
                            error "Missing value after argument $name"
197
                        }
198
                        set array($name) [lindex $list $index]
199
                        set found 1
200
                        break
201
                    }
202
 
203
                    # Not an exact match. Try looking for x=y
204
                    incr len
205
                    if { [string equal -length $len "$name=" $arg] } {
206
                        if { [info exists defined_args($name)] } {
207
                            error "Argument $name should be specified only once"
208
                        }
209
                        set array($name) [string range $arg $len end]
210
                        set found 1
211
                        break
212
                    }
213
                }
214
            }
215
            if { ! $found } {
216
                error "Invalid argument $arg"
217
            }
218
        }
219
    }
220
}
221
 
222
# }}}
223
# {{{  Starting and ending tests                        
224
 
225
# This section deals with starting tests, or cleaning up when the
226
# tests cannot actually proceed. Also there is some validation,
227
# for example to make sure that no endpoint number is used for
228
# multiple tests.
229
 
230
namespace eval usbtest {
231
    variable results
232
    variable _tests_submitted 0
233
    variable _control_endpoint_in_use 0
234
    variable _in_endpoints_in_use [list]
235
    variable _out_endpoints_in_use [list]
236
 
237
    proc reset { } {
238
        if { 0 != $usbtest::_tests_submitted } {
239
            usbtest::_cancel
240
            set usbtest::_tests_submitted 0
241
 
242
        }
243
        set usbtest::_in_endpoints_in_use [list]
244
        set usbtest::_out_endpoints_in_use [list]
245
    }
246
 
247
    proc use_endpoint { endpoint direction } {
248
        if { 0 == $endpoint } {
249
            if { $usbtest::_control_endpoint_in_use } {
250
                error "Attempt to run multiple tests on the control endpoint"
251
            }
252
            set usbtest::_control_endpoint_in_use 1
253
        } else {
254
            switch -- $direction {
255
                "in" {
256
                    if { -1 != [lsearch -exact $usbtest::_in_endpoints_in_use $endpoint] } {
257
                        error "Attempt to run multiple IN tests on endpoint $endpoint"
258
                    }
259
                    lappend usbtest::_in_endpoints_in_use $endpoint
260
                }
261
 
262
                "out" {
263
                    if { -1 != [lsearch -exact $usbtest::_out_endpoints_in_use $endpoint] } {
264
                        error "Attempt to run multiple OUT tests on endpoint $endpoint"
265
                    }
266
                    lappend usbtest::_out_endpoints_in_use $endpoint
267
                }
268
 
269
                default {
270
                    error "Invalid direction passed to usbtest::use_endpoint"
271
                }
272
            }
273
        }
274
    }
275
 
276
    proc test_submitted { } {
277
        incr usbtest::_tests_submitted
278
    }
279
 
280
    proc start { timeout } {
281
        set result 0
282
        if { 0 == $usbtest::_tests_submitted } {
283
            error "Attempt to start tests when no tests are scheduled to run."
284
        } elseif { ! [string is integer -strict $timeout] } {
285
            error "Invalid timeout specified, it should be a simple number."
286
        } else {
287
            set usbtest::results [list]
288
            set result [usbtest::_run $timeout]
289
            set usbtest::_tests_submitted 0
290
            set usbtest::_control_endpoint_in_use 0
291
            array unset _in_endpoints_in_use
292
            array unset _out_endpoints_in_use
293
        }
294
        return $result
295
    }
296
}
297
 
298
# }}}
299
# {{{  Bulk tests                                       
300
 
301
# Prepare to run a bulk test.
302
#
303
# This test requires rather a lot of parameters, many of which
304
# will have sensible defaults.
305
 
306
namespace eval usbtest {
307
 
308
    proc bulktest { endpoint direction number_packets args } {
309
 
310
 
311
        # Parameters to be passed to the C code. Most are
312
        # held in an array indexed by the option name,
313
        # facilitating command-line parsing.
314
        set arguments(format)        "none"
315
        set arguments(data1)         0
316
        set arguments(data*)         1
317
        set arguments(data+)         0
318
        set arguments(data1*)        1
319
        set arguments(data1+)        0
320
        set arguments(data**)        1
321
        set arguments(data*+)        0
322
        set arguments(data+*)        1
323
        set arguments(data++)        0
324
        set arguments(mechanism)     "usb"
325
        set arguments(txsize1)       32
326
        set arguments(txsize>=)      0
327
        set arguments(txsize<=)      -1
328
        set arguments(txsize*)       1
329
        set arguments(txsize/)       1
330
        set arguments(txsize+)       0
331
        set arguments(rxsize1)       0
332
        set arguments(rxsize>=)      0
333
        set arguments(rxsize<=)      -1
334
        set arguments(rxsize*)       1
335
        set arguments(rxsize/)       1
336
        set arguments(rxsize+)       0
337
        set arguments(txdelay1)      0
338
        set arguments(txdelay>=)     0
339
        set arguments(txdelay<=)     1000000000
340
        set arguments(txdelay*)      1
341
        set arguments(txdelay/)      1
342
        set arguments(txdelay+)      0
343
        set arguments(rxdelay1)      0
344
        set arguments(rxdelay>=)     0
345
        set arguments(rxdelay<=)     1000000000
346
        set arguments(rxdelay*)      1
347
        set arguments(rxdelay/)      1
348
        set arguments(rxdelay+)      0
349
 
350
        set endpoint_param                      ""
351
 
352
        # Target limits
353
        set target_min_size                     0
354
        set target_max_size                     0
355
        set target_padding                      0
356
        set target_devtab                       ""
357
 
358
        # Start by validating the endpoint and direction arguments.
359
        # Also check that the specified endpoint is not yet in use.
360
        if { ![string is integer -strict $endpoint] } {
361
            error "Invalid endpoint argument \"$endpoint\": should be a number"
362
        }
363
        if { ($endpoint < 1) || ($endpoint > 15) } {
364
            error "Invalid bulk endpoint argument \"$endpoint\": should be between 1 and 15"
365
        }
366
        switch -- $direction {
367
            "in" -
368
            "In" -
369
            "IN" {
370
                set direction "in"
371
                if { -1 == [lsearch -exact $usbtest::bulk_in_endpoints $endpoint] } {
372
                    error "Invalid bulk endpoint argument \"$endpoint\": the target does not list that as a bulk IN endpoint"
373
                }
374
                set target_min_size      $usbtest::bulk_in($endpoint,min_size)
375
                set target_max_size      $usbtest::bulk_in($endpoint,max_size)
376
                set target_padding       $usbtest::bulk_in($endpoint,max_in_padding)
377
                set target_devtab        $usbtest::bulk_in($endpoint,devtab);
378
                set endpoint_param [expr $endpoint | $usbtest::_USB_DIR_IN]
379
            }
380
 
381
            "out" -
382
            "Out" -
383
            "OUT" {
384
                set direction "out"
385
                if { -1 == [lsearch -exact $usbtest::bulk_out_endpoints $endpoint] } {
386
                    error "Invalid bulk endpoint argument \"$endpoint\": the target does not list that as a bulk OUT endpoint"
387
                }
388
                set target_min_size      $usbtest::bulk_out($endpoint,min_size)
389
                set target_max_size      $usbtest::bulk_out($endpoint,max_size)
390
                set target_devtab        $usbtest::bulk_out($endpoint,devtab);
391
                set target_padding       0; # Not applicable
392
                set endpoint_param       $endpoint
393
            }
394
 
395
            default {
396
                error "Invalid direction argument \"$direction\": should be \"in\" or \"out\""
397
            }
398
        }
399
 
400
        # Now parse any remaining arguments
401
        usbtest::process_arguments $args arguments
402
 
403
        # Convert two of the arguments from strings to numbers, for the
404
        # convenience of the C code
405
        switch -- $arguments(format) {
406
            "none"      { set arguments(format) $usbtest::_DATA_NONE }
407
            "bytefill"  { set arguments(format) $usbtest::_DATA_BYTE_FILL }
408
            "wordfill"  { set arguments(format) $usbtest::_DATA_WORD_FILL }
409
            "byteseq"   { set arguments(format) $usbtest::_DATA_BYTE_GEN }
410
            "wordseq"   { set arguments(format) $usbtest::_DATA_WORD_GEN }
411
 
412
            default {
413
                error "Invalid data format argument \"$arguments(data)\"\n    \
414
                       Should be \"none\", \"bytefill\", \"wordfill\", \"byteseq\" or \"wordseq\""
415
            }
416
        }
417
        switch -- $arguments(mechanism) {
418
            "usb"       { set arguments(mechanism) $usbtest::_IO_MECHANISM_USB }
419
            "devtab"    { set arguments(mechanism) $usbtest::_IO_MECHANISM_DEV }
420
 
421
            default {
422
                error "Invalid mechanism argument \"$arguments(mechanism)\"\n    \
423
                       Should be \"usb\" or \"devtab\""
424
            }
425
        }
426
 
427
        puts "validating fields"
428
        # Validate the remaining fields
429
        foreach field [list data1 data* data+ data1* data1+ data** data*+ data+* data++ \
430
                            txsize1 txsize>= txsize<= txsize* txsize/ txsize+           \
431
                            rxsize1 rxsize>= rxsize<= rxsize* rxsize/ rxsize+           \
432
                            txdelay1 txdelay>= txdelay<= txdelay* txdelay/ txdelay+     \
433
                            rxdelay1 rxdelay>= rxdelay<= rxdelay* rxdelay/ rxdelay+] {
434
            if { ![string is integer -strict $arguments($field)] } {
435
                error "Invalid value \"$arguments($field)\" for argument $field, should be an integer."
436
            }
437
        }
438
 
439
        if { $arguments(txsize>=) < $target_min_size } {
440
            set arguments(txsize>=) $target_min_size
441
        }
442
        if { (-1 == $arguments(txsize<=) ) || ($arguments(txsize<=) > $target_max_size) } {
443
            set arguments(txsize<=) $target_max_size
444
        }
445
        if { $arguments(rxsize<=) == -1 } {
446
            set arguments(rxsize<=) $target_max_size
447
        }
448
        if { $arguments(txsize1) < $arguments(txsize>=) } {
449
            set arguments(txsize1) $arguments(txsize>=)
450
        }
451
        # Make sure the endpoint is not already in use
452
        usbtest::use_endpoint $endpoint $direction
453
 
454
        puts "Submitting test"
455
        # Now submit the test. This is handled by C code.
456
        usbtest::_test_bulk             \
457
                $number_packets         \
458
                $endpoint_param         \
459
                $arguments(txsize1)     \
460
                $arguments(txsize>=)    \
461
                $arguments(txsize<=)    \
462
                $arguments(txsize*)     \
463
                $arguments(txsize/)     \
464
                $arguments(txsize+)     \
465
                $arguments(rxsize1)     \
466
                $arguments(rxsize>=)    \
467
                $arguments(rxsize<=)    \
468
                $arguments(rxsize*)     \
469
                $arguments(rxsize/)     \
470
                $arguments(rxsize+)     \
471
                $target_padding         \
472
                $arguments(txdelay1)    \
473
                $arguments(txdelay>=)   \
474
                $arguments(txdelay<=)   \
475
                $arguments(txdelay*)    \
476
                $arguments(txdelay/)    \
477
                $arguments(txdelay+)    \
478
                $arguments(rxdelay1)    \
479
                $arguments(rxdelay>=)   \
480
                $arguments(rxdelay<=)   \
481
                $arguments(rxdelay*)    \
482
                $arguments(rxdelay/)    \
483
                $arguments(rxdelay+)    \
484
                $arguments(mechanism)   \
485
                $arguments(format)      \
486
                $arguments(data1)       \
487
                $arguments(data*)       \
488
                $arguments(data+)       \
489
                $arguments(data1*)      \
490
                $arguments(data1+)      \
491
                $arguments(data**)      \
492
                $arguments(data*+)      \
493
                $arguments(data+*)      \
494
                $arguments(data++)
495
 
496
        test_submitted
497
    }
498
}
499
 
500
# }}}
501
# {{{  Execute the specified test script                
502
 
503
# Interpret the arguments as a test script plus auxiliary data.
504
set script [lindex $::argv 0]
505
set ::argv [lrange $::argv 1 end]
506
 
507
set result [catch {
508
    set path [file join [pwd] $script]
509
    if { ![file exists $path] } {
510
        set path "$path.tcl"
511
        if { ![file exists $path] } {
512
            set path [file join $usbtest::USBAUXDIR $script]
513
            if { ![file exists $path] } {
514
                set path "$path.tcl"
515
                if { ![file exists $path] } {
516
                    error "Error: unknown test script $script"
517
                }
518
            }
519
        }
520
    }
521
 
522
    source $path
523
 
524
} message]
525
 
526
if { 0 != $result } {
527
    puts $message
528
}
529
 
530
# }}}

powered by: WebSVN 2.1.0

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