diff --git a/hal/src/main/native/athena/DIO.cpp b/hal/src/main/native/athena/DIO.cpp index 6608071f92..732f7f985d 100644 --- a/hal/src/main/native/athena/DIO.cpp +++ b/hal/src/main/native/athena/DIO.cpp @@ -7,9 +7,13 @@ #include "HAL/DIO.h" +#include + #include +#include #include "DigitalInternal.h" +#include "HAL/cpp/fpga_clock.h" #include "HAL/handles/HandlesInternal.h" #include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" @@ -124,8 +128,21 @@ HAL_Bool HAL_CheckDIOChannel(int32_t channel) { void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) { auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO); // no status, so no need to check for a proper free. - digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO); if (port == nullptr) return; + digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO); + + // Wait for no other object to hold this handle. + auto start = hal::fpga_clock::now(); + while (port.use_count() != 1) { + auto current = hal::fpga_clock::now(); + if (start + std::chrono::seconds(1) < current) { + wpi::outs() << "DIO handle free timeout\n"; + wpi::outs().flush(); + break; + } + std::this_thread::yield(); + } + int32_t status = 0; std::lock_guard lock(digitalDIOMutex); if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { diff --git a/hal/src/main/native/athena/PWM.cpp b/hal/src/main/native/athena/PWM.cpp index 7c409e07cc..175fff3a3c 100644 --- a/hal/src/main/native/athena/PWM.cpp +++ b/hal/src/main/native/athena/PWM.cpp @@ -7,10 +7,14 @@ #include "HAL/PWM.h" +#include + #include +#include #include "ConstantsInternal.h" #include "DigitalInternal.h" +#include "HAL/cpp/fpga_clock.h" #include "HAL/handles/HandlesInternal.h" #include "PortsInternal.h" @@ -116,6 +120,20 @@ void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) { return; } + digitalChannelHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM); + + // Wait for no other object to hold this handle. + auto start = hal::fpga_clock::now(); + while (port.use_count() != 1) { + auto current = hal::fpga_clock::now(); + if (start + std::chrono::seconds(1) < current) { + wpi::outs() << "PWM handle free timeout\n"; + wpi::outs().flush(); + break; + } + std::this_thread::yield(); + } + if (port->channel > tPWM::kNumHdrRegisters - 1) { int32_t bitToUnset = 1 << remapMXPPWMChannel(port->channel); uint16_t specialFunctions = @@ -123,8 +141,6 @@ void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) { digitalSystem->writeEnableMXPSpecialFunction(specialFunctions & ~bitToUnset, status); } - - digitalChannelHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM); } HAL_Bool HAL_CheckPWMChannel(int32_t channel) {