/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Netscan.java
* Written by Eric Kim and Tom O'Neill, Sun Microsystems.
*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Electric(tm) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.tool.simulation.test;
/**
* Initialization, configuration, and connection API for Corelis NET-1149.1/E
* one-port boundary scan controller (JTAG tester device). Shifting data in and
* out should instead be performed using {@link ChainControl}. All of the
* methods could have been static, but we made them non-static to allow
* device-independent JTAG control.
* <p>
* Here is an example of how to use <code>Netscan</code>:<BLOCKQUOTE><TT>
* JtagTester jtag = new Netscan(JTAG_IP_ADDRESS); <BR>
* ChainControl control = new ChainControl(XML_PATH, jtag, DEFAULT_VDD,
* DEFAULT_TCK_KHZ); <BR>
* </TT> </BLOCKQUOTE> The user can then call {@link ChainControl#setInBits}
* and {@link ChainControl#shift} to program scan chains.
*/
public class Netscan extends NetscanGeneric {
/** Default stop state for scan. Value equals 1: Run-Test/Idle */
public static final short DEFAULT_STOP_STATE = 1;
/** Number of channels of programmable parallel output */
public static final int NUM_OUTPUT_PINS = 2;
/**
* Creates the <code>Netscan</code> object. Only one <code>Netscan</code>
* or {@link Netscan4} instance is allowed, because the Netscan
* library only supports one JTAG controller at a time. Connects to the JTAG
* tester (by using the Net_Connect routine in the scan function library).
* The tester must then be configured before use, by passing the new
* <code>Netscan</code> object to
* {@link ChainControl#ChainControl(String, JtagTester, float, int)}.
*
* @param addressIP
* IP address of JTAG tester
*/
public Netscan(String addressIP) {
incrementNumTesters();
// Connect to tester via ethernet
logInit("Connecting to Netscan at " + addressIP);
int status = NetscanJNI.net_connect(addressIP);
if (status <= 0) {
Infrastructure.fatal("NetscanJNI.net_connect(" + addressIP
+ ") returned error code " + status);
}
// Parallel outputs have pull-ups so initial state is probably true
logicOutput = new LogicSettableArray(NUM_OUTPUT_PINS);
setParallelIO(logicOutput.getLogicStates());
}
/**
* Configures the JTAG tester, setting its parameters, and resets the JTAG
* controller (clears TRSTb briefly). Can be run at any time after
* initialization to change settings.
*
* @param tapVolt
* signal (TAP) voltage in Volts
* @param kiloHerz
* the TCK frequency in kHz (from 391 kHz to 40 MHz)
*/
void configure(float tapVolt, long kiloHerz) {
int milliVolt = Math.round(tapVolt * 1000.f);
logSet("Netscan configuring " + kiloHerz + " kHz and " + milliVolt
+ " mV");
int status = NetscanJNI.net_configure(kiloHerz, DEFAULT_STOP_STATE,
milliVolt);
if (status != 0) {
Infrastructure
.fatal("NetscanJNI.net_configure returned error code "
+ status);
}
// Reset the JTAG controller
reset();
}
/**
* Reset the finite state machine of the chip's JTAG controller by briefly
* setting the TRSTb signal <tt>LO</tt>. The IR becomes bypass
* automatically.
*/
public void reset() {
int status = NetscanJNI.net_set_trst(0);
if (status != 0)
Infrastructure
.fatal("NetscanJNI.net_set_trst(0) returned error code "
+ status);
status = NetscanJNI.net_set_trst(1);
if (status != 0)
Infrastructure
.fatal("NetscanJNI.net_set_trst(1) returned error code "
+ status);
}
/**
* Reset the finite state machine of the chip's JTAG controller by briefly
* setting the TMS signal <tt>HI</tt> for five cycles. The IR becomes bypass
* automatically.
*/
public void tms_reset() {
int status = Netscan4JNI.netUSB_tms_reset(1);
if (status != 0)
Infrastructure
.fatal("Netscan4JNI.net_tms_reset("+1+") returned error code "
+ status);
}
/**
* Disconnect from the JTAG tester. Should be called before exiting JVM.
*/
void disconnect() {
int status = NetscanJNI.net_disconnect();
if (status != 0) {
Infrastructure
.fatal("NetscanJNI.net_disconnect() returned error code "
+ status);
}
}
/**
* Set the logic levels for the two programmable output signals from the
* JTAG tester to the chip.
*
* @param newLevel
* set parallel outputs 0, 1 <tt>HI</tt>?
*/
private void setParallelIO(boolean[] newLevel) {
if (newLevel.length != NUM_OUTPUT_PINS) {
Infrastructure.fatal("newLevel.length=" + newLevel.length
+ ", expected " + NUM_OUTPUT_PINS);
}
short port_data = 0;
if (newLevel[0])
port_data += 1;
if (newLevel[1])
port_data += 2;
int returnValue = NetscanJNI.net_set_parallel_io(port_data);
if (returnValue != 0)
Infrastructure.fatal("net_set_parallel_io returned error code "
+ returnValue);
}
/**
* Set the logic level for a single channel of the parallel programmable
* output signals from the JTAG tester to the chip. Must update
* {@link #logicOutput}.
*
* @param index
* Which parallel output to set
* @param newLevel
* set parallel output <tt>HI</tt>?
*/
void setLogicOutput(int index, boolean newLevel) {
logicOutput.setLogicState(index, newLevel);
setParallelIO(logicOutput.getLogicStates());
}
/**
* Write the bits <code>scanIn</code> to the JTAG controller's instruction
* register. The first bit scanned in to the chip is the LSB of
* <code>scanIn[0]</code>, and the first bit scanned out from the chip is
* the LSB of <code>scanOut[0]</code>.
*
* @param numBits
* The number of bits to shift
* @param scanIn
* Bit sequence to write to instruction register
* @param scanOut
* Bits scanned out of instruction register
* @return 0x00 (success), 0x11 (transmit error), 0x33 (receive error)
*/
protected int hw_net_scan_ir(int numBits, short[] scanIn,
short[] scanOut, int drBits) {
logOther("IR in: # shorts=" + scanIn.length + ", "
+ shortsToString(scanIn));
int result = NetscanJNI.net_scan_ir(scanIn, numBits, scanOut);
logOther("IR out: # shorts=" + scanOut.length + ", "
+ shortsToString(scanOut));
return result;
}
/**
* Write the bits <code>scanIn</code> to the JTAG controller's data
* register, and read back the bits <code>scanOut</code>. The first bit
* scanned in to the chip is the LSB of <code>scanIn[0]</code>, and the
* first bit scanned out from the chip is the LSB of <code>scanOut[0]</code>.
* <p>
* Extracted from netScan_DR to simplify overriding for different hardware,
* e.g., in class <code>Netscan4</code>.
*
* @param numBits
* The number of bits to shift
* @param scanIn
* Bit sequence to write to data register
* @param scanOut
* Bits scanned out of data register
* @return 0x00 (success), 0x11 (transmit error), 0x33 (receive error)
*/
protected int hw_net_scan_dr(int numBits, short[] scanIn,
short[] scanOut) {
logOther("DR in: # shorts=" + scanIn.length + ", "
+ shortsToString(scanIn));
logOther(" chain length=" + numBits);
int result = NetscanJNI.net_scan_dr(scanIn, numBits, scanOut);
logOther("DR out: # shorts=" + scanOut.length + ", "
+ shortsToString(scanOut));
return result;
}
}