###################################################################### # Copyright (c) 2006 Xilinx, Inc. All rights reserved. # # XILINX CONFIDENTIAL PROPERTY # This document contains proprietary information which is # protected by copyright. All rights are reserved. No part of # this document may be photocopied, reproduced or translated to # another program language without prior written consent of # XILINX Inc., San Jose, CA. 95124 # # Xilinx, Inc. # XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A # COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS # ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR # STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION # IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE # FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. # XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO # THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO # ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE # FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS FOR A PARTICULAR PURPOSE. # ###################################################################### # # For Tcl Manual for builtin commands, see # http://www.tcl.tk/man/tcl8.3 # # # # Example scanning devices and ChipScope cores, in a JTAG Chain, # using the Cse api. # Get the Cse DLL's and globals cd F:\\Xilinx9\\ChipScope_Pro_9_1i\\bin\\nt source csejtag.tcl namespace import ::chipscope::* # Create global variables # Parallel IV Cable set PARALLEL_CABLE_ARGS [list "port=LPT1" \ "frequency=200000"] # "frequency=5000000 | 2500000 | 200000" # Platform USB Cable set PLATFORM_USB_CABLE_ARGS [list "port=USB2" \ "frequency=3000000"] # frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000" set CABLE_NAME $CSEJTAG_TARGET_PLATFORMUSB set CABLE_ARGS $PLATFORM_USB_CABLE_ARGS set debug 0 proc main {argc argv} { global debug global PLATFORM_USB_CABLE_ARGS global CSEJTAG_TARGET_PLATFORMUSB global CABLE_NAME global CABLE_ARGS global CSE_MSG_INFO if {[expr ($argc > 0) && [string equal "-h" [lindex $argv 0]]]} { writeMessage 0 $CSE_MSG_INFO "Usage: xtclsh csejtag_examplel1.tcl \[-usb\] \[-d\]\n" exit } # for CseServer/CseClient use set serverflag_idx 0 set serveraddress_idx 0 # Checks to see if usb or debug flag is set for {set i 0} {$i < $argc} {incr i} { if {[string equal "-usb" [lindex $argv $i]]} { set CABLE_NAME $CSEJTAG_TARGET_PLATFORMUSB set CABLE_ARGS $PLATFORM_USB_CABLE_ARGS } elseif {[string equal "-d" [lindex $argv $i]]} { set debug 1 } elseif {[string equal "-server" [lindex $argv $i]]} { set serverflag_idx $i set serveraddress_idx [expr $i + 1] } } # Create Session. Pass location of idcode.lst to override default. set handle [csejtag_session create "writeMessage" [lindex $argv $serverflag_idx] [lindex $argv $serveraddress_idx] ] # Scan the JTAG chain scanChain $handle csejtag_session destroy $handle } proc scanChain {handle} { global CABLE_NAME global CABLE_ARGS global CSE_MSG_ERROR global CSE_MSG_INFO global CSEJTAG_SCAN_DEFAULT global CSEJTAG_LOCKED_ME global CSEJTAG_TEST_LOGIC_RESET global CSEJTAG_SHIFT_READ global CSEJTAG_RUN_TEST_IDLE # Open cable csejtag_target open $handle \ $CABLE_NAME \ 0 \ [lindex $CABLE_ARGS 0] \ [lindex $CABLE_ARGS 1] # CseJtag_session sendMessage will call the messageRouter # function specified in csejtag_session create csejtag_session send_message $handle $CSE_MSG_INFO "Open Cable successfully\n" # Need to lock cable before actually accessing JTAG chain set cablelock [csejtag_target lock $handle 5000] if {$cablelock != $CSEJTAG_LOCKED_ME} { csejtag_session send_message $handle $CSE_MSG_ERROR "cse_lock_target failed" csejtag_target close $handle return } csejtag_session send_message $handle $CSE_MSG_INFO "Obtained cable lock\n" # Scan the JTAG chain, reading idcodes, # setting IR lengths for known devices in the CseJtag # data structures. # CseJtag needs to know in order to do JTAG shifts. csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT # Get number of devices set deviceCount [csejtag_tap get_device_count $handle] set str [format "Found %u devices\n" $deviceCount] csejtag_session send_message $handle $CSE_MSG_INFO $str # Get a byte array of all idcodes by scanning the JTAG chain. csejtag_tap navigate $handle $CSEJTAG_TEST_LOGIC_RESET 0 0 set idcodeBuffer [csejtag_tap shift_chain_dr $handle\ $CSEJTAG_SHIFT_READ \ $CSEJTAG_RUN_TEST_IDLE \ 0 \ [expr $deviceCount * 32] \ 0 \ -hextdimask 0 \ -hextdomask 0] for {set deviceIndex 0} {$deviceIndex < $deviceCount} {incr deviceIndex} { scanDevice $handle $deviceIndex $deviceCount $idcodeBuffer } csejtag_target unlock $handle csejtag_target close $handle csejtag_session send_message $handle $CSE_MSG_INFO "Closed cable successfully\n" } # Note that this function (with the exception of the call to # scanUserReg() ) does not get any information # which requires a new scan of the device chain. # It is just lookup in the 'idcode.lst' file or # information which CseJtag data structures already has such as: # deviceCount and device idcodes. proc scanDevice {handle deviceIndex deviceCount idcodeBuffer} { global CSE_MSG_INFO # position of buffer set startofidcodeBuf [expr $deviceIndex * 8 ] set idcodeBuf [string range $idcodeBuffer $startofidcodeBuf [expr $startofidcodeBuf + 7] ] # Get idcode without scanning the JTAG chain set idcodeBuffer2 [csejtag_tap get_device_idcode $handle $deviceIndex] # Convert idcodeFromBuffer and idcodeFromBuffer2 to unsigned integers set idcodeFromBuffer [expr "0x0$idcodeBuf"] set idcode [expr [format "%u" [binaryStringToInt $idcodeBuffer2] ] ] # Get IR length without scanning JTAG chain set irLength 0 set irLength [csejtag_db get_irlength_for_idcode $handle $idcodeBuffer2] # NOTE If (irLength == 0) an application program needs to set it, # ( using function csejtag_tap_set_irlength $handle $deviceIndex $irLength) # perhaps after asking the user or looking it up someway. # Without irLength known for all devices in the chain, # JTAG communication will fail. # Get device name set deviceName [csejtag_db get_device_name_for_idcode $handle $idcodeBuffer2] # print out device info set str [format "\nDEVICE %u, idcode:%x, Scanned idcode:%x, IRLength:%u, %s\n" \ $deviceIndex $idcode $idcodeFromBuffer $irLength $deviceName] csejtag_session send_message $handle $CSE_MSG_INFO $str # Compares the two methods of obtaining the idcode, # prints a message if they are different. if {$idcode != $idcodeFromBuffer} { csejtag_session send_message $handle $CSE_MSG_INFO "IDCODES ARE NOT EQUAL!!!\n" } } proc writeMessage {handle msgFlags msg} { global debug global CSE_MSG_ERROR global CSE_MSG_WARNING global CSE_MSG_STATUS global CSE_MSG_INFO global CSE_MSG_NOISE global CSE_MSG_DEBUG if {[expr $debug || ($msgFlags != $CSE_MSG_DEBUG)]} { if {$msgFlags == $CSE_MSG_ERROR} { puts -nonewline "Error:" } elseif {$msgFlags == $CSE_MSG_WARNING} { puts -nonewline "Warning:" } elseif {$msgFlags == $CSE_MSG_INFO} { puts -nonewline "Info:" } elseif {$msgFlags == $CSE_MSG_STATUS} { puts -nonewline "Status:" } elseif {$msgFlags == $CSE_MSG_DEBUG} { puts -nonewline "Debug:" } puts -nonewline $msg flush stdout } } proc binaryStringToInt {binarystring} { set len [string length $binarystring] set retval 0 for {set i 0} {$i < $len} {incr i} { set retval [expr $retval << 1] if {[string index $binarystring $i] == "1"} { set retval [expr $retval | 1] } } return $retval } # Start the program main $argc $argv