mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
[hal] Add support for DMA to Java (#3158)
This commit is contained in:
@@ -50,7 +50,7 @@ public class Counter implements CounterBase, Sendable, AutoCloseable {
|
||||
protected DigitalSource m_downSource; // /< What makes the counter count down.
|
||||
private boolean m_allocatedUpSource;
|
||||
private boolean m_allocatedDownSource;
|
||||
private int m_counter; // /< The FPGA counter object.
|
||||
int m_counter; // /< The FPGA counter object.
|
||||
private int m_index; // /< The index of this counter.
|
||||
private double m_distancePerPulse; // distance of travel for each tick
|
||||
|
||||
|
||||
110
wpilibj/src/main/java/edu/wpi/first/wpilibj/DMA.java
Normal file
110
wpilibj/src/main/java/edu/wpi/first/wpilibj/DMA.java
Normal file
@@ -0,0 +1,110 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj;
|
||||
|
||||
import edu.wpi.first.hal.DMAJNI;
|
||||
import edu.wpi.first.wpilibj.motorcontrol.PWMMotorController;
|
||||
|
||||
public class DMA implements AutoCloseable {
|
||||
final int m_dmaHandle;
|
||||
|
||||
public DMA() {
|
||||
m_dmaHandle = DMAJNI.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
DMAJNI.free(m_dmaHandle);
|
||||
}
|
||||
|
||||
public void setPause(boolean pause) {
|
||||
DMAJNI.setPause(m_dmaHandle, pause);
|
||||
}
|
||||
|
||||
public void setTimedTrigger(double periodSeconds) {
|
||||
DMAJNI.setTimedTrigger(m_dmaHandle, periodSeconds);
|
||||
}
|
||||
|
||||
public void setTimedTriggerCycles(int cycles) {
|
||||
DMAJNI.setTimedTriggerCycles(m_dmaHandle, cycles);
|
||||
}
|
||||
|
||||
public void addEncoder(Encoder encoder) {
|
||||
DMAJNI.addEncoder(m_dmaHandle, encoder.m_encoder);
|
||||
}
|
||||
|
||||
public void addEncoderPeriod(Encoder encoder) {
|
||||
DMAJNI.addEncoderPeriod(m_dmaHandle, encoder.m_encoder);
|
||||
}
|
||||
|
||||
public void addCounter(Counter counter) {
|
||||
DMAJNI.addCounter(m_dmaHandle, counter.m_counter);
|
||||
}
|
||||
|
||||
public void addCounterPeriod(Counter counter) {
|
||||
DMAJNI.addCounterPeriod(m_dmaHandle, counter.m_counter);
|
||||
}
|
||||
|
||||
public void addDigitalSource(DigitalSource digitalSource) {
|
||||
DMAJNI.addDigitalSource(m_dmaHandle, digitalSource.getPortHandleForRouting());
|
||||
}
|
||||
|
||||
public void addDutyCycle(DutyCycle dutyCycle) {
|
||||
DMAJNI.addDutyCycle(m_dmaHandle, dutyCycle.m_handle);
|
||||
}
|
||||
|
||||
public void addAnalogInput(AnalogInput analogInput) {
|
||||
DMAJNI.addAnalogInput(m_dmaHandle, analogInput.m_port);
|
||||
}
|
||||
|
||||
public void addAveragedAnalogInput(AnalogInput analogInput) {
|
||||
DMAJNI.addAveragedAnalogInput(m_dmaHandle, analogInput.m_port);
|
||||
}
|
||||
|
||||
public void addAnalogAccumulator(AnalogInput analogInput) {
|
||||
DMAJNI.addAnalogAccumulator(m_dmaHandle, analogInput.m_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an external DMA trigger.
|
||||
*
|
||||
* @param source the source to trigger from.
|
||||
* @param rising trigger on rising edge.
|
||||
* @param falling trigger on falling edge.
|
||||
* @return the index of the trigger
|
||||
*/
|
||||
public int setExternalTrigger(DigitalSource source, boolean rising, boolean falling) {
|
||||
return DMAJNI.setExternalTrigger(
|
||||
m_dmaHandle,
|
||||
source.getPortHandleForRouting(),
|
||||
source.getAnalogTriggerTypeForRouting(),
|
||||
rising,
|
||||
falling);
|
||||
}
|
||||
|
||||
public int setPwmEdgeTrigger(PWMMotorController pwm, boolean rising, boolean falling) {
|
||||
return DMAJNI.setExternalTrigger(m_dmaHandle, pwm.getPwmHandle(), 0, rising, falling);
|
||||
}
|
||||
|
||||
public int setPwmEdgeTrigger(PWM pwm, boolean rising, boolean falling) {
|
||||
return DMAJNI.setExternalTrigger(m_dmaHandle, pwm.getHandle(), 0, rising, falling);
|
||||
}
|
||||
|
||||
public void clearSensors() {
|
||||
DMAJNI.clearSensors(m_dmaHandle);
|
||||
}
|
||||
|
||||
public void clearExternalTriggers() {
|
||||
DMAJNI.clearExternalTriggers(m_dmaHandle);
|
||||
}
|
||||
|
||||
public void start(int queueDepth) {
|
||||
DMAJNI.startDMA(m_dmaHandle, queueDepth);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
DMAJNI.stopDMA(m_dmaHandle);
|
||||
}
|
||||
}
|
||||
126
wpilibj/src/main/java/edu/wpi/first/wpilibj/DMASample.java
Normal file
126
wpilibj/src/main/java/edu/wpi/first/wpilibj/DMASample.java
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj;
|
||||
|
||||
import edu.wpi.first.hal.AnalogJNI;
|
||||
import edu.wpi.first.hal.DMAJNISample;
|
||||
|
||||
public class DMASample {
|
||||
public enum DMAReadStatus {
|
||||
kOk(1),
|
||||
kTimeout(2),
|
||||
kError(3);
|
||||
|
||||
private final int value;
|
||||
|
||||
DMAReadStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DMAReadStatus from a raw value.
|
||||
*
|
||||
* @param value raw value
|
||||
* @return enum value
|
||||
*/
|
||||
public static DMAReadStatus getValue(int value) {
|
||||
if (value == 1) {
|
||||
return kOk;
|
||||
} else if (value == 2) {
|
||||
return kTimeout;
|
||||
}
|
||||
return kError;
|
||||
}
|
||||
}
|
||||
|
||||
private final DMAJNISample m_dmaSample = new DMAJNISample();
|
||||
|
||||
public DMAReadStatus update(DMA dma, double timeoutSeconds) {
|
||||
return DMAReadStatus.getValue(m_dmaSample.update(dma.m_dmaHandle, timeoutSeconds));
|
||||
}
|
||||
|
||||
public int getCaptureSize() {
|
||||
return m_dmaSample.getCaptureSize();
|
||||
}
|
||||
|
||||
public int getTriggerChannels() {
|
||||
return m_dmaSample.getTriggerChannels();
|
||||
}
|
||||
|
||||
public int getRemaining() {
|
||||
return m_dmaSample.getRemaining();
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return m_dmaSample.getTime();
|
||||
}
|
||||
|
||||
public double getTimeStamp() {
|
||||
return getTime() * 1.0e-6;
|
||||
}
|
||||
|
||||
public int getEncoderRaw(Encoder encoder) {
|
||||
return m_dmaSample.getEncoder(encoder.m_encoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scaled encoder distance for this sample.
|
||||
*
|
||||
* @param encoder the encoder to use to read
|
||||
* @return the distance
|
||||
*/
|
||||
public double getEncoderDistance(Encoder encoder) {
|
||||
double val = getEncoderRaw(encoder);
|
||||
val *= encoder.getDecodingScaleFactor();
|
||||
val *= encoder.getDistancePerPulse();
|
||||
return val;
|
||||
}
|
||||
|
||||
public int getEncoderPeriodRaw(Encoder encoder) {
|
||||
return m_dmaSample.getEncoderPeriod(encoder.m_encoder);
|
||||
}
|
||||
|
||||
public int getCounter(Counter counter) {
|
||||
return m_dmaSample.getCounter(counter.m_counter);
|
||||
}
|
||||
|
||||
public int getCounterPeriod(Counter counter) {
|
||||
return m_dmaSample.getCounterPeriod(counter.m_counter);
|
||||
}
|
||||
|
||||
public boolean getDigitalSource(DigitalSource digitalSource) {
|
||||
return m_dmaSample.getDigitalSource(digitalSource.getPortHandleForRouting());
|
||||
}
|
||||
|
||||
public int getAnalogInputRaw(AnalogInput analogInput) {
|
||||
return m_dmaSample.getAnalogInput(analogInput.m_port);
|
||||
}
|
||||
|
||||
public double getAnalogInputVoltage(AnalogInput analogInput) {
|
||||
return AnalogJNI.getAnalogValueToVolts(analogInput.m_port, getAnalogInputRaw(analogInput));
|
||||
}
|
||||
|
||||
public int getAveragedAnalogInputRaw(AnalogInput analogInput) {
|
||||
return m_dmaSample.getAnalogInputAveraged(analogInput.m_port);
|
||||
}
|
||||
|
||||
public double getAveragedAnalogInputVoltage(AnalogInput analogInput) {
|
||||
return AnalogJNI.getAnalogValueToVolts(
|
||||
analogInput.m_port, getAveragedAnalogInputRaw(analogInput));
|
||||
}
|
||||
|
||||
public int getDutyCycleOutputRaw(DutyCycle dutyCycle) {
|
||||
return m_dmaSample.getDutyCycleOutput(dutyCycle.m_handle);
|
||||
}
|
||||
|
||||
public double getDutyCycleOutput(DutyCycle dutyCycle) {
|
||||
return m_dmaSample.getDutyCycleOutput(dutyCycle.m_handle)
|
||||
/ (double) dutyCycle.getOutputScaleFactor();
|
||||
}
|
||||
}
|
||||
@@ -52,8 +52,9 @@ public class Encoder implements CounterBase, Sendable, AutoCloseable {
|
||||
private boolean m_allocatedA;
|
||||
private boolean m_allocatedB;
|
||||
private boolean m_allocatedI;
|
||||
private final EncodingType m_encodingType;
|
||||
|
||||
private int m_encoder; // the HAL encoder object
|
||||
int m_encoder; // the HAL encoder object
|
||||
|
||||
/**
|
||||
* Common initialization code for Encoders. This code allocates resources for Encoders and is
|
||||
@@ -131,6 +132,7 @@ public class Encoder implements CounterBase, Sendable, AutoCloseable {
|
||||
m_allocatedI = false;
|
||||
m_aSource = new DigitalInput(channelA);
|
||||
m_bSource = new DigitalInput(channelB);
|
||||
m_encodingType = encodingType;
|
||||
SendableRegistry.addChild(this, m_aSource);
|
||||
SendableRegistry.addChild(this, m_bSource);
|
||||
initEncoder(reverseDirection, encodingType);
|
||||
@@ -230,6 +232,7 @@ public class Encoder implements CounterBase, Sendable, AutoCloseable {
|
||||
m_allocatedA = false;
|
||||
m_allocatedB = false;
|
||||
m_allocatedI = false;
|
||||
m_encodingType = encodingType;
|
||||
m_aSource = sourceA;
|
||||
m_bSource = sourceB;
|
||||
initEncoder(reverseDirection, encodingType);
|
||||
@@ -540,6 +543,24 @@ public class Encoder implements CounterBase, Sendable, AutoCloseable {
|
||||
EncoderJNI.setEncoderSimDevice(m_encoder, device.getNativeHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the decoding scale factor for scaling raw values to full counts.
|
||||
*
|
||||
* @return decoding scale factor
|
||||
*/
|
||||
public double getDecodingScaleFactor() {
|
||||
switch (m_encodingType) {
|
||||
case k1X:
|
||||
return 1.0;
|
||||
case k2X:
|
||||
return 0.5;
|
||||
case k4X:
|
||||
return 0.25;
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSendable(SendableBuilder builder) {
|
||||
if (EncoderJNI.getEncoderEncodingType(m_encoder) == EncodingType.k4X.value) {
|
||||
|
||||
@@ -37,8 +37,7 @@ public class PWM implements Sendable, AutoCloseable {
|
||||
|
||||
private final int m_channel;
|
||||
|
||||
// Package private to use from AddressableLED
|
||||
int m_handle;
|
||||
private int m_handle;
|
||||
|
||||
/**
|
||||
* Allocate a PWM given a channel.
|
||||
@@ -246,6 +245,15 @@ public class PWM implements Sendable, AutoCloseable {
|
||||
PWMJNI.latchPWMZero(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying handle.
|
||||
*
|
||||
* @return Underlying PWM handle
|
||||
*/
|
||||
public int getHandle() {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSendable(SendableBuilder builder) {
|
||||
builder.setSmartDashboardType("PWM");
|
||||
|
||||
@@ -86,6 +86,15 @@ public abstract class PWMMotorController extends MotorSafety
|
||||
return "PWM " + getChannel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the backing PWM handle.
|
||||
*
|
||||
* @return The pwm handle.
|
||||
*/
|
||||
public int getPwmHandle() {
|
||||
return m_pwm.getHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PWM channel number.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user