artf4700: Added DigitalGlitchFilter

Initial Java support from Tyler Veness.
Final java support done by Jerry Morrison.

Change-Id: I1f85eb555f9ea4c0250c4c6729d7c51a76f5bef4
This commit is contained in:
Austin Schuh
2015-11-22 21:18:59 -08:00
committed by Peter Johnson
parent 6d00b77ef3
commit b3b03c43c8
19 changed files with 751 additions and 5 deletions

View File

@@ -46,6 +46,13 @@ extern "C"
bool isPulsing(void* digital_port_pointer, int32_t *status);
bool isAnyPulsing(int32_t *status);
void setFilterSelect(void* digital_port_pointer, int filter_index,
int32_t* status);
int getFilterSelect(void* digital_port_pointer, int32_t* status);
void setFilterPeriod(int filter_index, uint32_t value, int32_t* status);
uint32_t getFilterPeriod(int filter_index, int32_t* status);
void* initializeCounter(Mode mode, uint32_t *index, int32_t *status);
void freeCounter(void* counter_pointer, int32_t *status);
void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status);

View File

@@ -95,6 +95,7 @@ namespace HALUsageReporting
kResourceType_VictorSP,
kResourceType_TalonSRX,
kResourceType_CANTalonSRX,
kResourceType_DigitalGlitchFilter,
};
enum tInstances

View File

@@ -649,6 +649,97 @@ bool isAnyPulsing(int32_t *status) {
return pulseRegister.Headers != 0 && pulseRegister.MXP != 0;
}
/**
* Write the filter index from the FPGA.
* Set the filter index used to filter out short pulses.
*
* @param digital_port_pointer The digital I/O channel
* @param filter_index The filter index. Must be in the range 0 - 3,
* where 0 means "none" and 1 - 3 means filter # filter_index - 1.
*/
void setFilterSelect(void* digital_port_pointer, int filter_index,
int32_t* status) {
DigitalPort* port = (DigitalPort*)digital_port_pointer;
std::lock_guard<priority_recursive_mutex> sync(digitalDIOMutex);
if (port->port.pin < kNumHeaders) {
digitalSystem->writeFilterSelectHdr(port->port.pin, filter_index, status);
}
else {
digitalSystem->writeFilterSelectMXP(remapMXPChannel(port->port.pin),
filter_index, status);
}
}
/**
* Read the filter index from the FPGA.
* Get the filter index used to filter out short pulses.
*
* @param digital_port_pointer The digital I/O channel
* @return filter_index The filter index. Must be in the range 0 - 3,
* where 0 means "none" and 1 - 3 means filter # filter_index - 1.
*/
int getFilterSelect(void* digital_port_pointer, int32_t* status) {
DigitalPort* port = (DigitalPort*)digital_port_pointer;
std::lock_guard<priority_recursive_mutex> sync(digitalDIOMutex);
if (port->port.pin < kNumHeaders) {
return digitalSystem->readFilterSelectHdr(port->port.pin, status);
}
else {
return digitalSystem->readFilterSelectMXP(remapMXPChannel(port->port.pin),
status);
}
}
/**
* Set the filter period for the specified filter index.
*
* Set the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. That can be changed later.
*
* @param filter_index The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
void setFilterPeriod(int filter_index, uint32_t value, int32_t* status) {
std::lock_guard<priority_recursive_mutex> sync(digitalDIOMutex);
digitalSystem->writeFilterPeriodHdr(filter_index, value, status);
if (*status == 0) {
digitalSystem->writeFilterPeriodMXP(filter_index, value, status);
}
}
/**
* Get the filter period for the specified filter index.
*
* Get the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. Set status to NiFpga_Status_SoftwareFault if the
* filter values miss-match.
*
* @param filter_index The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
uint32_t getFilterPeriod(int filter_index, int32_t* status) {
uint32_t hdr_period = 0;
uint32_t mxp_period = 0;
{
std::lock_guard<priority_recursive_mutex> sync(digitalDIOMutex);
hdr_period = digitalSystem->readFilterPeriodHdr(filter_index, status);
if (*status == 0) {
mxp_period = digitalSystem->readFilterPeriodMXP(filter_index, status);
}
}
if (hdr_period != mxp_period) {
*status = NiFpga_Status_SoftwareFault;
return -1;
}
return hdr_period;
}
struct counter_t {
tCounter* counter;
uint32_t index;

View File

@@ -73,6 +73,7 @@ namespace nUsageReporting
kResourceType_VictorSP,
kResourceType_TalonSRX,
kResourceType_CANTalonSRX,
kResourceType_DigitalGlitchFilter,
} tResourceType;
typedef enum

View File

@@ -14,6 +14,8 @@
#include <memory>
class DigitalGlitchFilter;
/**
* Class for counting the number of ticks on a digital input channel.
* This is a general purpose class for counting repetitive events. It can return
@@ -119,4 +121,5 @@ class Counter : public SensorBase,
uint32_t m_index = 0; ///< The index of this counter.
std::shared_ptr<ITable> m_table;
friend class DigitalGlitchFilter;
};

View File

@@ -0,0 +1,50 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. 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 $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <array>
#include "HAL/cpp/priority_mutex.h"
#include "DigitalSource.h"
class Encoder;
class Counter;
/**
* Class to enable glitch filtering on a set of digital inputs.
* This class will manage adding and removing digital inputs from a FPGA glitch
* filter. The filter lets the user configure the time that an input must remain
* high or low before it is classified as high or low.
*/
class DigitalGlitchFilter : public SensorBase {
public:
DigitalGlitchFilter();
~DigitalGlitchFilter();
void Add(DigitalSource *input);
void Add(Encoder *input);
void Add(Counter *input);
void Remove(DigitalSource *input);
void Remove(Encoder *input);
void Remove(Counter *input);
void SetPeriodCycles(uint32_t fpga_cycles);
void SetPeriodNanoSeconds(uint64_t nanoseconds);
uint32_t GetPeriodCycles();
uint64_t GetPeriodNanoSeconds();
private:
// Sets the filter for the input to be the requested index. A value of 0
// disables the filter, and the filter value must be between 1 and 3,
// inclusive.
void DoAdd(DigitalSource *input, int requested_index);
int m_channelIndex = -1;
static priority_mutex m_mutex;
static ::std::array<bool, 3> m_filterAllocated;
};

View File

@@ -12,6 +12,8 @@
#include <memory>
#include <cstdint>
class DigitalGlitchFilter;
/**
* Class to read a digital input.
* This class will read digital inputs and return the current value on the
@@ -45,4 +47,5 @@ class DigitalInput : public DigitalSource, public LiveWindowSendable {
uint32_t m_channel;
std::shared_ptr<ITable> m_table;
friend class DigitalGlitchFilter;
};

View File

@@ -16,6 +16,7 @@
#include <memory>
class DigitalSource;
class DigitalGlitchFilter;
/**
* Class to read quad encoders.
@@ -116,4 +117,5 @@ class Encoder : public SensorBase,
int32_t m_encodingScale; // 1x, 2x, or 4x, per the encodingType
std::shared_ptr<ITable> m_table;
friend class DigitalGlitchFilter;
};

View File

@@ -68,6 +68,7 @@ typedef enum {
kResourceType_VictorSP,
kResourceType_TalonSRX,
kResourceType_CANTalonSRX,
kResourceType_DigitalGlitchFilter,
} tResourceType;
typedef enum {

View File

@@ -0,0 +1,198 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. 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 $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#include <algorithm>
#include <array>
#include "DigitalGlitchFilter.h"
#include "Resource.h"
#include "WPIErrors.h"
#include "Encoder.h"
#include "Counter.h"
#include "Utility.h"
std::array<bool, 3> DigitalGlitchFilter::m_filterAllocated = {{false, false,
false}};
priority_mutex DigitalGlitchFilter::m_mutex;
DigitalGlitchFilter::DigitalGlitchFilter() {
std::lock_guard<priority_mutex> sync(m_mutex);
auto index =
std::find(m_filterAllocated.begin(), m_filterAllocated.end(), false);
wpi_assert(index != m_filterAllocated.end());
m_channelIndex = std::distance(m_filterAllocated.begin(), index);
*index = true;
}
DigitalGlitchFilter::~DigitalGlitchFilter() {
if (m_channelIndex >= 0) {
std::lock_guard<priority_mutex> sync(m_mutex);
m_filterAllocated[m_channelIndex] = false;
}
}
/**
* Assigns the DigitalSource to this glitch filter.
*
* @param input The DigitalSource to add.
*/
void DigitalGlitchFilter::Add(DigitalSource *input) {
DoAdd(input, m_channelIndex + 1);
}
void DigitalGlitchFilter::DoAdd(DigitalSource *input, int requested_index) {
// Some sources from Counters and Encoders are null. By pushing the check
// here, we catch the issue more generally.
if (input) {
int32_t status = 0;
setFilterSelect(m_digital_ports[input->GetChannelForRouting()],
requested_index, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
// Validate that we set it correctly.
int actual_index = getFilterSelect(
m_digital_ports[input->GetChannelForRouting()], &status);
wpi_assertEqual(actual_index, requested_index);
HALReport(HALUsageReporting::kResourceType_DigitalInput,
input->GetChannelForRouting());
}
}
/**
* Assigns the Encoder to this glitch filter.
*
* @param input The Encoder to add.
*/
void DigitalGlitchFilter::Add(Encoder *input) {
Add(input->m_aSource.get());
if (StatusIsFatal()) {
return;
}
Add(input->m_bSource.get());
}
/**
* Assigns the Counter to this glitch filter.
*
* @param input The Counter to add.
*/
void DigitalGlitchFilter::Add(Counter *input) {
Add(input->m_upSource.get());
if (StatusIsFatal()) {
return;
}
Add(input->m_downSource.get());
}
/**
* Removes a digital input from this filter.
*
* Removes the DigitalSource from this glitch filter and re-assigns it to
* the default filter.
*
* @param input The DigitalSource to remove.
*/
void DigitalGlitchFilter::Remove(DigitalSource *input) {
DoAdd(input, 0);
}
/**
* Removes an encoder from this filter.
*
* Removes the Encoder from this glitch filter and re-assigns it to
* the default filter.
*
* @param input The Encoder to remove.
*/
void DigitalGlitchFilter::Remove(Encoder *input) {
Remove(input->m_aSource.get());
if (StatusIsFatal()) {
return;
}
Remove(input->m_bSource.get());
}
/**
* Removes a counter from this filter.
*
* Removes the Counter from this glitch filter and re-assigns it to
* the default filter.
*
* @param input The Counter to remove.
*/
void DigitalGlitchFilter::Remove(Counter *input) {
Remove(input->m_upSource.get());
if (StatusIsFatal()) {
return;
}
Remove(input->m_downSource.get());
}
/**
* Sets the number of cycles that the input must not change state for.
*
* @param fpga_cycles The number of FPGA cycles.
*/
void DigitalGlitchFilter::SetPeriodCycles(uint32_t fpga_cycles) {
int32_t status = 0;
setFilterPeriod(m_channelIndex, fpga_cycles, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
HALReport(HALUsageReporting::kResourceType_DigitalGlitchFilter,
m_channelIndex);
}
/**
* Sets the number of nanoseconds that the input must not change state for.
*
* @param nanoseconds The number of nanoseconds.
*/
void DigitalGlitchFilter::SetPeriodNanoSeconds(uint64_t nanoseconds) {
int32_t status = 0;
uint32_t fpga_cycles =
nanoseconds * kSystemClockTicksPerMicrosecond / 4 / 1000;
setFilterPeriod(m_channelIndex, fpga_cycles, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
HALReport(HALUsageReporting::kResourceType_DigitalGlitchFilter,
m_channelIndex);
}
/**
* Gets the number of cycles that the input must not change state for.
*
* @return The number of cycles.
*/
uint32_t DigitalGlitchFilter::GetPeriodCycles() {
int32_t status = 0;
uint32_t fpga_cycles = getFilterPeriod(m_channelIndex, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
HALReport(HALUsageReporting::kResourceType_DigitalGlitchFilter,
m_channelIndex);
return fpga_cycles;
}
/**
* Gets the number of nanoseconds that the input must not change state for.
*
* @return The number of nanoseconds.
*/
uint64_t DigitalGlitchFilter::GetPeriodNanoSeconds() {
int32_t status = 0;
uint32_t fpga_cycles = getFilterPeriod(m_channelIndex, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
HALReport(HALUsageReporting::kResourceType_DigitalGlitchFilter,
m_channelIndex);
return static_cast<uint64_t>(fpga_cycles) * 1000L /
static_cast<uint64_t>(kSystemClockTicksPerMicrosecond / 4);
}

View File

@@ -0,0 +1,60 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. 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. */
/*----------------------------------------------------------------------------*/
#include <Counter.h>
#include <DigitalInput.h>
#include <Encoder.h>
#include <DigitalGlitchFilter.h>
#include "gtest/gtest.h"
/**
* Tests that configuring inputs to be filtered succeeds.
*
* This test actually tests everything except that the actual FPGA
* implementation works as intended. We configure the FPGA and then query it to
* make sure that the acutal configuration matches.
*/
TEST(DigitalGlitchFilterTest, BasicTest) {
DigitalInput input1(1);
DigitalInput input2(2);
DigitalInput input3(3);
DigitalInput input4(4);
Encoder encoder5(5, 6);
Counter counter7(7);
// Check that we can make a single filter and set the period.
DigitalGlitchFilter filter1;
filter1.Add(&input1);
filter1.SetPeriodNanoSeconds(4200);
// Check that we can make a second filter with 2 inputs.
DigitalGlitchFilter filter2;
filter2.Add(&input2);
filter2.Add(&input3);
filter2.SetPeriodNanoSeconds(97100);
// Check that we can make a third filter with an input, an encoder, and a
// counter.
DigitalGlitchFilter filter3;
filter3.Add(&input4);
filter3.Add(&encoder5);
filter3.Add(&counter7);
filter3.SetPeriodNanoSeconds(167800);
// Verify that the period was properly set for all 3 filters.
EXPECT_EQ(4200u, filter1.GetPeriodNanoSeconds());
EXPECT_EQ(97100u, filter2.GetPeriodNanoSeconds());
EXPECT_EQ(167800u, filter3.GetPeriodNanoSeconds());
// Clean up.
filter1.Remove(&input1);
filter2.Remove(&input2);
filter2.Remove(&input3);
filter3.Remove(&input4);
filter3.Remove(&encoder5);
filter3.Remove(&counter7);
}

View File

@@ -142,6 +142,7 @@ task jniHeaders {
args 'edu.wpi.first.wpilibj.hal.AccelerometerJNI'
args 'edu.wpi.first.wpilibj.hal.AnalogJNI'
args 'edu.wpi.first.wpilibj.hal.CounterJNI'
args 'edu.wpi.first.wpilibj.hal.DigitalGlitchFilterJNI'
args 'edu.wpi.first.wpilibj.hal.DIOJNI'
args 'edu.wpi.first.wpilibj.hal.EncoderJNI'
args 'edu.wpi.first.wpilibj.hal.I2CJNI'
@@ -161,4 +162,4 @@ task jniHeaders {
clean {
delete generatedJNIHeaderLoc
}
}

View File

@@ -0,0 +1,61 @@
#include <jni.h>
#include "HAL/HAL.hpp"
#include "HALUtil.h"
#include "edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI.h"
/*
* Class: edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI
* Method: setFilterSelect
*/
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI_setFilterSelect
(JNIEnv* env, jclass, jlong port_pointer, jint filter_index)
{
int32_t status = 0;
void* digital_port_pointer = reinterpret_cast<void*>(port_pointer);
setFilterSelect(digital_port_pointer, filter_index, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI
* Method: getFilterSelect
*/
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI_getFilterSelect
(JNIEnv *env, jclass, jlong port_pointer)
{
int32_t status = 0;
void* digital_port_pointer = reinterpret_cast<void*>(port_pointer);
jint result = getFilterSelect(digital_port_pointer, &status);
CheckStatus(env, status);
return result;
}
/*
* Class: edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI
* Method: setFilterPeriod
*/
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI_setFilterPeriod
(JNIEnv *env, jclass, jint filter_index, jint fpga_cycles)
{
int32_t status = 0;
setFilterPeriod(filter_index, fpga_cycles, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI
* Method: getFilterPeriod
*/
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI_getFilterPeriod
(JNIEnv *env, jclass, jint filter_index)
{
int32_t status = 0;
jint result = getFilterPeriod(filter_index, &status);
CheckStatus(env, status);
return result;
}

View File

@@ -60,8 +60,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
}
private DigitalSource m_upSource; // /< What makes the counter count up.
private DigitalSource m_downSource; // /< What makes the counter count down.
protected DigitalSource m_upSource; // /< What makes the counter count up.
protected DigitalSource m_downSource; // /< What makes the counter count down.
private boolean m_allocatedUpSource;
private boolean m_allocatedDownSource;
private long m_counter; // /< The FPGA counter object.

View File

@@ -0,0 +1,164 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. 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 $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.wpilibj.DigitalSource;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Counter;
import edu.wpi.first.wpilibj.hal.DigitalGlitchFilterJNI;
/**
* Class to enable glitch filtering on a set of digital inputs.
* This class will manage adding and removing digital inputs from a FPGA glitch
* filter. The filter lets the user configure the time that an input must remain
* high or low before it is classified as high or low.
*/
public class DigitalGlitchFilter extends SensorBase {
public DigitalGlitchFilter() {
synchronized(m_mutex) {
int i = 0;
while (m_filterAllocated[i] != false && i < m_filterAllocated.length) {
i++;
}
if (i != m_filterAllocated.length) {
m_channelIndex = i;
m_filterAllocated[i] = true;
}
}
}
public void free() {
if (m_channelIndex >= 0) {
synchronized(m_mutex) {
m_filterAllocated[m_channelIndex] = false;
}
}
}
private static void setFilter(DigitalSource input, int channelIndex) {
if (input != null) { // Counter might have just one input
DigitalGlitchFilterJNI.setFilterSelect(input.m_port, channelIndex);
int selected = DigitalGlitchFilterJNI.getFilterSelect(input.m_port);
if (selected != channelIndex) {
throw new IllegalStateException("DigitalGlitchFilterJNI.setFilterSelect("
+ channelIndex + ") failed -> " + selected);
}
}
}
/**
* Assigns the DigitalSource to this glitch filter.
*
* @param input The DigitalSource to add.
*/
public void add(DigitalSource input) {
setFilter(input, m_channelIndex + 1);
}
/**
* Assigns the Encoder to this glitch filter.
*
* @param input The Encoder to add.
*/
public void add(Encoder input) {
add(input.m_aSource);
add(input.m_bSource);
}
/**
* Assigns the Counter to this glitch filter.
*
* @param input The Counter to add.
*/
public void add(Counter input) {
add(input.m_upSource);
add(input.m_downSource);
}
/**
* Removes this filter from the given digital input.
*
* @param input The DigitalSource to stop filtering.
*/
public void remove(DigitalSource input) {
setFilter(input, 0);
}
/**
* Removes this filter from the given Encoder.
*
* @param input the Encoder to stop filtering.
*/
public void remove(Encoder input) {
remove(input.m_aSource);
remove(input.m_bSource);
}
/**
* Removes this filter from the given Counter.
*
* @param input The Counter to stop filtering.
*/
public void remove(Counter input) {
remove(input.m_upSource);
remove(input.m_downSource);
}
/**
* Sets the number of FPGA cycles that the input must hold steady to pass
* through this glitch filter.
*
* @param fpga_cycles The number of FPGA cycles.
*/
public void setPeriodCycles(int fpga_cycles) {
DigitalGlitchFilterJNI.setFilterPeriod(m_channelIndex, fpga_cycles);
}
/**
* Sets the number of nanoseconds that the input must hold steady to pass
* through this glitch filter.
*
* @param nanoseconds The number of nanoseconds.
*/
public void setPeriodNanoSeconds(long nanoseconds) {
int fpga_cycles = (int) (nanoseconds * kSystemClockTicksPerMicrosecond / 4 /
1000);
setPeriodCycles(fpga_cycles);
}
/**
* Gets the number of FPGA cycles that the input must hold steady to pass
* through this glitch filter.
*
* @return The number of cycles.
*/
public int getPeriodCycles() {
return DigitalGlitchFilterJNI.getFilterPeriod(m_channelIndex);
}
/**
* Gets the number of nanoseconds that the input must hold steady to pass
* through this glitch filter.
*
* @return The number of nanoseconds.
*/
public long getPeriodNanoSeconds() {
int fpga_cycles = getPeriodCycles();
return (long) fpga_cycles * 1000L /
(long) (kSystemClockTicksPerMicrosecond / 4);
}
private int m_channelIndex = -1;
private static final Lock m_mutex = new ReentrantLock(true);
private static final boolean[] m_filterAllocated = new boolean[3];
};

View File

@@ -379,6 +379,11 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
* src\main\include\NetworkCommunication\UsageReporting.h:62</i>
*/
public static final int kResourceType_CANTalonSRX = 52;
/**
* <i>native declaration :
* src\main\include\NetworkCommunication\UsageReporting.h:63</i>
*/
public static final int kResourceType_DigitalGlitchFilter = 53;
};
/**
* <i>native declaration :

View File

@@ -0,0 +1,8 @@
package edu.wpi.first.wpilibj.hal;
public class DigitalGlitchFilterJNI extends JNIWrapper {
public static native void setFilterSelect(long digital_port_pointer, int filter_index);
public static native int getFilterSelect(long digital_port_pointer);
public static native void setFilterPeriod(int filter_index, int fpga_cycles);
public static native int getFilterPeriod(int filter_index);
}

View File

@@ -0,0 +1,89 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2015. 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 static org.junit.Assert.assertEquals;
import java.util.logging.Logger;
import org.junit.Test;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
import edu.wpi.first.wpilibj.DigitalInput;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Counter;
import edu.wpi.first.wpilibj.DigitalGlitchFilter;
/**
* Test for the DigitalGlitchFilter class.
*
* @author Austin Schuh and Jerry Morrison
*/
public class DigitalGlitchFilterTest extends AbstractComsSetup {
private static final Logger logger = Logger.getLogger(
DigitalGlitchFilterTest.class.getName());
protected Logger getClassLogger() {
return logger;
}
/**
* This is a test to make sure that filters can be created and are consistent.
* This assumes that the FPGA implementation to actually implement the filter
* has been tested. It does validate that we are successfully able to set and
* get the active filters for ports and makes sure that the FPGA filter is
* changed correctly, and does the same for the period.
*/
@Test
public void testDigitalGlitchFilterBasic() {
DigitalInput input1 = new DigitalInput(1);
DigitalInput input2 = new DigitalInput(2);
DigitalInput input3 = new DigitalInput(3);
DigitalInput input4 = new DigitalInput(4);
Encoder encoder5 = new Encoder(5, 6);
Counter counter7 = new Counter(7);
DigitalGlitchFilter filter1 = new DigitalGlitchFilter();
filter1.add(input1);
filter1.setPeriodNanoSeconds(4200);
DigitalGlitchFilter filter2 = new DigitalGlitchFilter();
filter2.add(input2);
filter2.add(input3);
filter2.setPeriodNanoSeconds(97100);
DigitalGlitchFilter filter3 = new DigitalGlitchFilter();
filter3.add(input4);
filter3.add(encoder5);
filter3.add(counter7);
filter3.setPeriodNanoSeconds(167800);
assertEquals(4200, filter1.getPeriodNanoSeconds());
assertEquals(97100, filter2.getPeriodNanoSeconds());
assertEquals(167800, filter3.getPeriodNanoSeconds());
filter1.remove(input1);
filter2.remove(input2);
filter2.remove(input3);
filter3.remove(input4);
filter3.remove(encoder5);
filter3.remove(counter7);
input1.free();
input2.free();
input3.free();
input4.free();
encoder5.free();
counter7.free();
filter1.free();
filter2.free();
filter3.free();
}
}

View File

@@ -20,8 +20,9 @@ import edu.wpi.first.wpilibj.test.AbstractTestSuite;
@RunWith(Suite.class)
@SuiteClasses({AnalogCrossConnectTest.class, AnalogPotentiometerTest.class,
BuiltInAccelerometerTest.class, CANTalonTest.class, CounterTest.class,
DIOCrossConnectTest.class, EncoderTest.class, GyroTest.class, MotorEncoderTest.class,
MotorInvertingTest.class, PCMTest.class, PDPTest.class, PIDTest.class, PreferencesTest.class,
DigitalGlitchFilterTest.class, DIOCrossConnectTest.class, EncoderTest.class,
GyroTest.class, MotorEncoderTest.class, MotorInvertingTest.class,
PCMTest.class, PDPTest.class, PIDTest.class, PreferencesTest.class,
RelayCrossConnectTest.class, SampleTest.class, TimerTest.class})
public class WpiLibJTestSuite extends AbstractTestSuite {
}