diff --git a/hal/src/main/native/athena/REVPDH.cpp b/hal/src/main/native/athena/REVPDH.cpp index 1359c98ae4..10c019d59e 100644 --- a/hal/src/main/native/athena/REVPDH.cpp +++ b/hal/src/main/native/athena/REVPDH.cpp @@ -11,6 +11,7 @@ #include #include +#include #include @@ -35,6 +36,7 @@ struct REV_PDHObj { int32_t controlPeriod; HAL_CANHandle hcan; std::string previousAllocation; + HAL_PowerDistributionVersion versionInfo; }; } // namespace @@ -226,6 +228,7 @@ HAL_REVPDHHandle HAL_InitializeREVPDH(int32_t module, hpdh->previousAllocation = allocationLocation ? allocationLocation : ""; hpdh->hcan = hcan; hpdh->controlPeriod = kDefaultControlPeriod; + std::memset(&hpdh->versionInfo, 0, sizeof(hpdh->versionInfo)); return handle; } @@ -490,6 +493,18 @@ void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle, return; } + if (hpdh->versionInfo.firmwareMajor > 0) { + version->firmwareMajor = hpdh->versionInfo.firmwareMajor; + version->firmwareMinor = hpdh->versionInfo.firmwareMinor; + version->firmwareFix = hpdh->versionInfo.firmwareFix; + version->hardwareMajor = hpdh->versionInfo.hardwareMajor; + version->hardwareMinor = hpdh->versionInfo.hardwareMinor; + version->uniqueId = hpdh->versionInfo.uniqueId; + + *status = 0; + return; + } + HAL_WriteCANRTRFrame(hpdh->hcan, PDH_VERSION_LENGTH, PDH_VERSION_FRAME_API, status); @@ -497,9 +512,15 @@ void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle, return; } - HAL_ReadCANPacketTimeout(hpdh->hcan, PDH_VERSION_FRAME_API, packedData, - &length, ×tamp, kDefaultControlPeriod * 2, - status); + uint32_t timeoutMs = 100; + for (uint32_t i = 0; i <= timeoutMs; i++) { + HAL_ReadCANPacketNew(hpdh->hcan, PDH_VERSION_FRAME_API, packedData, &length, + ×tamp, status); + if (*status == 0) { + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } if (*status != 0) { return; @@ -513,6 +534,8 @@ void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle, version->hardwareMinor = result.hardware_minor; version->hardwareMajor = result.hardware_major; version->uniqueId = result.unique_id; + + hpdh->versionInfo = *version; } void HAL_GetREVPDHFaults(HAL_REVPDHHandle handle, diff --git a/hal/src/main/native/athena/REVPH.cpp b/hal/src/main/native/athena/REVPH.cpp index 6a7a112f15..5b18de6d04 100644 --- a/hal/src/main/native/athena/REVPH.cpp +++ b/hal/src/main/native/athena/REVPH.cpp @@ -4,6 +4,8 @@ #include "hal/REVPH.h" +#include + #include #include "HALInitializer.h" @@ -63,6 +65,7 @@ struct REV_PHObj { wpi::mutex solenoidLock; HAL_CANHandle hcan; std::string previousAllocation; + HAL_REVPHVersion versionInfo; }; } // namespace @@ -221,6 +224,9 @@ HAL_REVPHHandle HAL_InitializeREVPH(int32_t module, hph->previousAllocation = allocationLocation ? allocationLocation : ""; hph->hcan = hcan; hph->controlPeriod = kDefaultControlPeriod; + std::memset(&hph->desiredSolenoidsState, 0, + sizeof(hph->desiredSolenoidsState)); + std::memset(&hph->versionInfo, 0, sizeof(hph->versionInfo)); // Start closed-loop compressor control by starting solenoid state updates HAL_SendREVPHSolenoidsState(hph.get(), status); @@ -480,6 +486,18 @@ void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version, return; } + if (ph->versionInfo.firmwareMajor > 0) { + version->firmwareMajor = ph->versionInfo.firmwareMajor; + version->firmwareMinor = ph->versionInfo.firmwareMinor; + version->firmwareFix = ph->versionInfo.firmwareFix; + version->hardwareMajor = ph->versionInfo.hardwareMajor; + version->hardwareMinor = ph->versionInfo.hardwareMinor; + version->uniqueId = ph->versionInfo.uniqueId; + + *status = 0; + return; + } + HAL_WriteCANRTRFrame(ph->hcan, PH_VERSION_LENGTH, PH_VERSION_FRAME_API, status); @@ -487,8 +505,15 @@ void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version, return; } - HAL_ReadCANPacketTimeout(ph->hcan, PH_VERSION_FRAME_API, packedData, &length, - ×tamp, kDefaultControlPeriod * 2, status); + uint32_t timeoutMs = 100; + for (uint32_t i = 0; i <= timeoutMs; i++) { + HAL_ReadCANPacketNew(ph->hcan, PH_VERSION_FRAME_API, packedData, &length, + ×tamp, status); + if (*status == 0) { + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } if (*status != 0) { return; @@ -502,6 +527,8 @@ void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version, version->hardwareMinor = result.hardware_minor; version->hardwareMajor = result.hardware_major; version->uniqueId = result.unique_id; + + ph->versionInfo = *version; } int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status) { diff --git a/wpilibc/src/main/native/cpp/PneumaticHub.cpp b/wpilibc/src/main/native/cpp/PneumaticHub.cpp index 558b3102c1..9520559684 100644 --- a/wpilibc/src/main/native/cpp/PneumaticHub.cpp +++ b/wpilibc/src/main/native/cpp/PneumaticHub.cpp @@ -54,6 +54,15 @@ class PneumaticHub::DataStore { m_moduleObject = PneumaticHub{handle, module}; m_moduleObject.m_dataStore = std::shared_ptr{this, wpi::NullDeleter()}; + + auto version = m_moduleObject.GetVersion(); + if (version.FirmwareMajor > 0 && version.FirmwareMajor < 22) { + throw FRC_MakeError( + err::AssertionFailure, + "The Pneumatic Hub has firmware version {}.{}.{}, and must be " + "updated to version 2022.0.0 or later using the REV Hardware Client", + version.FirmwareMajor, version.FirmwareMinor, version.FirmwareFix); + } } ~DataStore() noexcept { HAL_FreeREVPH(m_moduleObject.m_handle); } diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java index 7d1669e240..95f5583ede 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java @@ -27,6 +27,17 @@ public class PneumaticHub implements PneumaticsBase { m_handle = REVPHJNI.initialize(module); m_module = module; m_handleMap.put(module, this); + + final REVPHVersion version = REVPHJNI.getVersion(m_handle); + if (version.firmwareMajor > 0 && version.firmwareMajor < 22) { + final String fwVersion = + version.firmwareMajor + "." + version.firmwareMinor + "." + version.firmwareFix; + throw new IllegalStateException( + "The Pneumatic Hub has firmware version " + + fwVersion + + ", and must be updated to version 2022.0.0 or later " + + "using the REV Hardware Client."); + } } @Override