diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java index cb9e96f419..f0b6bde7e4 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java @@ -1,8 +1,8 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ +/* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ +/* the project. */ /*----------------------------------------------------------------------------*/ package edu.wpi.first.wpilibj; @@ -53,7 +53,7 @@ public class AnalogInput extends SensorBase implements PIDSource, * Construct an analog channel. * * @param channel - * The channel number to represent. + * The channel number to represent. */ public AnalogInput(final int channel) { m_channel = channel; @@ -69,7 +69,7 @@ public class AnalogInput extends SensorBase implements PIDSource, + " is already allocated"); } - ByteBuffer port_pointer = AnalogJNI.getPortWithModule((byte) 1, (byte) channel); + ByteBuffer port_pointer = AnalogJNI.getPort((byte) channel); ByteBuffer status = ByteBuffer.allocateDirect(4); // set the byte order status.order(ByteOrder.LITTLE_ENDIAN); @@ -91,21 +91,12 @@ public class AnalogInput extends SensorBase implements PIDSource, } /** - * Get the analog module. + * Get a sample straight from this channel. The sample is a 12-bit value + * representing the 0V to 10V range of the A/D converter. The units are in + * A/D converter codes. Use GetVoltage() to get the analog value in + * calibrated units. * - * @return The AnalogModule. - */ - public AnalogModule getModule() { - return AnalogModule.getInstance(1); - } - - /** - * Get a sample straight from this channel on the module. The sample is a - * 12-bit value representing the -10V to 10V range of the A/D converter in - * the module. The units are in A/D converter codes. Use GetVoltage() to get - * the analog value in calibrated units. - * - * @return A sample straight from this channel on the module. + * @return A sample straight from this channel. */ public int getValue() { ByteBuffer status = ByteBuffer.allocateDirect(4); @@ -122,8 +113,8 @@ public class AnalogInput extends SensorBase implements PIDSource, * SetOversampleBits(). The value configured in setAverageBits() will cause * this value to be averaged 2**bits number of samples. This is not a * sliding window. The sample will not change until 2**(OversamplBits + - * AverageBits) samples have been acquired from the module on this channel. - * Use getAverageVoltage() to get the analog value in calibrated units. + * AverageBits) samples have been acquired from this channel. Use + * getAverageVoltage() to get the analog value in calibrated units. * * @return A sample from the oversample and average engine for this channel. */ @@ -137,11 +128,11 @@ public class AnalogInput extends SensorBase implements PIDSource, } /** - * Get a scaled sample straight from this channel on the module. The value - * is scaled to units of Volts using the calibrated scaling data from - * getLSBWeight() and getOffset(). + * Get a scaled sample straight from this channel. The value is scaled to + * units of Volts using the calibrated scaling data from getLSBWeight() and + * getOffset(). * - * @return A scaled sample straight from this channel on the module. + * @return A scaled sample straight from this channel. */ public double getVoltage() { ByteBuffer status = ByteBuffer.allocateDirect(4); @@ -161,7 +152,7 @@ public class AnalogInput extends SensorBase implements PIDSource, * stable, but it will update more slowly. * * @return A scaled sample from the output of the oversample and average - * engine for this channel. + * engine for this channel. */ public double getAverageVoltage() { ByteBuffer status = ByteBuffer.allocateDirect(4); @@ -175,7 +166,7 @@ public class AnalogInput extends SensorBase implements PIDSource, /** * Get the factory scaling least significant bit weight constant. The least * significant bit weight constant for the channel that was calibrated in - * manufacturing and stored in an eeprom in the module. + * manufacturing and stored in an eeprom. * * Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9) * @@ -192,8 +183,7 @@ public class AnalogInput extends SensorBase implements PIDSource, /** * Get the factory scaling offset constant. The offset constant for the - * channel that was calibrated in manufacturing and stored in an eeprom in - * the module. + * channel that was calibrated in manufacturing and stored in an eeprom. * * Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9) * @@ -223,7 +213,7 @@ public class AnalogInput extends SensorBase implements PIDSource, * automatically in the FPGA. * * @param bits - * The number of averaging bits. + * The number of averaging bits. */ public void setAverageBits(final int bits) { ByteBuffer status = ByteBuffer.allocateDirect(4); @@ -255,7 +245,7 @@ public class AnalogInput extends SensorBase implements PIDSource, * oversampling is done automatically in the FPGA. * * @param bits - * The number of oversample bits. + * The number of oversample bits. */ public void setOversampleBits(final int bits) { ByteBuffer status = ByteBuffer.allocateDirect(4); @@ -306,7 +296,7 @@ public class AnalogInput extends SensorBase implements PIDSource, * This will be added to all values returned to the user. * * @param initialValue - * The value that the accumulator should start from when reset. + * The value that the accumulator should start from when reset. */ public void setAccumulatorInitialValue(long initialValue) { m_accumulatorOffset = initialValue; @@ -396,7 +386,7 @@ public class AnalogInput extends SensorBase implements PIDSource, * can be used for averaging. * * @param result - * AccumulatorResult object to store the results in. + * AccumulatorResult object to store the results in. */ public void getAccumulatorOutput(AccumulatorResult result) { if (result == null) { @@ -435,16 +425,41 @@ public class AnalogInput extends SensorBase implements PIDSource, return false; } - public void setSampleRate(final double samplesPerSecond) { - // TODO: This will change when variable size scan lists are implemented. - // TODO: Need float comparison with epsilon. + /** + * Set the sample rate. + * + * This is a global setting for all channels. + * + * @param samplesPerSecond The number of samples per second. + */ + public static void setGlobalSampleRate(final double samplesPerSecond) { ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order status.order(ByteOrder.LITTLE_ENDIAN); - AnalogJNI.setAnalogSampleRate((float) samplesPerSecond, status.asIntBuffer()); + + AnalogJNI.setAnalogSampleRate((float)samplesPerSecond, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); } + /** + * Get the current sample rate. + * + * This assumes one entry in the scan list. This is a global setting for + * all channels. + * + * @return Sample rate. + */ + public static double getGlobalSampleRate() { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + double value = AnalogJNI.getAnalogSampleRate(status.asIntBuffer()); + + HALUtil.checkStatus(status.asIntBuffer()); + + return value; + } + /** * Get the average value for use with PIDController * diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogModule.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogModule.java deleted file mode 100644 index edc1ab8900..0000000000 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogModule.java +++ /dev/null @@ -1,316 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -package edu.wpi.first.wpilibj; - -import java.nio.ByteOrder; -import java.nio.ByteBuffer; - -import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tModuleType; -import edu.wpi.first.wpilibj.hal.AnalogJNI; -import edu.wpi.first.wpilibj.hal.HALUtil; - -/** - * Analog Module class. - * Each module can independently sample its channels at a configurable rate. - * There is a 64-bit hardware accumulator associated with channel 1 on each module. - * The accumulator is attached to the output of the oversample and average engine so that the center - * value can be specified in higher resolution resulting in less error. - */ -public class AnalogModule extends Module { - - /** - * The time base used by the module - */ - public static final int kTimebase = 40000000; - /** - * The default number of Oversample bits to use - */ - public static final int kDefaultOversampleBits = 0; - /** - * The default number of averaging bits to use - */ - public static final int kDefaultAverageBits = 7; - /** - * The default sample rate - */ - public static final double kDefaultSampleRate = 50000.0; - private ByteBuffer[] m_ports; - - /** - * Get an instance of an Analog Module. - * - * Singleton analog module creation where a module is allocated on the first use - * and the same module is returned on subsequent uses. - * - * @param moduleNumber The index of the analog module to get (1 or 2). - * @return The AnalogModule. - */ - public static synchronized AnalogModule getInstance(final int moduleNumber) { - checkAnalogModule(moduleNumber); - return (AnalogModule) getModule(tModuleType.kModuleType_Analog, moduleNumber); - } - - /** - * Create a new instance of an analog module. - * - * Create an instance of the analog module object. Initialize all the parameters - * to reasonable values on start. - * Setting a global value on an analog module can be done only once unless subsequent - * values are set the previously set value. - * Analog modules are a singleton, so the constructor is never called outside of this class. - * - * @param moduleNumber The index of the analog module to create (1 or 2). - */ - protected AnalogModule(final int moduleNumber) { - super(tModuleType.kModuleType_Analog, moduleNumber); - - m_ports = new ByteBuffer[8]; - for (int i = 0; i < SensorBase.kAnalogInputChannels; i++) { - ByteBuffer port_pointer = AnalogJNI.getPortWithModule((byte) moduleNumber, (byte) i); - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - // XXX: Uncomment when analogchannel has been fixed -// m_ports[i] = HALLibrary.initializeAnalogPort(port_pointer, status); - HALUtil.checkStatus(status.asIntBuffer()); - } - } - - /** - * Set the sample rate on the module. - * - * This is a global setting for the module and effects all channels. - * - * @param samplesPerSecond - * The number of samples per channel per second. - */ - public void setSampleRate(final double samplesPerSecond) { - // TODO: This will change when variable size scan lists are implemented. - // TODO: Need float comparison with epsilon. - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - AnalogJNI.setAnalogSampleRateWithModule((byte) m_moduleNumber, (float) samplesPerSecond, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Get the current sample rate on the module. - * - * This assumes one entry in the scan list. This is a global setting for the - * module and effects all channels. - * - * @return Sample rate. - */ - public double getSampleRate() { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - double value = AnalogJNI.getAnalogSampleRateWithModule((byte) m_moduleNumber, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Set the number of averaging bits. - * - * This sets the number of averaging bits. The actual number of averaged - * samples is 2**bits. The averaging is done automatically in the FPGA. - * - * @param channel - * Analog channel to configure. - * @param bits - * Number of bits to average. - */ - public void setAverageBits(final int channel, final int bits) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - AnalogJNI.setAnalogAverageBits(m_ports[channel], bits, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Get the number of averaging bits. - * - * This gets the number of averaging bits from the FPGA. The actual number - * of averaged samples is 2**bits. The averaging is done automatically in - * the FPGA. - * - * @param channel Channel to address. - * @return Bits to average. - */ - public int getAverageBits(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = AnalogJNI.getAnalogAverageBits(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Set the number of oversample bits. - * - * This sets the number of oversample bits. The actual number of oversampled values is 2**bits. - * Use oversampling to improve the resolution of your measurements at the expense of sampling rate. - * The oversampling is done automatically in the FPGA. - * - * @param channel Analog channel to configure. - * @param bits Number of bits to oversample. - */ - public void setOversampleBits(final int channel, final int bits) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - AnalogJNI.setAnalogOversampleBits(m_ports[channel], bits, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Get the number of oversample bits. - * - * This gets the number of oversample bits from the FPGA. The actual number - * of oversampled values is 2**bits. The oversampling is done automatically - * in the FPGA. - * - * @param channel Channel to address. - * @return Bits to oversample. - */ - public int getOversampleBits(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = AnalogJNI.getAnalogOversampleBits(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the raw analog value. - * - * Get the analog value as it is returned from the D/A converter. - * - * @param channel Channel number to read. - * @return Raw value. - */ - public int getValue(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = AnalogJNI.getAnalogValue(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the raw averaged and oversampled value. - * - * @param channel Channel number to read. - * @return The averaged and oversampled raw value. - */ - public int getAverageValue(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = AnalogJNI.getAnalogAverageValue(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Convert a voltage to a raw value for a specified channel. - * - * This process depends on the calibration of each channel, so the channel - * must be specified. - * - * @todo This assumes raw values. Oversampling not supported as is. - * - * @param channel - * The channel to convert for. - * @param voltage - * The voltage to convert. - * @return The raw value for the channel. - */ - public int voltsToValue(final int channel, final double voltage) { - // wpi_assert(voltage >= -10.0 && voltage <= 10.0); - ByteBuffer status = ByteBuffer.allocate(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = AnalogJNI.getAnalogVoltsToValue(m_ports[channel], (float) voltage, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the voltage. - * - * Return the voltage from the A/D converter. - * - * @param channel The channel to read. - * @return The scaled voltage from the channel. - */ - public double getVoltage(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - double value = AnalogJNI.getAnalogVoltage(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the averaged voltage. - * - * Return the averaged voltage from the A/D converter. - * - * @param channel The channel to read. - * @return The scaled averaged and oversampled voltage from the channel. - */ - public double getAverageVoltage(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - double value = AnalogJNI.getAnalogAverageVoltage(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the LSB Weight portion of the calibration for a channel. - * - * @param channel The channel to get calibration data for. - * @return LSB Weight calibration point. - */ - public long getLSBWeight(final int channel) { - // TODO: add scaling to make this worth while. - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - long value = AnalogJNI.getAnalogLSBWeight(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the Offset portion of the calibration for a channel. - * - * @param channel The channel to get calibration data for. - * @return Offset calibration point. - */ - public int getOffset(final int channel) { - // TODO: add scaling to make this worth while. - // TODO: actually use this function. - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = AnalogJNI.getAnalogOffset(m_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } -} diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java index 787b904c73..832c993a6f 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java @@ -1,8 +1,8 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2014. All Rights Reserved. */ +/* Copyright (c) FIRST 2014. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ +/* the project. */ /*----------------------------------------------------------------------------*/ package edu.wpi.first.wpilibj; @@ -28,113 +28,113 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException; * Analog output class. */ public class AnalogOutput extends SensorBase implements LiveWindowSendable { - private static Resource channels = new Resource(kAnalogOutputChannels); - private ByteBuffer m_port; - private int m_channel; + private static Resource channels = new Resource(kAnalogOutputChannels); + private ByteBuffer m_port; + private int m_channel; - /** - * Construct an analog output on a specified MXP channel. - * - * @param channel - * The channel number to represent. - */ - public AnalogOutput(final int channel) { - m_channel = channel; + /** + * Construct an analog output on a specified MXP channel. + * + * @param channel + * The channel number to represent. + */ + public AnalogOutput(final int channel) { + m_channel = channel; - if (AnalogJNI.checkAnalogOutputChannel(channel) == 0) { - throw new AllocationException("Analog output channel " + m_channel - + " cannot be allocated. Channel is not present."); - } - try { - channels.allocate(channel); - } catch (CheckedAllocationException e) { - throw new AllocationException("Analog output channel " + m_channel - + " is already allocated"); - } + if (AnalogJNI.checkAnalogOutputChannel(channel) == 0) { + throw new AllocationException("Analog output channel " + m_channel + + " cannot be allocated. Channel is not present."); + } + try { + channels.allocate(channel); + } catch (CheckedAllocationException e) { + throw new AllocationException("Analog output channel " + m_channel + + " is already allocated"); + } - ByteBuffer port_pointer = AnalogJNI.getPortWithModule((byte) 1, (byte) channel); - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - m_port = AnalogJNI.initializeAnalogOutputPort(port_pointer, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); + ByteBuffer port_pointer = AnalogJNI.getPort((byte)channel); + ByteBuffer status = ByteBuffer.allocateDirect(4); + // set the byte order + status.order(ByteOrder.LITTLE_ENDIAN); + m_port = AnalogJNI.initializeAnalogOutputPort(port_pointer, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); - LiveWindow.addSensor("AnalogOutput", channel, this); - UsageReporting.report(tResourceType.kResourceType_AnalogChannel, channel, 1); - } + LiveWindow.addSensor("AnalogOutput", channel, this); + UsageReporting.report(tResourceType.kResourceType_AnalogChannel, channel, 1); + } - /** - * Channel destructor. - */ - public void free() { - channels.free(m_channel); - m_channel = 0; - } + /** + * Channel destructor. + */ + public void free() { + channels.free(m_channel); + m_channel = 0; + } - public void setVoltage(double voltage) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - status.order(ByteOrder.LITTLE_ENDIAN); + public void setVoltage(double voltage) { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); - AnalogJNI.setAnalogOutput(m_port, voltage, status.asIntBuffer()); + AnalogJNI.setAnalogOutput(m_port, voltage, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } + HALUtil.checkStatus(status.asIntBuffer()); + } - public double getVoltage() { - ByteBuffer status = ByteBuffer.allocateDirect(4); - status.order(ByteOrder.LITTLE_ENDIAN); + public double getVoltage() { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); - double voltage = AnalogJNI.getAnalogOutput(m_port, status.asIntBuffer()); + double voltage = AnalogJNI.getAnalogOutput(m_port, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); - return voltage; - } + return voltage; + } - /* - * Live Window code, only does anything if live window is activated. - */ - public String getSmartDashboardType() { - return "Analog Output"; - } + /* + * Live Window code, only does anything if live window is activated. + */ + public String getSmartDashboardType() { + return "Analog Output"; + } - private ITable m_table; + private ITable m_table; - /** - * {@inheritDoc} - */ - public void initTable(ITable subtable) { - m_table = subtable; - updateTable(); - } + /** + * {@inheritDoc} + */ + public void initTable(ITable subtable) { + m_table = subtable; + updateTable(); + } - /** - * {@inheritDoc} - */ - public void updateTable() { - if (m_table != null) { - m_table.putNumber("Value", getVoltage()); - } - } + /** + * {@inheritDoc} + */ + public void updateTable() { + if (m_table != null) { + m_table.putNumber("Value", getVoltage()); + } + } - /** - * {@inheritDoc} - */ - public ITable getTable() { - return m_table; - } + /** + * {@inheritDoc} + */ + public ITable getTable() { + return m_table; + } - /** - * Analog Channels don't have to do anything special when entering the - * LiveWindow. {@inheritDoc} - */ - public void startLiveWindowMode() { - } + /** + * Analog Channels don't have to do anything special when entering the + * LiveWindow. {@inheritDoc} + */ + public void startLiveWindowMode() { + } - /** - * Analog Channels don't have to do anything special when exiting the - * LiveWindow. {@inheritDoc} - */ - public void stopLiveWindowMode() { - } + /** + * Analog Channels don't have to do anything special when exiting the + * LiveWindow. {@inheritDoc} + */ + public void stopLiveWindowMode() { + } } diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java index 558ada811e..b28f31f05b 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java @@ -56,7 +56,7 @@ public class AnalogTrigger implements IInputOutput { * the port to use for the analog trigger */ protected void initTrigger(final int channel) { - ByteBuffer port_pointer = AnalogJNI.getPortWithModule((byte) 1, (byte) channel); + ByteBuffer port_pointer = AnalogJNI.getPort((byte) channel); IntBuffer status = IntBuffer.allocate(1); IntBuffer index = IntBuffer.allocate(1); // XXX: Uncomment when analog has been fixed diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalModule.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalModule.java deleted file mode 100644 index c05b5bfab0..0000000000 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalModule.java +++ /dev/null @@ -1,542 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ -package edu.wpi.first.wpilibj; - -import java.nio.ByteOrder; -import java.nio.IntBuffer; -import java.nio.ByteBuffer; - -//import com.sun.jna.Pointer; -//import com.sun.jna.ptr.IntByReference; - - -import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tModuleType; -import edu.wpi.first.wpilibj.hal.DIOJNI; -import edu.wpi.first.wpilibj.hal.PWMJNI; -import edu.wpi.first.wpilibj.hal.RelayJNI; -import edu.wpi.first.wpilibj.hal.HALLibrary; -import edu.wpi.first.wpilibj.hal.HALUtil; - -/** - * Class representing a digital module - * - * @author dtjones - */ -public class DigitalModule extends Module { - - /** - * Expected loop timing - */ - public static final int kExpectedLoopTiming = 260; - private int m_module; - private ByteBuffer[] m_digital_ports; - private ByteBuffer[] m_relay_ports; - private ByteBuffer[] m_pwm_ports; - - /** - * Get an instance of an Digital Module. Singleton digital module creation - * where a module is allocated on the first use and the same module is - * returned on subsequent uses. - * - * @param moduleNumber - * The number of the digital module to access. - * @return The digital module of the specified number. - */ - public static synchronized DigitalModule getInstance(final int moduleNumber) { - SensorBase.checkDigitalModule(moduleNumber); - return (DigitalModule) getModule(tModuleType.kModuleType_Digital, - moduleNumber); - } - - /** - * Create a new digital module - * - * @param moduleNumber - * The number of the digital module to use (1 or 2) - */ - protected DigitalModule(final int moduleNumber) { - super(tModuleType.kModuleType_Digital, moduleNumber); - m_module = moduleNumber; - - m_digital_ports = new ByteBuffer[SensorBase.kDigitalChannels]; - for (int i = 0; i < SensorBase.kDigitalChannels; i++) { - ByteBuffer port_pointer = DIOJNI.getPortWithModule( - (byte) moduleNumber, (byte) i); - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - m_digital_ports[i] = DIOJNI.initializeDigitalPort(port_pointer, - status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - m_relay_ports = new ByteBuffer[SensorBase.kRelayChannels]; - for (int i = 0; i < SensorBase.kRelayChannels; i++) { - ByteBuffer port_pointer = RelayJNI.getPortWithModule( - (byte) moduleNumber, (byte) i); - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - m_relay_ports[i] = RelayJNI.initializeDigitalPort(port_pointer, - status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - m_pwm_ports = new ByteBuffer[SensorBase.kPwmChannels]; - for (int i = 0; i < SensorBase.kPwmChannels; i++) { - ByteBuffer port_pointer = PWMJNI.getPortWithModule( - (byte) moduleNumber, (byte) i); - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - m_pwm_ports[i] = PWMJNI.initializeDigitalPort(port_pointer, - status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - } - - /** - * Set a PWM channel to the desired value. The values range from 0 to 255 - * and the period is controlled by the PWM Period and MinHigh registers. - * - * @param channel - * The PWM channel to set. - * @param value - * The PWM value to set. - */ - public void setPWM(final int channel, final int value) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWM(m_pwm_ports[channel], (short) value, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Get a value from a PWM channel. The values range from 0 to 255. - * - * @param channel - * The PWM channel to read from. - * @return The raw PWM value. - */ - public int getPWM(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = (int) PWMJNI.getPWM(m_pwm_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Set how how often the PWM signal is squelched, thus scaling the period. - * - * @param channel - * The PWM channel to configure. - * @param squelchMask - * The 2-bit mask of outputs to squelch. - */ - public void setPWMPeriodScale(final int channel, final int squelchMask) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWMPeriodScale(m_pwm_ports[channel], squelchMask, - status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Set the state of a relay. Set the state of a relay output to be forward. - * Relays have two outputs and each is independently set to 0v or 12v. - * - * @param channel - * The Relay channel. - * @param on - * Indicates whether to set the relay to the On state. - */ - public void setRelayForward(final int channel, final boolean on) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - RelayJNI.setRelayForward(m_relay_ports[channel], (byte) (on ? 1 - : 0), status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Set the state of a relay. Set the state of a relay output to be reverse. - * Relays have two outputs and each is independently set to 0v or 12v. - * - * @param channel - * The Relay channel. - * @param on - * Indicates whether to set the relay to the On state. - */ - public void setRelayReverse(final int channel, final boolean on) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - RelayJNI.setRelayReverse(m_relay_ports[channel], (byte) (on ? 1 - : 0), status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Get the current state of the forward relay channel - * - * @param channel - * the channel of the relay to get - * @return The current state of the relay. - */ - public boolean getRelayForward(int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - boolean value = RelayJNI.getRelayForward(m_relay_ports[channel], - status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the current state of all of the forward relay channels on this - * module. - * - * @return The state of all forward relay channels as a byte. - */ - public byte getRelayForward() { - byte value = 0; - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < SensorBase.kRelayChannels; i++) { - value |= RelayJNI.getRelayForward(m_relay_ports[i], status.asIntBuffer()) << i; - } - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the current state of the reverse relay channel - * - * @param channel - * the channel of the relay to get - * @return The current statte of the relay - */ - public boolean getRelayReverse(int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - boolean value = RelayJNI.getRelayReverse(m_relay_ports[channel], - status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Get the current state of all of the reverse relay channels on this - * module. - * - * @return The state of all forward relay channels as a byte. - */ - public byte getRelayReverse() { - byte value = 0; - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < SensorBase.kRelayChannels; i++) { - value |= RelayJNI.getRelayReverse(m_relay_ports[i], status.asIntBuffer()) << i; - } - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Allocate Digital I/O channels. Allocate channels so that they are not - * accidently reused. Also the direction is set at the time of the - * allocation. - * - * @param channel - * The channel to allocate. - * @param input - * Indicates whether the I/O pin is an input (true) or an output - * (false). - * @return True if the I/O pin was allocated, false otherwise. - */ - public boolean allocateDIO(final int channel, final boolean input) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - boolean allocated = DIOJNI.allocateDIO( - m_digital_ports[channel], (byte) (input ? 1 : 0), status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return allocated; - } - - /** - * Free the resource associated with a digital I/O channel. - * - * @param channel - * The channel whose resources should be freed. - */ - public void freeDIO(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - DIOJNI.freeDIO(m_digital_ports[channel], status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Write a digital I/O bit to the FPGA. Set a single value on a digital I/O - * channel. - * - * @param channel - * The channel to set. - * @param value - * The value to set. - */ - public void setDIO(final int channel, final boolean value) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - DIOJNI.setDIO(m_digital_ports[channel], (byte) (value ? 1 : 0), - status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Read a digital I/O bit from the FPGA. Get a single value from a digital - * I/O channel. - * - * @param channel - * The channel to read - * @return The value of the selected channel - */ - public boolean getDIO(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - boolean value = DIOJNI.getDIO(m_digital_ports[channel], status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Read the state of all the Digital I/O lines from the FPGA These are not - * remapped to logical order. They are still in hardware order. - * - * @return The state of all the Digital IO lines in hardware order - */ - public short getAllDIO() { - short value = 0; - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < SensorBase.kDigitalChannels; i++) { - value |= DIOJNI.getDIO(m_digital_ports[i], status.asIntBuffer()) << i; - } - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Read the direction of a digital I/O line - * - * @param channel - * The channel of the DIO to get the direction of. - * @return True if the digital channel is configured as an output, false if - * it is an input - */ - public boolean getDIODirection(int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - boolean value = DIOJNI.getDIODirection( - m_digital_ports[channel], status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Read the direction of all the Digital I/O lines from the FPGA A 1 bit - * means output and a 0 bit means input. These are not remapped to logical - * order. They are still in hardware order. - * - * @return The direction of all the Digital IO lines in hardware order - */ - public short getDIODirection() { - byte value = 0; - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < SensorBase.kDigitalChannels; i++) { - value |= DIOJNI.getDIODirection(m_digital_ports[i], status.asIntBuffer()) << i; - } - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Generate a single pulse. Write a pulse to the specified digital output - * channel. There can only be a single pulse going at any time. - * - * @param channel - * The channel to pulse. - * @param pulseLength - * The length of the pulse. - */ - public void pulse(final int channel, final float pulseLength) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - DIOJNI.pulse(m_digital_ports[channel], pulseLength, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * @deprecated Generate a single pulse. Write a pulse to the specified - * digital output channel. There can only be a single pulse - * going at any time. - * - * @param channel - * The channel to pulse. - * @param pulseLength - * The length of the pulse. - */ - public void pulse(final int channel, final int pulseLength) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - float convertedPulse = (float) (pulseLength / 1.0e9 * (DIOJNI.getLoopTiming(status.asIntBuffer()) * 25)); - System.err - .println("You should use the float version of pulse for portability. This is deprecated"); - DIOJNI.pulse(m_digital_ports[channel], convertedPulse, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Check a DIO line to see if it is currently generating a pulse. - * - * @param channel - * The channel to check. - * @return True if the channel is pulsing, false otherwise. - */ - public boolean isPulsing(final int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - boolean value = DIOJNI.isPulsing(m_digital_ports[channel], - status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Check if any DIO line is currently generating a pulse. - * - * @return True if any channel is pulsing, false otherwise. - */ - public boolean isPulsing() { - boolean value; - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - value = DIOJNI.isAnyPulsingWithModule((byte) m_module, status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Allocate a DO PWM Generator. Allocate PWM generators so that they are not - * accidently reused. - */ - public ByteBuffer allocateDO_PWM() { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - ByteBuffer value = PWMJNI.allocatePWMWithModule((byte) m_module, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } - - /** - * Free the resource associated with a DO PWM generator. - */ - public void freeDO_PWM(ByteBuffer pwmGenerator) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.freePWMWithModule((byte) m_module, pwmGenerator, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Change the frequency of the DO PWM generator. - * - * The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is - * logarithmic. - * - * @param rate - * The frequency to output all digital output PWM signals on this - * module. - */ - public void setDO_PWMRate(double rate) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWMRateWithModule((byte) m_module, rate, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Configure which DO channel the PWM siganl is output on - * - * @param pwmGenerator - * The generator index reserved by allocateDO_PWM() - * @param channel - * The Digital Output channel to output on - */ - public void setDO_PWMOutputChannel(ByteBuffer pwmGenerator, int channel) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWMOutputChannelWithModule((byte) m_module, pwmGenerator, - channel, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Configure the duty-cycle of the PWM generator - * - * @param pwmGenerator - * The generator index reserved by allocateDO_PWM() - * @param dutyCycle - * The percent duty cycle to output [0..1]. - */ - public void setDO_PWMDutyCycle(ByteBuffer pwmGenerator, double dutyCycle) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWMDutyCycleWithModule((byte) m_module, pwmGenerator, dutyCycle, status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - } - - /** - * Get the loop timing of the Digital Module - * - * @return The number of clock ticks per DIO loop - */ - public int getLoopTiming() { - ByteBuffer status = ByteBuffer.allocateDirect(4); - // set the byte order - status.order(ByteOrder.LITTLE_ENDIAN); - int value = DIOJNI.getLoopTiming(status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); - return value; - } -} diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java index 9cb42d7363..1036e29a24 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java @@ -138,25 +138,22 @@ public class DigitalOutput extends DigitalSource implements IInputOutput, * The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is * logarithmic. * - * There is only one PWM frequency per digital module. + * There is only one PWM frequency for all channnels. * - * @param rate - * The frequency to output all digital output PWM signals on this - * module. + * @param rate The frequency to output all digital output PWM signals. */ public void setPWMRate(double rate) { ByteBuffer status = ByteBuffer.allocateDirect(4); // set the byte order status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWMRateWithModule((byte) 1, rate, - status.asIntBuffer()); + PWMJNI.setPWMRate(rate, status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); } /** * Enable a PWM Output on this line. * - * Allocate one of the 4 DO PWM generator resources from this module. + * Allocate one of the 4 DO PWM generator resources. * * Supply the initial duty-cycle to output so as to avoid a glitch when * first starting. @@ -173,12 +170,12 @@ public class DigitalOutput extends DigitalSource implements IInputOutput, ByteBuffer status = ByteBuffer.allocateDirect(4); // set the byte order status.order(ByteOrder.LITTLE_ENDIAN); - m_pwmGenerator = PWMJNI.allocatePWMWithModule((byte) 1, status.asIntBuffer()); + m_pwmGenerator = PWMJNI.allocatePWM(status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); PWMJNI.setPWMDutyCycle(m_pwmGenerator, initialDutyCycle, status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); - PWMJNI.setPWMOutputChannelWithModule((byte) 1, m_pwmGenerator, m_channel, status.asIntBuffer()); + PWMJNI.setPWMOutputChannel(m_pwmGenerator, m_channel, status.asIntBuffer()); } /** @@ -193,7 +190,7 @@ public class DigitalOutput extends DigitalSource implements IInputOutput, status.order(ByteOrder.LITTLE_ENDIAN); PWMJNI.setPWMOutputChannel(m_pwmGenerator, kDigitalChannels, status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); - PWMJNI.freePWMWithModule((byte) 1, m_pwmGenerator, status.asIntBuffer()); + PWMJNI.freePWM(m_pwmGenerator, status.asIntBuffer()); m_pwmGenerator = null; } @@ -210,7 +207,7 @@ public class DigitalOutput extends DigitalSource implements IInputOutput, ByteBuffer status = ByteBuffer.allocateDirect(4); // set the byte order status.order(ByteOrder.LITTLE_ENDIAN); - PWMJNI.setPWMDutyCycleWithModule((byte) 1, m_pwmGenerator, dutyCycle, status.asIntBuffer()); + PWMJNI.setPWMDutyCycle(m_pwmGenerator, dutyCycle, status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); } diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java index b681ba4f86..9fda2678fa 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java @@ -44,7 +44,7 @@ public abstract class DigitalSource extends InterruptableSensorBase { + " is already allocated"); } - ByteBuffer port_pointer = DIOJNI.getPortWithModule((byte) 1, (byte) channel); + ByteBuffer port_pointer = DIOJNI.getPort((byte) channel); ByteBuffer status = ByteBuffer.allocateDirect(4); // set the byte order status.order(ByteOrder.LITTLE_ENDIAN); diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/GearTooth.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/GearTooth.java index e35b04f099..645b698d78 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/GearTooth.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/GearTooth.java @@ -52,9 +52,9 @@ public class GearTooth extends Counter implements ISensor { super(channel); enableDirectionSensing(directionSensitive); if(directionSensitive) { - UsageReporting.report(tResourceType.kResourceType_GearTooth, channel, DigitalModule.getDefaultDigitalModule()-1, "D"); + UsageReporting.report(tResourceType.kResourceType_GearTooth, channel, 0, "D"); } else { - UsageReporting.report(tResourceType.kResourceType_GearTooth, channel, DigitalModule.getDefaultDigitalModule()-1); + UsageReporting.report(tResourceType.kResourceType_GearTooth, channel, 0); } LiveWindow.addSensor("GearTooth", channel, this); } diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Gyro.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Gyro.java index 87c6243150..8d9bd81d0a 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Gyro.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Gyro.java @@ -57,7 +57,7 @@ public class Gyro extends SensorBase implements PIDSource, ISensor, m_analog.setOversampleBits(kOversampleBits); double sampleRate = kSamplesPerSecond * (1 << (kAverageBits + kOversampleBits)); - m_analog.setSampleRate(sampleRate); + AnalogInput.setGlobalSampleRate(sampleRate); Timer.delay(1.0); m_analog.initAccumulator(); @@ -160,7 +160,7 @@ public class Gyro extends SensorBase implements PIDSource, ISensor, * 1e-9 * m_analog.getLSBWeight() * (1 << m_analog.getAverageBits()) - / (m_analog.getModule().getSampleRate() * m_voltsPerDegreePerSecond); + / (AnalogInput.getGlobalSampleRate() * m_voltsPerDegreePerSecond); return scaledValue; } diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/I2C.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/I2C.java index 8476aa0f11..224921ddcc 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/I2C.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/I2C.java @@ -28,11 +28,11 @@ import edu.wpi.first.wpilibj.util.BoundaryException; public class I2C extends SensorBase { public enum Port {kOnboard(0), kMXP(1); private int value; - + private Port(int value){ this.value = value; } - + public int getValue(){ return this.value; } @@ -44,21 +44,19 @@ public class I2C extends SensorBase { /** * Constructor. * - * @param module - * The Digital Module to which the device is connected. * @param deviceAddress * The address of the device on the I2C bus. */ public I2C(Port port, int deviceAddress) { ByteBuffer status = ByteBuffer.allocateDirect(4); status.order(ByteOrder.LITTLE_ENDIAN); - + m_port = port; m_deviceAddress = deviceAddress; - + I2CJNI.i2CInitialize((byte)m_port.getValue(), status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); - + UsageReporting.report(tResourceType.kResourceType_I2C, deviceAddress); } @@ -93,7 +91,7 @@ public class I2C extends SensorBase { ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(receiveSize); aborted = I2CJNI - .i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress, + .i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer, (byte) sendSize, dataReceivedBuffer, (byte) receiveSize) != 0; /*if (status.get() == HALUtil.PARAMETER_OUT_OF_RANGE) { @@ -140,13 +138,13 @@ public class I2C extends SensorBase { byte[] buffer = new byte[2]; buffer[0] = (byte) registerAddress; buffer[1] = (byte) data; - + ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(2); dataToSendBuffer.put(buffer); - + return I2CJNI.i2CWrite((byte)m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer, (byte)buffer.length) < 0; } - + /** * Execute a write transaction with the device. * @@ -156,10 +154,10 @@ public class I2C extends SensorBase { * @param data * The data to write to the device. */ - public synchronized boolean writeBulk(byte[] data) { + public synchronized boolean writeBulk(byte[] data) { ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(data.length); dataToSendBuffer.put(data); - + return I2CJNI.i2CWrite((byte)m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer, (byte)data.length) < 0; } @@ -190,7 +188,7 @@ public class I2C extends SensorBase { return transaction(registerAddressArray, registerAddressArray.length, buffer, count); } - + /** * Execute a read only transaction with the device. * @@ -209,9 +207,9 @@ public class I2C extends SensorBase { if (buffer == null) { throw new NullPointerException("Null return buffer was given"); } - + ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(count); - + int retVal = I2CJNI.i2CRead((byte)m_port.getValue(), (byte) m_deviceAddress, dataReceivedBuffer, (byte)count); dataReceivedBuffer.get(buffer); return retVal < 0; diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Module.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Module.java deleted file mode 100644 index 3f26f73c9d..0000000000 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Module.java +++ /dev/null @@ -1,93 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -package edu.wpi.first.wpilibj; - -import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary; -import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tModuleType; - -/** - * Base class for AnalogModule and DigitalModule. - * - * @author dtjones - */ -public class Module extends SensorBase { - - /** - * An array holding the object representing each module - */ - protected static Module[] m_modules = new Module[tModuleType.kModuleType_Solenoid * FRCNetworkCommunicationsLibrary.kMaxModuleNumber + (FRCNetworkCommunicationsLibrary.kMaxModuleNumber - 1)]; - /** - * The module number of the module - */ - protected int m_moduleNumber; - protected int m_moduleType; - - /** - * Constructor. - * - * @param moduleNumber The number of this module (1 or 2). - */ - protected Module(int moduleType, final int moduleNumber) { - m_modules[toIndex(moduleType, moduleNumber)] = this; - m_moduleNumber = moduleNumber; - } - - /** - * Gets the module number associated with a module. - * - * @return The module's number. - */ - public int getModuleNumber() { - return m_moduleNumber; - } - - /** - * Gets the module type associated with a module. - * - * @return The module's type. - */ - public int getModuleType() { - return m_moduleType; - } - - /** - * Static module singleton factory. - * - * @param moduleType The type of the module represented. - * @param moduleNumber The module index within the module type. - * @return the module - */ - public static Module getModule(int moduleType, int moduleNumber) { - if(m_modules[toIndex(moduleType, moduleNumber)] == null) { - if(moduleType == tModuleType.kModuleType_Analog) { - new AnalogModule(moduleNumber); - } else if (moduleType == tModuleType.kModuleType_Digital) { - new DigitalModule(moduleNumber); - /* } else if (moduleType.equals(ModulePresence.ModuleType.kSolenoid)) { - new Sol - */ - } else { - throw new RuntimeException("A module of type "+moduleType+" with module index "+moduleNumber); - } - } - return m_modules[toIndex(moduleType, moduleNumber)]; - } - - /** - * Create an index into m_modules based on type and number - * - * @param moduleType The type of the module represented. - * @param moduleNumber The module index within the module type. - * @return The index into m_modules. - */ - private static int toIndex(int moduleType, int moduleNumber) { - if(moduleNumber == 0 || moduleNumber > FRCNetworkCommunicationsLibrary.kMaxModuleNumber) - return 0; - return moduleType * FRCNetworkCommunicationsLibrary.kMaxModuleNumber + (moduleNumber - 1); - } -} diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/PWM.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/PWM.java index 44539f13fc..530d267ca6 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/PWM.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/PWM.java @@ -7,14 +7,19 @@ package edu.wpi.first.wpilibj; +import java.nio.ByteOrder; +import java.nio.ByteBuffer; + import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; import edu.wpi.first.wpilibj.communication.UsageReporting; import edu.wpi.first.wpilibj.hal.PWMJNI; +import edu.wpi.first.wpilibj.hal.DIOJNI; import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable; import edu.wpi.first.wpilibj.tables.ITable; import edu.wpi.first.wpilibj.tables.ITableListener; import edu.wpi.first.wpilibj.util.AllocationException; import edu.wpi.first.wpilibj.util.CheckedAllocationException; +import edu.wpi.first.wpilibj.hal.HALUtil; /** * Class implements the PWM generation in the FPGA. @@ -32,427 +37,457 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException; * 0 = disabled (i.e. PWM output is held low) */ public class PWM extends SensorBase implements LiveWindowSendable { + private static Resource allocated = new Resource( kPwmChannels); + + /** + * Represents the amount to multiply the minimum servo-pulse pwm period by. + */ + public static class PeriodMultiplier { + + /** + * The integer value representing this enumeration + */ + public final int value; + static final int k1X_val = 1; + static final int k2X_val = 2; + static final int k4X_val = 4; + /** + * Period Multiplier: don't skip pulses + */ + public static final PeriodMultiplier k1X = new PeriodMultiplier(k1X_val); + /** + * Period Multiplier: skip every other pulse + */ + public static final PeriodMultiplier k2X = new PeriodMultiplier(k2X_val); + /** + * Period Multiplier: skip three out of four pulses + */ + public static final PeriodMultiplier k4X = new PeriodMultiplier(k4X_val); + + private PeriodMultiplier(int value) { + this.value = value; + } + } + private int m_channel; + private ByteBuffer m_port; + /** + * kDefaultPwmPeriod is in ms + * + * - 20ms periods (50 Hz) are the "safest" setting in that this works for all devices + * - 20ms periods seem to be desirable for Vex Motors + * - 20ms periods are the specified period for HS-322HD servos, but work reliably down + * to 10.0 ms; starting at about 8.5ms, the servo sometimes hums and get hot; + * by 5.0ms the hum is nearly continuous + * - 10ms periods work well for Victor 884 + * - 5ms periods allows higher update rates for Luminary Micro Jaguar speed controllers. + * Due to the shipping firmware on the Jaguar, we can't run the update period less + * than 5.05 ms. + * + * kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period scaling is implemented as an + * output squelch to get longer periods for old devices. + */ + protected static final double kDefaultPwmPeriod = 5.05; + /** + * kDefaultPwmCenter is the PWM range center in ms + */ + protected static final double kDefaultPwmCenter = 1.5; + /** + * kDefaultPWMStepsDown is the number of PWM steps below the centerpoint + */ + protected static final int kDefaultPwmStepsDown = 1000; + public static final int kPwmDisabled = 0; + boolean m_eliminateDeadband; + int m_maxPwm; + int m_deadbandMaxPwm; + int m_centerPwm; + int m_deadbandMinPwm; + int m_minPwm; + + /** + * Initialize PWMs given a channel. + * + * This method is private and is the common path for all the constructors + * for creating PWM instances. Checks channel value ranges and allocates + * the appropriate channel. The allocation is only done to help users + * ensure that they don't double assign channels. + */ + private void initPWM(final int channel) { + checkPWMChannel(channel); + try { + allocated.allocate(channel); + } catch (CheckedAllocationException e) { + throw new AllocationException( + "PWM channel " + channel + " is already allocated"); + } + m_channel = channel; + + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel), status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + + PWMJNI.setPWM(m_port, (short) 0, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + + m_eliminateDeadband = false; + + UsageReporting.report(tResourceType.kResourceType_PWM, channel); + } + + /** + * Allocate a PWM given a channel. + * + * @param channel The PWM channel. + */ + public PWM(final int channel) { + initPWM(channel); + } + + /** + * Free the PWM channel. + * + * Free the resource associated with the PWM channel and set the value to 0. + */ + public void free() { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + PWMJNI.setPWM(m_port, (short) 0, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + + PWMJNI.freeDIO(m_port, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + + allocated.free(m_channel); + } + + /** + * Optionally eliminate the deadband from a speed controller. + * @param eliminateDeadband If true, set the motor curve on the Jaguar to eliminate + * the deadband in the middle of the range. Otherwise, keep the full range without + * modifying any values. + */ + public void enableDeadbandElimination(boolean eliminateDeadband) { + m_eliminateDeadband = eliminateDeadband; + } + + /** + * Set the bounds on the PWM values. + * This sets the bounds on the PWM values for a particular each type of controller. The values + * determine the upper and lower speeds as well as the deadband bracket. + * @deprecated Recommended to set bounds in ms using {@link #setBounds(double, double, double, double, double)} + * @param max The Minimum pwm value + * @param deadbandMax The high end of the deadband range + * @param center The center speed (off) + * @param deadbandMin The low end of the deadband range + * @param min The minimum pwm value + */ + public void setBounds(final int max, final int deadbandMax, final int center, final int deadbandMin, final int min) { + m_maxPwm = max; + m_deadbandMaxPwm = deadbandMax; + m_centerPwm = center; + m_deadbandMinPwm = deadbandMin; + m_minPwm = min; + } + + /** + * Set the bounds on the PWM pulse widths. + * This sets the bounds on the PWM values for a particular type of controller. The values + * determine the upper and lower speeds as well as the deadband bracket. + * @param max The max PWM pulse width in ms + * @param deadbandMax The high end of the deadband range pulse width in ms + * @param center The center (off) pulse width in ms + * @param deadbandMin The low end of the deadband pulse width in ms + * @param min The minimum pulse width in ms + */ + protected void setBounds(double max, double deadbandMax, double center, double deadbandMin, double min) { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + double loopTime = DIOJNI.getLoopTiming(status.asIntBuffer())/(kSystemClockTicksPerMicrosecond*1e3); + + m_maxPwm = (int)((max-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); + m_deadbandMaxPwm = (int)((deadbandMax-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); + m_centerPwm = (int)((center-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); + m_deadbandMinPwm = (int)((deadbandMin-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); + m_minPwm = (int)((min-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); + } + + /** + * Gets the channel number associated with the PWM Object. + * + * @return The channel number. + */ + public int getChannel() { + return m_channel; + } + + /** + * Set the PWM value based on a position. + * + * This is intended to be used by servos. + * + * @pre SetMaxPositivePwm() called. + * @pre SetMinNegativePwm() called. + * + * @param pos The position to set the servo between 0.0 and 1.0. + */ + public void setPosition(double pos) { + if (pos < 0.0) { + pos = 0.0; + } else if (pos > 1.0) { + pos = 1.0; + } + + int rawValue; + // note, need to perform the multiplication below as floating point before converting to int + rawValue = (int) ((pos * (double)getFullRangeScaleFactor()) + getMinNegativePwm()); + + // send the computed pwm value to the FPGA + setRaw(rawValue); + } + + /** + * Get the PWM value in terms of a position. + * + * This is intended to be used by servos. + * + * @pre SetMaxPositivePwm() called. + * @pre SetMinNegativePwm() called. + * + * @return The position the servo is set to between 0.0 and 1.0. + */ + public double getPosition() { + int value = getRaw(); + if (value < getMinNegativePwm()) { + return 0.0; + } else if (value > getMaxPositivePwm()) { + return 1.0; + } else { + return (double)(value - getMinNegativePwm()) / (double)getFullRangeScaleFactor(); + } + } + + /** + * Set the PWM value based on a speed. + * + * This is intended to be used by speed controllers. + * + * @pre SetMaxPositivePwm() called. + * @pre SetMinPositivePwm() called. + * @pre SetCenterPwm() called. + * @pre SetMaxNegativePwm() called. + * @pre SetMinNegativePwm() called. + * + * @param speed The speed to set the speed controller between -1.0 and 1.0. + */ + final void setSpeed(double speed) { + // clamp speed to be in the range 1.0 >= speed >= -1.0 + if (speed < -1.0) { + speed = -1.0; + } else if (speed > 1.0) { + speed = 1.0; + } + + // calculate the desired output pwm value by scaling the speed appropriately + int rawValue; + if (speed == 0.0) { + rawValue = getCenterPwm(); + } else if (speed > 0.0) { + rawValue = (int) (speed * ((double)getPositiveScaleFactor()) + + ((double)getMinPositivePwm()) + 0.5); + } else { + rawValue = (int) (speed * ((double)getNegativeScaleFactor()) + + ((double)getMaxNegativePwm()) + 0.5); + } + + // send the computed pwm value to the FPGA + setRaw(rawValue); + } + + /** + * Get the PWM value in terms of speed. + * + * This is intended to be used by speed controllers. + * + * @pre SetMaxPositivePwm() called. + * @pre SetMinPositivePwm() called. + * @pre SetMaxNegativePwm() called. + * @pre SetMinNegativePwm() called. + * + * @return The most recently set speed between -1.0 and 1.0. + */ + public double getSpeed() { + int value = getRaw(); + if (value > getMaxPositivePwm()) { + return 1.0; + } else if (value < getMinNegativePwm()) { + return -1.0; + } else if (value > getMinPositivePwm()) { + return (double) (value - getMinPositivePwm()) / (double)getPositiveScaleFactor(); + } else if (value < getMaxNegativePwm()) { + return (double) (value - getMaxNegativePwm()) / (double)getNegativeScaleFactor(); + } else { + return 0.0; + } + } + + /** + * Set the PWM value directly to the hardware. + * + * Write a raw value to a PWM channel. + * + * @param value Raw PWM value. Range 0 - 255. + */ + public void setRaw(int value) { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + PWMJNI.setPWM(m_port, (short) value, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + } + + /** + * Get the PWM value directly from the hardware. + * + * Read a raw value from a PWM channel. + * + * @return Raw PWM control value. Range: 0 - 255. + */ + public int getRaw() { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + int value = PWMJNI.getPWM(m_port, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + + return value; + } + + /** + * Slow down the PWM signal for old devices. + * + * @param mult The period multiplier to apply to this channel + */ + public void setPeriodMultiplier(PeriodMultiplier mult) { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + switch (mult.value) { + case PeriodMultiplier.k4X_val: + // Squelch 3 out of 4 outputs + PWMJNI.setPWMPeriodScale(m_port, 3, status.asIntBuffer()); + break; + case PeriodMultiplier.k2X_val: + // Squelch 1 out of 2 outputs + PWMJNI.setPWMPeriodScale(m_port, 1, status.asIntBuffer()); + break; + case PeriodMultiplier.k1X_val: + // Don't squelch any outputs + PWMJNI.setPWMPeriodScale(m_port, 0, status.asIntBuffer()); + break; + default: + //Cannot hit this, limited by PeriodMultiplier enum + } + + HALUtil.checkStatus(status.asIntBuffer()); + } + + private int getMaxPositivePwm() { + return m_maxPwm; + } + + ; + + private int getMinPositivePwm() { + return m_eliminateDeadband ? m_deadbandMaxPwm : m_centerPwm + 1; + } + + ; + + private int getCenterPwm() { + return m_centerPwm; + } + + ; + + private int getMaxNegativePwm() { + return m_eliminateDeadband ? m_deadbandMinPwm : m_centerPwm - 1; + } + + ; + + private int getMinNegativePwm() { + return m_minPwm; + } + + ; + + private int getPositiveScaleFactor() { + return getMaxPositivePwm() - getMinPositivePwm(); + } ///< The scale for positive speeds. + + private int getNegativeScaleFactor() { + return getMaxNegativePwm() - getMinNegativePwm(); + } ///< The scale for negative speeds. + + private int getFullRangeScaleFactor() { + return getMaxPositivePwm() - getMinNegativePwm(); + } ///< The scale for positions. /* - * XXX: Refactor to no longer depend on the DigitalModule, and move all - * resource tracking into the HAL. This will wait until we get the unit - * tests running for the first time. + * Live Window code, only does anything if live window is activated. */ + public String getSmartDashboardType() { + return "Speed Controller"; + } + private ITable m_table; + private ITableListener m_table_listener; - private static Resource allocated = new Resource( kPwmChannels); + /** + * {@inheritDoc} + */ + public void initTable(ITable subtable) { + m_table = subtable; + updateTable(); + } - /** - * Represents the amount to multiply the minimum servo-pulse pwm period by. - */ - public static class PeriodMultiplier { + /** + * {@inheritDoc} + */ + public void updateTable() { + if (m_table != null) { + m_table.putNumber("Value", getSpeed()); + } + } - /** - * The integer value representing this enumeration - */ - public final int value; - static final int k1X_val = 1; - static final int k2X_val = 2; - static final int k4X_val = 4; - /** - * Period Multiplier: don't skip pulses - */ - public static final PeriodMultiplier k1X = new PeriodMultiplier(k1X_val); - /** - * Period Multiplier: skip every other pulse - */ - public static final PeriodMultiplier k2X = new PeriodMultiplier(k2X_val); - /** - * Period Multiplier: skip three out of four pulses - */ - public static final PeriodMultiplier k4X = new PeriodMultiplier(k4X_val); + /** + * {@inheritDoc} + */ + public ITable getTable() { + return m_table; + } - private PeriodMultiplier(int value) { - this.value = value; - } - } - private int m_channel; - private DigitalModule m_module; - /** - * kDefaultPwmPeriod is in ms - * - * - 20ms periods (50 Hz) are the "safest" setting in that this works for all devices - * - 20ms periods seem to be desirable for Vex Motors - * - 20ms periods are the specified period for HS-322HD servos, but work reliably down - * to 10.0 ms; starting at about 8.5ms, the servo sometimes hums and get hot; - * by 5.0ms the hum is nearly continuous - * - 10ms periods work well for Victor 884 - * - 5ms periods allows higher update rates for Luminary Micro Jaguar speed controllers. - * Due to the shipping firmware on the Jaguar, we can't run the update period less - * than 5.05 ms. - * - * kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period scaling is implemented as an - * output squelch to get longer periods for old devices. - */ - protected static final double kDefaultPwmPeriod = 5.05; - /** - * kDefaultPwmCenter is the PWM range center in ms - */ - protected static final double kDefaultPwmCenter = 1.5; - /** - * kDefaultPWMStepsDown is the number of PWM steps below the centerpoint - */ - protected static final int kDefaultPwmStepsDown = 1000; - public static final int kPwmDisabled = 0; - boolean m_eliminateDeadband; - int m_maxPwm; - int m_deadbandMaxPwm; - int m_centerPwm; - int m_deadbandMinPwm; - int m_minPwm; + /** + * {@inheritDoc} + */ + public void startLiveWindowMode() { + setSpeed(0); // Stop for safety + m_table_listener = new ITableListener() { + public void valueChanged(ITable itable, String key, Object value, boolean bln) { + setSpeed(((Double) value).doubleValue()); + } + }; + m_table.addTableListener("Value", m_table_listener, true); + } - /** - * Initialize PWMs given a channel. - * - * This method is private and is the common path for all the constructors for creating PWM - * instances. Checks module and channel value ranges and allocates the appropriate channel. - * The allocation is only done to help users ensure that they don't double assign channels. - */ - private void initPWM(final int channel) { - checkPWMChannel(channel); - try { - allocated.allocate(channel); - } catch (CheckedAllocationException e) { - throw new AllocationException( - "PWM channel " + channel + " is already allocated"); - } - m_channel = channel; - m_module = DigitalModule.getInstance(1); - m_module.setPWM(m_channel, kPwmDisabled); - m_eliminateDeadband = false; - - UsageReporting.report(tResourceType.kResourceType_PWM, channel); - } - - /** - * Allocate a PWM given a channel. - * - * @param channel The PWM channel. - */ - public PWM(final int channel) { - initPWM(channel); - } - - /** - * Free the PWM channel. - * - * Free the resource associated with the PWM channel and set the value to 0. - */ - public void free() { - m_module.setPWM(m_channel, kPwmDisabled); - m_module.freeDIO(m_channel); - allocated.free(m_channel); - } - - /** - * Optionally eliminate the deadband from a speed controller. - * @param eliminateDeadband If true, set the motor curve on the Jaguar to eliminate - * the deadband in the middle of the range. Otherwise, keep the full range without - * modifying any values. - */ - public void enableDeadbandElimination(boolean eliminateDeadband) { - m_eliminateDeadband = eliminateDeadband; - } - - /** - * Set the bounds on the PWM values. - * This sets the bounds on the PWM values for a particular each type of controller. The values - * determine the upper and lower speeds as well as the deadband bracket. - * @deprecated Recommended to set bounds in ms using {@link #setBounds(double, double, double, double, double)} - * @param max The Minimum pwm value - * @param deadbandMax The high end of the deadband range - * @param center The center speed (off) - * @param deadbandMin The low end of the deadband range - * @param min The minimum pwm value - */ - public void setBounds(final int max, final int deadbandMax, final int center, final int deadbandMin, final int min) { - m_maxPwm = max; - m_deadbandMaxPwm = deadbandMax; - m_centerPwm = center; - m_deadbandMinPwm = deadbandMin; - m_minPwm = min; - } - - /** - * Set the bounds on the PWM pulse widths. - * This sets the bounds on the PWM values for a particular type of controller. The values - * determine the upper and lower speeds as well as the deadband bracket. - * @param max The max PWM pulse width in ms - * @param deadbandMax The high end of the deadband range pulse width in ms - * @param center The center (off) pulse width in ms - * @param deadbandMin The low end of the deadband pulse width in ms - * @param min The minimum pulse width in ms - */ - protected void setBounds(double max, double deadbandMax, double center, double deadbandMin, double min) { - double loopTime = m_module.getLoopTiming()/(kSystemClockTicksPerMicrosecond*1e3); - - m_maxPwm = (int)((max-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); - m_deadbandMaxPwm = (int)((deadbandMax-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); - m_centerPwm = (int)((center-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); - m_deadbandMinPwm = (int)((deadbandMin-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); - m_minPwm = (int)((min-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1); - } - - /** - * Gets the channel number associated with the PWM Object. - * - * @return The channel number. - */ - public int getChannel() { - return m_channel; - } - - /** - * Set the PWM value based on a position. - * - * This is intended to be used by servos. - * - * @pre SetMaxPositivePwm() called. - * @pre SetMinNegativePwm() called. - * - * @param pos The position to set the servo between 0.0 and 1.0. - */ - public void setPosition(double pos) { - if (pos < 0.0) { - pos = 0.0; - } else if (pos > 1.0) { - pos = 1.0; - } - - int rawValue; - // note, need to perform the multiplication below as floating point before converting to int - rawValue = (int) ((pos * (double)getFullRangeScaleFactor()) + getMinNegativePwm()); - - // send the computed pwm value to the FPGA - setRaw(rawValue); - } - - /** - * Get the PWM value in terms of a position. - * - * This is intended to be used by servos. - * - * @pre SetMaxPositivePwm() called. - * @pre SetMinNegativePwm() called. - * - * @return The position the servo is set to between 0.0 and 1.0. - */ - public double getPosition() { - int value = getRaw(); - if (value < getMinNegativePwm()) { - return 0.0; - } else if (value > getMaxPositivePwm()) { - return 1.0; - } else { - return (double)(value - getMinNegativePwm()) / (double)getFullRangeScaleFactor(); - } - } - - /** - * Set the PWM value based on a speed. - * - * This is intended to be used by speed controllers. - * - * @pre SetMaxPositivePwm() called. - * @pre SetMinPositivePwm() called. - * @pre SetCenterPwm() called. - * @pre SetMaxNegativePwm() called. - * @pre SetMinNegativePwm() called. - * - * @param speed The speed to set the speed controller between -1.0 and 1.0. - */ - final void setSpeed(double speed) { - // clamp speed to be in the range 1.0 >= speed >= -1.0 - if (speed < -1.0) { - speed = -1.0; - } else if (speed > 1.0) { - speed = 1.0; - } - - // calculate the desired output pwm value by scaling the speed appropriately - int rawValue; - if (speed == 0.0) { - rawValue = getCenterPwm(); - } else if (speed > 0.0) { - rawValue = (int) (speed * ((double)getPositiveScaleFactor()) + - ((double)getMinPositivePwm()) + 0.5); - } else { - rawValue = (int) (speed * ((double)getNegativeScaleFactor()) + - ((double)getMaxNegativePwm()) + 0.5); - } - - // send the computed pwm value to the FPGA - setRaw(rawValue); - } - - /** - * Get the PWM value in terms of speed. - * - * This is intended to be used by speed controllers. - * - * @pre SetMaxPositivePwm() called. - * @pre SetMinPositivePwm() called. - * @pre SetMaxNegativePwm() called. - * @pre SetMinNegativePwm() called. - * - * @return The most recently set speed between -1.0 and 1.0. - */ - public double getSpeed() { - int value = getRaw(); - if (value > getMaxPositivePwm()) { - return 1.0; - } else if (value < getMinNegativePwm()) { - return -1.0; - } else if (value > getMinPositivePwm()) { - return (double) (value - getMinPositivePwm()) / (double)getPositiveScaleFactor(); - } else if (value < getMaxNegativePwm()) { - return (double) (value - getMaxNegativePwm()) / (double)getNegativeScaleFactor(); - } else { - return 0.0; - } - } - - /** - * Set the PWM value directly to the hardware. - * - * Write a raw value to a PWM channel. - * - * @param value Raw PWM value. Range 0 - 255. - */ - public void setRaw(int value) { - m_module.setPWM(m_channel, value); - } - - /** - * Get the PWM value directly from the hardware. - * - * Read a raw value from a PWM channel. - * - * @return Raw PWM control value. Range: 0 - 255. - */ - public int getRaw() { - return m_module.getPWM(m_channel); - } - - /** - * Slow down the PWM signal for old devices. - * - * @param mult The period multiplier to apply to this channel - */ - public void setPeriodMultiplier(PeriodMultiplier mult) { - switch (mult.value) { - case PeriodMultiplier.k4X_val: - m_module.setPWMPeriodScale(m_channel, 3); // Squelch 3 out of 4 outputs - break; - case PeriodMultiplier.k2X_val: - m_module.setPWMPeriodScale(m_channel, 1); // Squelch 1 out of 2 outputs - break; - case PeriodMultiplier.k1X_val: - m_module.setPWMPeriodScale(m_channel, 0); // Don't squelch any outputs - break; - default: - //Cannot hit this, limited by PeriodMultiplier enum - } - } - - private int getMaxPositivePwm() { - return m_maxPwm; - } - - ; - - private int getMinPositivePwm() { - return m_eliminateDeadband ? m_deadbandMaxPwm : m_centerPwm + 1; - } - - ; - - private int getCenterPwm() { - return m_centerPwm; - } - - ; - - private int getMaxNegativePwm() { - return m_eliminateDeadband ? m_deadbandMinPwm : m_centerPwm - 1; - } - - ; - - private int getMinNegativePwm() { - return m_minPwm; - } - - ; - - private int getPositiveScaleFactor() { - return getMaxPositivePwm() - getMinPositivePwm(); - } ///< The scale for positive speeds. - - private int getNegativeScaleFactor() { - return getMaxNegativePwm() - getMinNegativePwm(); - } ///< The scale for negative speeds. - - private int getFullRangeScaleFactor() { - return getMaxPositivePwm() - getMinNegativePwm(); - } ///< The scale for positions. - - /* - * Live Window code, only does anything if live window is activated. - */ - public String getSmartDashboardType() { - return "Speed Controller"; - } - private ITable m_table; - private ITableListener m_table_listener; - - /** - * {@inheritDoc} - */ - public void initTable(ITable subtable) { - m_table = subtable; - updateTable(); - } - - /** - * {@inheritDoc} - */ - public void updateTable() { - if (m_table != null) { - m_table.putNumber("Value", getSpeed()); - } - } - - /** - * {@inheritDoc} - */ - public ITable getTable() { - return m_table; - } - - /** - * {@inheritDoc} - */ - public void startLiveWindowMode() { - setSpeed(0); // Stop for safety - m_table_listener = new ITableListener() { - public void valueChanged(ITable itable, String key, Object value, boolean bln) { - setSpeed(((Double) value).doubleValue()); - } - }; - m_table.addTableListener("Value", m_table_listener, true); - } - - /** - * {@inheritDoc} - */ - public void stopLiveWindowMode() { - setSpeed(0); // Stop for safety - // TODO: Broken, should only remove the listener from "Value" only. - m_table.removeTableListener(m_table_listener); - } + /** + * {@inheritDoc} + */ + public void stopLiveWindowMode() { + setSpeed(0); // Stop for safety + // TODO: Broken, should only remove the listener from "Value" only. + m_table.removeTableListener(m_table_listener); + } } diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Relay.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Relay.java index fa8d0fd652..902022f4a3 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Relay.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Relay.java @@ -7,9 +7,15 @@ package edu.wpi.first.wpilibj; +import java.nio.ByteOrder; +import java.nio.ByteBuffer; + import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; import edu.wpi.first.wpilibj.communication.UsageReporting; +import edu.wpi.first.wpilibj.hal.DIOJNI; +import edu.wpi.first.wpilibj.hal.RelayJNI; import edu.wpi.first.wpilibj.hal.HALLibrary; +import edu.wpi.first.wpilibj.hal.HALUtil; import edu.wpi.first.wpilibj.livewindow.LiveWindow; import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable; import edu.wpi.first.wpilibj.parsing.IDeviceController; @@ -113,8 +119,8 @@ public class Relay extends SensorBase implements IDeviceController, } private int m_channel; + private ByteBuffer m_port; private Direction m_direction; - private DigitalModule m_module; private static Resource relayChannels = new Resource(kRelayChannels * 2); /** @@ -138,9 +144,13 @@ public class Relay extends SensorBase implements IDeviceController, } catch (CheckedAllocationException e) { throw new AllocationException("Relay channel " + m_channel + " is already allocated"); } - m_module = DigitalModule.getInstance(1); - m_module.setRelayForward(m_channel, false); - m_module.setRelayReverse(m_channel, false); + + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel), status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); + LiveWindow.addActuator("Relay", m_channel, this); } @@ -173,21 +183,22 @@ public class Relay extends SensorBase implements IDeviceController, } public void free() { - m_module.setRelayForward(m_channel, false); - m_module.setRelayReverse(m_channel, false); + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + RelayJNI.setRelayForward(m_port, (byte) 0, status.asIntBuffer()); + RelayJNI.setRelayForward(m_port, (byte) 0, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); if (m_direction == Direction.kBoth || m_direction == Direction.kForward) { - relayChannels.free(((m_module.getModuleNumber() - 1) - * kRelayChannels + m_channel) * 2); - m_module.freeDIO(((m_module.getModuleNumber() - 1) * kRelayChannels - + m_channel) * 2); + relayChannels.free(m_channel); } if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) { - relayChannels.free(((m_module.getModuleNumber() - 1) - * kRelayChannels + m_channel) * 2 + 1); - m_module.freeDIO(((m_module.getModuleNumber() - 1) * kRelayChannels - + m_channel) * 2 + 1); + relayChannels.free(m_channel + 1); } + + DIOJNI.freeDIO(m_port, status.asIntBuffer()); + HALUtil.checkStatus(status.asIntBuffer()); } /** @@ -207,25 +218,28 @@ public class Relay extends SensorBase implements IDeviceController, * The state to set the relay. */ public void set(Value value) { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + switch (value.value) { case Value.kOff_val: if (m_direction == Direction.kBoth || m_direction == Direction.kForward) { - m_module.setRelayForward(m_channel, false); + RelayJNI.setRelayForward(m_port, (byte) 0, status.asIntBuffer()); } if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) { - m_module.setRelayReverse(m_channel, false); + RelayJNI.setRelayReverse(m_port, (byte) 0, status.asIntBuffer()); } break; case Value.kOn_val: if (m_direction == Direction.kBoth || m_direction == Direction.kForward) { - m_module.setRelayForward(m_channel, true); + RelayJNI.setRelayForward(m_port, (byte) 1, status.asIntBuffer()); } if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) { - m_module.setRelayReverse(m_channel, true); + RelayJNI.setRelayReverse(m_port, (byte) 1, status.asIntBuffer()); } break; case Value.kForward_val: @@ -234,10 +248,10 @@ public class Relay extends SensorBase implements IDeviceController, "A relay configured for reverse cannot be set to forward"); if (m_direction == Direction.kBoth || m_direction == Direction.kForward) { - m_module.setRelayForward(m_channel, true); + RelayJNI.setRelayForward(m_port, (byte) 1, status.asIntBuffer()); } if (m_direction == Direction.kBoth) { - m_module.setRelayReverse(m_channel, false); + RelayJNI.setRelayReverse(m_port, (byte) 0, status.asIntBuffer()); } break; case Value.kReverse_val: @@ -245,16 +259,18 @@ public class Relay extends SensorBase implements IDeviceController, throw new InvalidValueException( "A relay configured for forward cannot be set to reverse"); if (m_direction == Direction.kBoth) { - m_module.setRelayForward(m_channel, false); + RelayJNI.setRelayForward(m_port, (byte) 0, status.asIntBuffer()); } if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) { - m_module.setRelayReverse(m_channel, true); + RelayJNI.setRelayReverse(m_port, (byte) 1, status.asIntBuffer()); } break; default: // Cannot hit this, limited by Value enum } + + HALUtil.checkStatus(status.asIntBuffer()); } /** @@ -268,8 +284,11 @@ public class Relay extends SensorBase implements IDeviceController, * @return The current state of the relay as a Relay::Value */ public Value get() { - if (m_module.getRelayForward(m_channel)) { - if (m_module.getRelayReverse(m_channel)) { + ByteBuffer status = ByteBuffer.allocateDirect(4); + status.order(ByteOrder.LITTLE_ENDIAN); + + if (RelayJNI.getRelayForward(m_port, status.asIntBuffer()) != 0) { + if (RelayJNI.getRelayReverse(m_port, status.asIntBuffer()) != 0) { return Value.kOn; } else { if (m_direction == Direction.kForward) { @@ -279,7 +298,7 @@ public class Relay extends SensorBase implements IDeviceController, } } } else { - if (m_module.getRelayReverse(m_channel)) { + if (RelayJNI.getRelayReverse(m_port, status.asIntBuffer()) != 0) { if (m_direction == Direction.kForward) { return Value.kOn; } else { diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/SensorBase.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/SensorBase.java index 9c5772d027..0a2d11b28b 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/SensorBase.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/SensorBase.java @@ -14,8 +14,6 @@ import edu.wpi.first.wpilibj.hal.AnalogJNI; * Base class for all sensors. * Stores most recent status information as well as containing utility functions for checking * channels and error processing. - * - * XXX: Wait, there's no exception thrown if we try to allocate a non-existent module? It that behavior correct? */ public abstract class SensorBase { // TODO: Refactor @@ -30,28 +28,19 @@ public abstract class SensorBase { // TODO: Refactor */ public static final int kDigitalChannels = 26; /** - * Number of digital modules - * XXX: This number is incorrect. We need to find the correct number. - */ - public static final int kDigitalModules = 1; - /** - * Number of analog input channels per module + * Number of analog input channels */ public static final int kAnalogInputChannels = 8; /** - * Number of analog output channels per module + * Number of analog output channels */ public static final int kAnalogOutputChannels = 2; - /** - * Number of analog modules - */ - public static final int kAnalogModules = 1; /** * Number of solenoid channels per module */ public static final int kSolenoidChannels = 8; /** - * Number of analog modules + * Number of solenoid modules */ public static final int kSolenoidModules = 2; /** @@ -67,8 +56,6 @@ public abstract class SensorBase { // TODO: Refactor */ public static final int kPDPChannels = 16; - private static int m_defaultAnalogModule = 1; - private static int m_defaultDigitalModule = 1; private static int m_defaultSolenoidModule = 0; /** @@ -78,33 +65,7 @@ public abstract class SensorBase { // TODO: Refactor } /** - * Sets the default Digital Module. - * This sets the default digital module to use for objects that are created without - * specifying the digital module in the constructor. The default module is initialized - * to the first module in the chassis. - * - * @param moduleNumber The number of the digital module to use. - */ - public static void setDefaultDigitalModule(final int moduleNumber) { - checkDigitalModule(moduleNumber); - SensorBase.m_defaultDigitalModule = moduleNumber; - } - - /** - * Sets the default Analog module. - * This sets the default analog module to use for objects that are created without - * specifying the analog module in the constructor. The default module is initialized - * to the first module in the chassis. - * - * @param moduleNumber The number of the analog module to use. - */ - public static void setDefaultAnalogModule(final int moduleNumber) { - checkAnalogModule(moduleNumber); - SensorBase.m_defaultAnalogModule = moduleNumber; - } - - /** - * Set the default location for the Solenoid (9472) module. + * Set the default location for the Solenoid module. * * @param moduleNumber The number of the solenoid module to use. */ @@ -113,49 +74,6 @@ public abstract class SensorBase { // TODO: Refactor SensorBase.m_defaultSolenoidModule = moduleNumber; } - /** - * Check that the digital module number is valid. - * Module numbers are 1 or 2 (they are no longer real cRIO slots). - * - * @param moduleNumber The digital module module number to check. - */ - protected static void checkDigitalModule(final int moduleNumber) { - if(DIOJNI.checkDigitalModule((byte) moduleNumber) != 1) - System.err.println("Digital module " + moduleNumber + " is not present."); - } - - /** - * Check that the digital module number is valid. - * Module numbers are 1 or 2 (they are no longer real cRIO slots). - * - * @param moduleNumber The digital module module number to check. - */ - protected static void checkRelayModule(final int moduleNumber) { - checkDigitalModule(moduleNumber); - } - - /** - * Check that the digital module number is valid. - * Module numbers are 1 or 2 (they are no longer real cRIO slots). - * - * @param moduleNumber The digital module module number to check. - */ - protected static void checkPWMModule(final int moduleNumber) { - checkDigitalModule(moduleNumber); - } - - /** - * Check that the analog module number is valid. - * Module numbers are 1 or 2 (they are no longer real cRIO slots). - * - * @param moduleNumber The analog module module number to check. - */ - protected static void checkAnalogModule(final int moduleNumber) { - if(AnalogJNI.checkAnalogModule((byte) (moduleNumber - 1)) != 0) { - System.err.println("Analog module " + moduleNumber + " is not present."); - } - } - /** * Verify that the solenoid module is correct. * Module numbers are 1 or 2 (they are no longer real cRIO slots). @@ -260,25 +178,7 @@ public abstract class SensorBase { // TODO: Refactor } /** - * Get the number of the default analog module. - * - * @return The number of the default analog module. - */ - public static int getDefaultAnalogModule() { - return SensorBase.m_defaultAnalogModule; - } - - /** - * Get the number of the default analog module. - * - * @return The number of the default analog module. - */ - public static int getDefaultDigitalModule() { - return SensorBase.m_defaultDigitalModule; - } - - /** - * Get the number of the default analog module. + * Get the number of the default solenoid module. * * @return The number of the default analog module. */ diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Solenoid.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Solenoid.java index fcfb25a1db..07d666ff16 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Solenoid.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Solenoid.java @@ -22,14 +22,14 @@ import edu.wpi.first.wpilibj.util.AllocationException; import edu.wpi.first.wpilibj.util.CheckedAllocationException; /** - * Solenoid class for running high voltage Digital Output (9472 module). + * Solenoid class for running high voltage Digital Output. * * The Solenoid class is typically used for pneumatics solenoids, but could be used - * for any device within the current spec of the 9472 module. + * for any device within the current spec of the PCM. */ public class Solenoid extends SolenoidBase implements LiveWindowSendable { - private int m_channel; ///< The channel on the module to control. + private int m_channel; ///< The channel to control. private ByteBuffer m_solenoid_port; /** @@ -39,16 +39,9 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable { checkSolenoidModule(m_moduleNumber); checkSolenoidChannel(m_channel); -// try { -// m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_channel - 1); -// } catch (CheckedAllocationException e) { -// throw new AllocationException( -// "Solenoid channel " + m_channel + " on module " + m_moduleNumber + " is already allocated"); -// } - ByteBuffer status = ByteBuffer.allocateDirect(4); status.order(ByteOrder.LITTLE_ENDIAN); - + ByteBuffer port = SolenoidJNI.getPortWithModule((byte) m_moduleNumber, (byte) m_channel); m_solenoid_port = SolenoidJNI.initializeSolenoidPort(port, status.asIntBuffer()); HALUtil.checkStatus(status.asIntBuffer()); diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java index 110c261237..d5d66d911e 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java @@ -162,8 +162,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, ISensor, /** * Create an instance of the Ultrasonic Sensor. * This is designed to supchannel the Daventech SRF04 and Vex ultrasonic - * sensors. This constructor assumes that both digital I/O channels are in - * the default digital module. Default unit is inches. + * sensors. Default unit is inches. * * @param pingChannel * The digital output channel that sends the pulse to initiate diff --git a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java index 9bb7ab2eae..5e3d3b66e1 100644 --- a/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java +++ b/wpilibj/wpilibJava/src/main/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java @@ -23,33 +23,33 @@ public class JNIWrapper jniLibrary = File.createTempFile("libwpilibJavaJNI", ".so"); // flag for delete on exit jniLibrary.deleteOnExit(); - + byte [] buffer = new byte[1024]; - + int readBytes; - + InputStream is = JNIWrapper.class.getResourceAsStream("/linux-arm/libwpilibJavaJNI.so"); - + OutputStream os = new FileOutputStream(jniLibrary); - + try { while((readBytes = is.read(buffer)) != -1 ) { os.write(buffer, 0, readBytes); } - + } finally { os.close(); is.close(); } - - + + libraryLoaded = true; } - + System.load(jniLibrary.getAbsolutePath()); } catch( Exception ex ) @@ -59,4 +59,5 @@ public class JNIWrapper } } public static native ByteBuffer getPortWithModule(byte module, byte pin); + public static native ByteBuffer getPort(byte pin); } diff --git a/wpilibj/wpilibJavaJNI/lib/JNIWrapper.cpp b/wpilibj/wpilibJavaJNI/lib/JNIWrapper.cpp index de4b9687ff..a31bf9a95e 100644 --- a/wpilibj/wpilibJavaJNI/lib/JNIWrapper.cpp +++ b/wpilibj/wpilibJavaJNI/lib/JNIWrapper.cpp @@ -23,3 +23,19 @@ JNIEXPORT jobject JNICALL Java_edu_wpi_first_wpilibj_hal_JNIWrapper_getPortWithM return env->NewDirectByteBuffer( portPtr, 4); } +/* + * Class: edu_wpi_first_wpilibj_hal_JNIWrapper + * Method: getPort + * Signature: (BB)Ljava/nio/ByteBuffer; + */ +JNIEXPORT jobject JNICALL Java_edu_wpi_first_wpilibj_hal_JNIWrapper_getPort + (JNIEnv * env, jclass, jbyte pin) +{ + //FILE_LOG(logDEBUG) << "Calling JNIWrapper getPortWithModlue"; + //FILE_LOG(logDEBUG) << "Module = " << (jint)module; + //FILE_LOG(logDEBUG) << "Pin = " << (jint)pin; + void** portPtr = (void**)new unsigned char[4]; + *portPtr = getPort(pin); + //FILE_LOG(logDEBUG) << "Port Ptr = " << *portPtr; + return env->NewDirectByteBuffer( portPtr, 4); +}