diff --git a/hal/include/HAL/Analog.hpp b/hal/include/HAL/Analog.hpp index 17523683aa..2aa5e43ede 100644 --- a/hal/include/HAL/Analog.hpp +++ b/hal/include/HAL/Analog.hpp @@ -14,12 +14,14 @@ extern "C" { // Analog output functions void* initializeAnalogOutputPort(void* port_pointer, int32_t *status); + void freeAnalogOutputPort(void* analog_port_pointer); void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status); double getAnalogOutput(void* analog_port_pointer, int32_t *status); bool checkAnalogOutputChannel(uint32_t pin); // Analog input functions void* initializeAnalogInputPort(void* port_pointer, int32_t *status); + void freeAnalogInputPort(void* analog_port_pointer); bool checkAnalogModule(uint8_t module); bool checkAnalogInputChannel(uint32_t pin); diff --git a/hal/include/HAL/Digital.hpp b/hal/include/HAL/Digital.hpp index 2ef512df80..25eb91be2a 100644 --- a/hal/include/HAL/Digital.hpp +++ b/hal/include/HAL/Digital.hpp @@ -16,6 +16,7 @@ priority_recursive_mutex& spiGetSemaphore(uint8_t port); extern "C" { void* initializeDigitalPort(void* port_pointer, int32_t *status); + void freeDigitalPort(void* digital_port_pointer); bool checkPWMChannel(void* digital_port_pointer); bool checkRelayChannel(void* digital_port_pointer); diff --git a/hal/include/HAL/HAL.hpp b/hal/include/HAL/HAL.hpp index df87d96d93..3ef56504ff 100644 --- a/hal/include/HAL/HAL.hpp +++ b/hal/include/HAL/HAL.hpp @@ -211,6 +211,7 @@ extern "C" void* getPort(uint8_t pin); void* getPortWithModule(uint8_t module, uint8_t pin); + void freePort(void* port); const char* getHALErrorMessage(int32_t code); uint16_t getFPGAVersion(int32_t *status); diff --git a/hal/include/HAL/Solenoid.hpp b/hal/include/HAL/Solenoid.hpp index df06a33b77..f5bb9cf69c 100644 --- a/hal/include/HAL/Solenoid.hpp +++ b/hal/include/HAL/Solenoid.hpp @@ -5,6 +5,7 @@ extern "C" { void* initializeSolenoidPort(void* port_pointer, int32_t *status); + void freeSolenoidPort(void* solenoid_port_pointer); bool checkSolenoidModule(uint8_t module); bool getSolenoid(void* solenoid_port_pointer, int32_t *status); diff --git a/hal/lib/Athena/Analog.cpp b/hal/lib/Athena/Analog.cpp index 9c644f91c3..5a45178736 100644 --- a/hal/lib/Athena/Analog.cpp +++ b/hal/lib/Athena/Analog.cpp @@ -71,6 +71,13 @@ void* initializeAnalogInputPort(void* port_pointer, int32_t *status) { return analog_port; } +void freeAnalogInputPort(void* analog_port_pointer) { + AnalogPort* port = (AnalogPort*) analog_port_pointer; + if (!port) return; + delete port->accumulator; + delete port; +} + /** * Initialize the analog output port using the given port object. */ @@ -81,9 +88,17 @@ void* initializeAnalogOutputPort(void* port_pointer, int32_t *status) { // Initialize port structure AnalogPort* analog_port = new AnalogPort(); analog_port->port = *port; + analog_port->accumulator = NULL; return analog_port; } +void freeAnalogOutputPort(void* analog_port_pointer) { + AnalogPort* port = (AnalogPort*) analog_port_pointer; + if (!port) return; + delete port->accumulator; + delete port; +} + /** * Check that the analog module number is valid. @@ -594,8 +609,10 @@ void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *stat void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status) { AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer; + if (!trigger) return; triggers->Free(trigger->index); delete trigger->trigger; + freeAnalogInputPort(trigger->port); delete trigger; } diff --git a/hal/lib/Athena/Digital.cpp b/hal/lib/Athena/Digital.cpp index add1202a3f..801a6a3287 100644 --- a/hal/lib/Athena/Digital.cpp +++ b/hal/lib/Athena/Digital.cpp @@ -150,6 +150,11 @@ void* initializeDigitalPort(void* port_pointer, int32_t *status) { return digital_port; } +void freeDigitalPort(void* digital_port_pointer) { + DigitalPort* port = (DigitalPort*) digital_port_pointer; + delete port; +} + bool checkPWMChannel(void* digital_port_pointer) { DigitalPort* port = (DigitalPort*) digital_port_pointer; return port->port.pin < kPwmPins; @@ -487,6 +492,7 @@ bool allocatePWMChannel(void* digital_port_pointer, int32_t *status) { void freePWMChannel(void* digital_port_pointer, int32_t *status) { DigitalPort* port = (DigitalPort*) digital_port_pointer; + if (!port) return; if (!verifyPWMChannel(port, status)) { return; } PWMChannels->Free(port->port.pin); @@ -505,6 +511,7 @@ void freePWMChannel(void* digital_port_pointer, int32_t *status) { */ void freeDIO(void* digital_port_pointer, int32_t *status) { DigitalPort* port = (DigitalPort*) digital_port_pointer; + if (!port) return; DIOChannels->Free(port->port.pin); } @@ -666,13 +673,10 @@ void* initializeCounter(Mode mode, uint32_t *index, int32_t *status) { } void freeCounter(void* counter_pointer, int32_t *status) { - if (counter_pointer != NULL) { - Counter* counter = (Counter*) counter_pointer; - delete counter->counter; - counters->Free(counter->index); - } else { - *status = NULL_PARAMETER; - } + Counter* counter = (Counter*) counter_pointer; + if (!counter) return; + delete counter->counter; + counters->Free(counter->index); } void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status) { @@ -1004,6 +1008,7 @@ void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin, bool port_a_ void freeEncoder(void* encoder_pointer, int32_t *status) { Encoder* encoder = (Encoder*) encoder_pointer; + if (!encoder) return; quadEncoders->Free(encoder->index); delete encoder->encoder; } diff --git a/hal/lib/Athena/HALAthena.cpp b/hal/lib/Athena/HALAthena.cpp index e6463fbf83..378cb3db8e 100644 --- a/hal/lib/Athena/HALAthena.cpp +++ b/hal/lib/Athena/HALAthena.cpp @@ -41,6 +41,12 @@ void* getPortWithModule(uint8_t module, uint8_t pin) return port; } +void freePort(void* port_pointer) +{ + Port* port = (Port*) port_pointer; + delete port; +} + const char* getHALErrorMessage(int32_t code) { switch(code) { diff --git a/hal/lib/Athena/Solenoid.cpp b/hal/lib/Athena/Solenoid.cpp index 876045024b..49be9b1e09 100644 --- a/hal/lib/Athena/Solenoid.cpp +++ b/hal/lib/Athena/Solenoid.cpp @@ -33,6 +33,11 @@ void* initializeSolenoidPort(void *port_pointer, int32_t *status) { return solenoid_port; } +void freeSolenoidPort(void* solenoid_port_pointer) { + solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer; + delete port; +} + bool checkSolenoidModule(uint8_t module) { return module < NUM_MODULE_NUMBERS; } diff --git a/wpilibc/Athena/src/AnalogInput.cpp b/wpilibc/Athena/src/AnalogInput.cpp index 34d5564f09..540c84ef5b 100644 --- a/wpilibc/Athena/src/AnalogInput.cpp +++ b/wpilibc/Athena/src/AnalogInput.cpp @@ -55,7 +55,10 @@ AnalogInput::AnalogInput(uint32_t channel) { /** * Channel destructor. */ -AnalogInput::~AnalogInput() { inputs->Free(m_channel); } +AnalogInput::~AnalogInput() { + freeAnalogInputPort(m_port); + inputs->Free(m_channel); +} /** * Get a sample straight from this channel. diff --git a/wpilibc/Athena/src/AnalogOutput.cpp b/wpilibc/Athena/src/AnalogOutput.cpp index 6b8b0c04d9..4905e824a0 100644 --- a/wpilibc/Athena/src/AnalogOutput.cpp +++ b/wpilibc/Athena/src/AnalogOutput.cpp @@ -50,7 +50,10 @@ AnalogOutput::AnalogOutput(uint32_t channel) { /** * Destructor. Frees analog output resource */ -AnalogOutput::~AnalogOutput() { outputs->Free(m_channel); } +AnalogOutput::~AnalogOutput() { + freeAnalogOutputPort(m_port); + outputs->Free(m_channel); +} /** * Set the value of the analog output diff --git a/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp b/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp index 04bc6367dd..8a20b7f95e 100644 --- a/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp @@ -33,6 +33,18 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_initializeAnalo return (jlong)analog; } +/* + * Class: edu_wpi_first_wpilibj_hal_AnalogJNI + * Method: freeAnalogInputPort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_freeAnalogInputPort + (JNIEnv * env, jclass, jlong id) +{ + ANALOGJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeAnalogInputPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_AnalogJNI * Method: initializeAnalogOutputPort @@ -50,6 +62,18 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_initializeAnalo return (jlong)analog; } +/* + * Class: edu_wpi_first_wpilibj_hal_AnalogJNI + * Method: freeAnalogOutputPort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_freeAnalogOutputPort + (JNIEnv * env, jclass, jlong id) +{ + ANALOGJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeAnalogOutputPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_AnalogJNI * Method: checkAnalogModule diff --git a/wpilibj/src/athena/cpp/lib/DIOJNI.cpp b/wpilibj/src/athena/cpp/lib/DIOJNI.cpp index a79b5a85a7..ff06f36d34 100644 --- a/wpilibj/src/athena/cpp/lib/DIOJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/DIOJNI.cpp @@ -34,6 +34,19 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_initializeDigitalP return (jlong)dio; } +/* +* Class: edu_wpi_first_wpilibj_hal_DIOJNI +* Method: freeDigitalPort +* Signature: (J)V; +*/ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_freeDigitalPort +(JNIEnv * env, jclass, jlong id) +{ + DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDigitalPort"; + DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeDigitalPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_DIOJNI * Method: allocateDIO diff --git a/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp b/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp index f8d0e95e61..fb9dd4465f 100644 --- a/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp +++ b/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp @@ -40,4 +40,19 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_JNIWrapper_getPort return (jlong)port; } +/* + * Class: edu_wpi_first_wpilibj_hal_JNIWrapper + * Method: freePort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_JNIWrapper_freePort + (JNIEnv * env, jclass, jlong id) +{ + //FILE_LOG(logDEBUG) << "Calling JNIWrapper getPortWithModlue"; + //FILE_LOG(logDEBUG) << "Module = " << (jint)module; + //FILE_LOG(logDEBUG) << "Pin = " << (jint)pin; + freePort((void*)id); + //FILE_LOG(logDEBUG) << "Port Ptr = " << port; +} + } // extern "C" diff --git a/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp b/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp index 861a3ce5b1..d2b03bea1d 100644 --- a/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp @@ -41,6 +41,20 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_SolenoidJNI_initializeSol return (jlong)solenoid_port_pointer; } +/* + * Class: edu_wpi_first_wpilibj_hal_SolenoidJNI + * Method: freeSolenoidPort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_SolenoidJNI_freeSolenoidPort + (JNIEnv *env, jclass, jlong id) +{ + SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort"; + + SOLENOIDJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeSolenoidPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_SolenoidJNI * Method: getPortWithModule diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java index a2873f4007..008790d186 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java @@ -77,6 +77,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend * Channel destructor. */ public void free() { + AnalogJNI.freeAnalogInputPort(m_port); + m_port = 0; channels.free(m_channel); m_channel = 0; m_accumulatorOffset = 0; diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java index 5a66357885..f04c10fa94 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java @@ -52,6 +52,8 @@ public class AnalogOutput extends SensorBase implements LiveWindowSendable { * Channel destructor. */ public void free() { + AnalogJNI.freeAnalogOutputPort(m_port); + m_port = 0; channels.free(m_channel); m_channel = 0; } diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java index 160486fdd9..e5a98bb3e3 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java @@ -47,6 +47,8 @@ public abstract class DigitalSource extends InterruptableSensorBase { public void free() { channels.free(m_channel); DIOJNI.freeDIO(m_port); + DIOJNI.freeDigitalPort(m_port); + m_port = 0; m_channel = 0; } diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java index c5045e7523..9d9cc49bc2 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java @@ -100,6 +100,7 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable { public synchronized void free() { m_allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel); m_allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel); + super.free(); } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java index 899e633130..24d933b86d 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java @@ -140,9 +140,12 @@ public class PWM extends SensorBase implements LiveWindowSendable { * Free the resource associated with the PWM channel and set the value to 0. */ public void free() { + if (m_port == 0) return; PWMJNI.setPWM(m_port, (short) 0); PWMJNI.freePWMChannel(m_port); PWMJNI.freeDIO(m_port); + DIOJNI.freeDigitalPort(m_port); + m_port = 0; } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java index 8284bf49c4..d8084125d0 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java @@ -178,6 +178,8 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable RelayJNI.setRelayReverse(m_port, false); DIOJNI.freeDIO(m_port); + DIOJNI.freeDigitalPort(m_port); + m_port = 0; } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java index 10533eadd1..a3610da940 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java @@ -77,6 +77,9 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable { */ public synchronized void free() { m_allocated.free(m_moduleNumber * kSolenoidChannels + m_channel); + SolenoidJNI.freeSolenoidPort(m_solenoid_port); + m_solenoid_port = 0; + super.free(); } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java index 53168a9d15..b4129552dc 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java @@ -34,6 +34,17 @@ public abstract class SolenoidBase extends SensorBase { } } + /** + * Free the resources associated with by the solenoid base. + */ + @Override + public void free() { + for (int i = 0; i < m_ports.length; i++) { + SolenoidJNI.freeSolenoidPort(m_ports[i]); + m_ports[i] = 0; + } + } + /** * Set the value of a solenoid. * diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java index a90e592494..d8bec8bf45 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java @@ -34,8 +34,12 @@ public class AnalogJNI extends JNIWrapper { public static native long initializeAnalogInputPort(long port_pointer); + public static native void freeAnalogInputPort(long port_pointer); + public static native long initializeAnalogOutputPort(long port_pointer); + public static native void freeAnalogOutputPort(long port_pointer); + public static native boolean checkAnalogModule(byte module); public static native boolean checkAnalogInputChannel(int pin); diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java index d6ac993676..4ebeb25a6f 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java @@ -3,6 +3,8 @@ package edu.wpi.first.wpilibj.hal; public class DIOJNI extends JNIWrapper { public static native long initializeDigitalPort(long port_pointer); + public static native void freeDigitalPort(long port_pointer); + public static native boolean allocateDIO(long digital_port_pointer, boolean input); public static native void freeDIO(long digital_port_pointer); diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java index 5b9d3e89ee..a07a5e1819 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java @@ -51,4 +51,6 @@ public class JNIWrapper { public static native long getPortWithModule(byte module, byte pin); public static native long getPort(byte pin); + + public static native void freePort(long port_pointer); } diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java index 857ac11c59..bf187f2eec 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java @@ -3,6 +3,8 @@ package edu.wpi.first.wpilibj.hal; public class SolenoidJNI extends JNIWrapper { public static native long initializeSolenoidPort(long portPointer); + public static native void freeSolenoidPort(long port_pointer); + public static native long getPortWithModule(byte module, byte channel); public static native void setSolenoid(long port, boolean on);