mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
[hal] Add support for DMA to Java (#3158)
This commit is contained in:
@@ -58,6 +58,8 @@ public class AnalogJNI extends JNIWrapper {
|
||||
|
||||
public static native int getAnalogVoltsToValue(int analogPortHandle, double voltage);
|
||||
|
||||
public static native double getAnalogValueToVolts(int analogPortHandle, int value);
|
||||
|
||||
public static native double getAnalogVoltage(int analogPortHandle);
|
||||
|
||||
public static native double getAnalogAverageVoltage(int analogPortHandle);
|
||||
|
||||
57
hal/src/main/java/edu/wpi/first/hal/DMAJNI.java
Normal file
57
hal/src/main/java/edu/wpi/first/hal/DMAJNI.java
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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.hal;
|
||||
|
||||
@SuppressWarnings("AbbreviationAsWordInName")
|
||||
public class DMAJNI extends JNIWrapper {
|
||||
public static native int initialize();
|
||||
|
||||
public static native void free(int handle);
|
||||
|
||||
public static native void setPause(int handle, boolean pause);
|
||||
|
||||
public static native void setTimedTrigger(int handle, double periodSeconds);
|
||||
|
||||
public static native void setTimedTriggerCycles(int handle, int cycles);
|
||||
|
||||
public static native void addEncoder(int handle, int encoderHandle);
|
||||
|
||||
public static native void addEncoderPeriod(int handle, int encoderHandle);
|
||||
|
||||
public static native void addCounter(int handle, int counterHandle);
|
||||
|
||||
public static native void addCounterPeriod(int handle, int counterHandle);
|
||||
|
||||
public static native void addDigitalSource(int handle, int digitalSourceHandle);
|
||||
|
||||
public static native void addDutyCycle(int handle, int dutyCycleHandle);
|
||||
|
||||
public static native void addAnalogInput(int handle, int analogInputHandle);
|
||||
|
||||
public static native void addAveragedAnalogInput(int handle, int analogInputHandle);
|
||||
|
||||
public static native void addAnalogAccumulator(int handle, int analogInputHandle);
|
||||
|
||||
public static native int setExternalTrigger(
|
||||
int handle, int digitalSourceHandle, int analogTriggerType, boolean rising, boolean falling);
|
||||
|
||||
public static native void clearSensors(int handle);
|
||||
|
||||
public static native void clearExternalTriggers(int handle);
|
||||
|
||||
public static native void startDMA(int handle, int queueDepth);
|
||||
|
||||
public static native void stopDMA(int handle);
|
||||
|
||||
// 0-21 channelOffsets
|
||||
// 22: capture size
|
||||
// 23: triggerChannels (bitflags)
|
||||
// 24: remaining
|
||||
// 25: read status
|
||||
public static native long readDMA(
|
||||
int handle, double timeoutSeconds, int[] buffer, int[] sampleStore);
|
||||
|
||||
public static native DMAJNISample.BaseStore getSensorReadData(int handle);
|
||||
}
|
||||
169
hal/src/main/java/edu/wpi/first/hal/DMAJNISample.java
Normal file
169
hal/src/main/java/edu/wpi/first/hal/DMAJNISample.java
Normal file
@@ -0,0 +1,169 @@
|
||||
// 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.hal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("AbbreviationAsWordInName")
|
||||
public class DMAJNISample {
|
||||
private static final int kEnable_Accumulator0 = 8;
|
||||
private static final int kEnable_Accumulator1 = 9;
|
||||
|
||||
static class BaseStore {
|
||||
public final int m_valueType;
|
||||
public final int m_index;
|
||||
|
||||
BaseStore(int valueType, int index) {
|
||||
this.m_valueType = valueType;
|
||||
this.m_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
private final int[] m_dataBuffer = new int[100];
|
||||
private final int[] m_storage = new int[100];
|
||||
private long m_timeStamp;
|
||||
private Map<Integer, BaseStore> m_propertyMap = new HashMap<>();
|
||||
|
||||
public int update(int dmaHandle, double timeoutSeconds) {
|
||||
m_timeStamp = DMAJNI.readDMA(dmaHandle, timeoutSeconds, m_dataBuffer, m_storage);
|
||||
return m_storage[25];
|
||||
}
|
||||
|
||||
public int getCaptureSize() {
|
||||
return m_storage[22];
|
||||
}
|
||||
|
||||
public int getTriggerChannels() {
|
||||
return m_storage[23];
|
||||
}
|
||||
|
||||
public int getRemaining() {
|
||||
return m_storage[24];
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return m_timeStamp;
|
||||
}
|
||||
|
||||
private BaseStore addSensorInternal(int handle) {
|
||||
BaseStore sensorData = DMAJNI.getSensorReadData(handle);
|
||||
m_propertyMap.put(handle, sensorData);
|
||||
return sensorData;
|
||||
}
|
||||
|
||||
public void addSensor(int handle) {
|
||||
addSensorInternal(handle);
|
||||
}
|
||||
|
||||
private int readValue(int valueType, int index) {
|
||||
int offset = m_storage[valueType];
|
||||
if (offset == -1) {
|
||||
throw new RuntimeException("Resource not found in DMA capture");
|
||||
}
|
||||
return m_dataBuffer[offset + index];
|
||||
}
|
||||
|
||||
public int getEncoder(int encoderHandle) {
|
||||
BaseStore data = m_propertyMap.get(encoderHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(encoderHandle);
|
||||
}
|
||||
return readValue(data.m_valueType, data.m_index);
|
||||
}
|
||||
|
||||
public int getEncoderPeriod(int encoderHandle) {
|
||||
BaseStore data = m_propertyMap.get(encoderHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(encoderHandle);
|
||||
}
|
||||
// + 2 Hack, but needed to not have to call into JNI
|
||||
return readValue(data.m_valueType + 2, data.m_index);
|
||||
}
|
||||
|
||||
public int getCounter(int counterHandle) {
|
||||
BaseStore data = m_propertyMap.get(counterHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(counterHandle);
|
||||
}
|
||||
return readValue(data.m_valueType, data.m_index);
|
||||
}
|
||||
|
||||
public int getCounterPeriod(int counterHandle) {
|
||||
BaseStore data = m_propertyMap.get(counterHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(counterHandle);
|
||||
}
|
||||
// Hack, but needed to not have to call into JNI
|
||||
return readValue(data.m_valueType + 2, data.m_index);
|
||||
}
|
||||
|
||||
public boolean getDigitalSource(int digitalSourceHandle) {
|
||||
BaseStore data = m_propertyMap.get(digitalSourceHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(digitalSourceHandle);
|
||||
}
|
||||
|
||||
int value = readValue(data.m_valueType, 0);
|
||||
|
||||
return ((value >> data.m_index) & 0x1) != 0;
|
||||
}
|
||||
|
||||
public int getAnalogInput(int analogInputHandle) {
|
||||
BaseStore data = m_propertyMap.get(analogInputHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(analogInputHandle);
|
||||
}
|
||||
|
||||
int value = readValue(data.m_valueType, data.m_index / 2);
|
||||
if ((data.m_index % 2) != 0) {
|
||||
return (value >>> 16) & 0xFFFF;
|
||||
} else {
|
||||
return value & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
public int getAnalogInputAveraged(int analogInputHandle) {
|
||||
BaseStore data = m_propertyMap.get(analogInputHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(analogInputHandle);
|
||||
}
|
||||
|
||||
// + 2 Hack, but needed to not have to call into JNI
|
||||
int value = readValue(data.m_valueType + 2, data.m_index);
|
||||
return value;
|
||||
}
|
||||
|
||||
public void getAnalogAccumulator(int analogInputHandle, AccumulatorResult result) {
|
||||
BaseStore data = m_propertyMap.get(analogInputHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(analogInputHandle);
|
||||
}
|
||||
|
||||
if (data.m_index == 0) {
|
||||
int val0 = readValue(kEnable_Accumulator0, 0);
|
||||
int val1 = readValue(kEnable_Accumulator0, 1);
|
||||
int val2 = readValue(kEnable_Accumulator0, 2);
|
||||
result.count = val2;
|
||||
result.value = ((long) val1 << 32) | val0;
|
||||
} else if (data.m_index == 1) {
|
||||
int val0 = readValue(kEnable_Accumulator1, 0);
|
||||
int val1 = readValue(kEnable_Accumulator1, 1);
|
||||
int val2 = readValue(kEnable_Accumulator1, 2);
|
||||
result.count = val2;
|
||||
result.value = ((long) val1 << 32) | val0;
|
||||
} else {
|
||||
throw new RuntimeException("Resource not found in DMA capture");
|
||||
}
|
||||
}
|
||||
|
||||
public int getDutyCycleOutput(int dutyCycleHandle) {
|
||||
BaseStore data = m_propertyMap.get(dutyCycleHandle);
|
||||
if (data == null) {
|
||||
data = addSensorInternal(dutyCycleHandle);
|
||||
}
|
||||
return readValue(data.m_valueType, data.m_index);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user