diff --git a/hal/include/HAL/Errors.h b/hal/include/HAL/Errors.h index 6b7d09f8d9..e233c2e7f8 100644 --- a/hal/include/HAL/Errors.h +++ b/hal/include/HAL/Errors.h @@ -67,6 +67,12 @@ #define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range." #define RESOURCE_IS_ALLOCATED -1029 #define RESOURCE_IS_ALLOCATED_MESSAGE "HAL: Resource already allocated" +#define RESOURCE_OUT_OF_RANGE -1030 +#define RESOURCE_OUT_OF_RANGE_MESSAGE \ + "HAL: The requested resource is out of range." +#define HAL_INVALID_ACCUMULATOR_CHANNEL -1035 +#define HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE \ + "HAL: The requested input is not an accumulator channel" #define HAL_COUNTER_NOT_SUPPORTED -1058 #define HAL_COUNTER_NOT_SUPPORTED_MESSAGE \ "HAL: Counter mode not supported for encoder method" diff --git a/hal/lib/athena/handles/DigitalHandleResource.h b/hal/include/HAL/handles/DigitalHandleResource.h similarity index 98% rename from hal/lib/athena/handles/DigitalHandleResource.h rename to hal/include/HAL/handles/DigitalHandleResource.h index 1dafdd3464..778ff364e9 100644 --- a/hal/lib/athena/handles/DigitalHandleResource.h +++ b/hal/include/HAL/handles/DigitalHandleResource.h @@ -15,7 +15,7 @@ #include "HAL/Errors.h" #include "HAL/Types.h" #include "HAL/cpp/priority_mutex.h" -#include "HandlesInternal.h" +#include "HAL/handles/HandlesInternal.h" namespace hal { @@ -67,7 +67,7 @@ THandle DigitalHandleResource::Allocate( int16_t index, HAL_HandleEnum enumValue, int32_t* status) { // don't aquire the lock if we can fail early. if (index < 0 || index >= size) { - *status = PARAMETER_OUT_OF_RANGE; + *status = RESOURCE_OUT_OF_RANGE; return HAL_kInvalidHandle; } std::lock_guard sync(m_handleMutexes[index]); diff --git a/hal/lib/athena/handles/HandlesInternal.h b/hal/include/HAL/handles/HandlesInternal.h similarity index 100% rename from hal/lib/athena/handles/HandlesInternal.h rename to hal/include/HAL/handles/HandlesInternal.h diff --git a/hal/lib/athena/handles/IndexedHandleResource.h b/hal/include/HAL/handles/IndexedHandleResource.h similarity index 98% rename from hal/lib/athena/handles/IndexedHandleResource.h rename to hal/include/HAL/handles/IndexedHandleResource.h index b1fbb30ba1..c19fdab53c 100644 --- a/hal/lib/athena/handles/IndexedHandleResource.h +++ b/hal/include/HAL/handles/IndexedHandleResource.h @@ -15,7 +15,7 @@ #include "HAL/Errors.h" #include "HAL/Types.h" #include "HAL/cpp/priority_mutex.h" -#include "HandlesInternal.h" +#include "HAL/handles/HandlesInternal.h" namespace hal { @@ -73,7 +73,7 @@ THandle IndexedHandleResource::Allocate( int16_t index, int32_t* status) { // don't aquire the lock if we can fail early. if (index < 0 || index >= size) { - *status = PARAMETER_OUT_OF_RANGE; + *status = RESOURCE_OUT_OF_RANGE; return HAL_kInvalidHandle; } std::lock_guard sync(m_handleMutexes[index]); diff --git a/hal/lib/athena/handles/LimitedClassedHandleResource.h b/hal/include/HAL/handles/LimitedClassedHandleResource.h similarity index 99% rename from hal/lib/athena/handles/LimitedClassedHandleResource.h rename to hal/include/HAL/handles/LimitedClassedHandleResource.h index 33387ade1a..61dec5fc60 100644 --- a/hal/lib/athena/handles/LimitedClassedHandleResource.h +++ b/hal/include/HAL/handles/LimitedClassedHandleResource.h @@ -14,7 +14,7 @@ #include "HAL/Types.h" #include "HAL/cpp/priority_mutex.h" -#include "HandlesInternal.h" +#include "HAL/handles/HandlesInternal.h" namespace hal { diff --git a/hal/lib/athena/handles/LimitedHandleResource.h b/hal/include/HAL/handles/LimitedHandleResource.h similarity index 100% rename from hal/lib/athena/handles/LimitedHandleResource.h rename to hal/include/HAL/handles/LimitedHandleResource.h diff --git a/hal/lib/athena/handles/UnlimitedHandleResource.h b/hal/include/HAL/handles/UnlimitedHandleResource.h similarity index 98% rename from hal/lib/athena/handles/UnlimitedHandleResource.h rename to hal/include/HAL/handles/UnlimitedHandleResource.h index 423faa6a9d..a765a89c5a 100644 --- a/hal/lib/athena/handles/UnlimitedHandleResource.h +++ b/hal/include/HAL/handles/UnlimitedHandleResource.h @@ -14,7 +14,7 @@ #include "HAL/Types.h" #include "HAL/cpp/priority_mutex.h" -#include "handles/HandlesInternal.h" +#include "HAL/handles/HandlesInternal.h" namespace hal { diff --git a/hal/lib/athena/AnalogAccumulator.cpp b/hal/lib/athena/AnalogAccumulator.cpp index f6b5c11bf7..cd075b7606 100644 --- a/hal/lib/athena/AnalogAccumulator.cpp +++ b/hal/lib/athena/AnalogAccumulator.cpp @@ -36,6 +36,10 @@ HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analog_port_handle, */ void HAL_InitAccumulator(HAL_AnalogInputHandle analog_port_handle, int32_t* status) { + if (!HAL_IsAccumulatorChannel(analog_port_handle, status)) { + *status = HAL_INVALID_ACCUMULATOR_CHANNEL; + return; + } HAL_SetAccumulatorCenter(analog_port_handle, 0, status); HAL_ResetAccumulator(analog_port_handle, status); } diff --git a/hal/lib/athena/AnalogGyro.cpp b/hal/lib/athena/AnalogGyro.cpp index 0ba431f7e9..a1db55185f 100644 --- a/hal/lib/athena/AnalogGyro.cpp +++ b/hal/lib/athena/AnalogGyro.cpp @@ -13,7 +13,7 @@ #include "AnalogInternal.h" #include "HAL/AnalogAccumulator.h" #include "HAL/AnalogInput.h" -#include "handles/IndexedHandleResource.h" +#include "HAL/handles/IndexedHandleResource.h" namespace { struct AnalogGyro { @@ -46,7 +46,7 @@ HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analog_handle, int32_t* status) { if (!HAL_IsAccumulatorChannel(analog_handle, status)) { if (*status == 0) { - *status = PARAMETER_OUT_OF_RANGE; + *status = HAL_INVALID_ACCUMULATOR_CHANNEL; } return HAL_kInvalidHandle; } diff --git a/hal/lib/athena/AnalogInput.cpp b/hal/lib/athena/AnalogInput.cpp index 80de41859d..882efe265c 100644 --- a/hal/lib/athena/AnalogInput.cpp +++ b/hal/lib/athena/AnalogInput.cpp @@ -14,8 +14,8 @@ #include "HAL/AnalogAccumulator.h" #include "HAL/HAL.h" #include "HAL/cpp/priority_mutex.h" +#include "HAL/handles/HandlesInternal.h" #include "PortsInternal.h" -#include "handles/HandlesInternal.h" using namespace hal; diff --git a/hal/lib/athena/AnalogInternal.h b/hal/lib/athena/AnalogInternal.h index 55dc564cbc..5d076e3b3b 100644 --- a/hal/lib/athena/AnalogInternal.h +++ b/hal/lib/athena/AnalogInternal.h @@ -12,8 +12,8 @@ #include "ChipObject.h" #include "HAL/Ports.h" #include "HAL/cpp/priority_mutex.h" +#include "HAL/handles/IndexedHandleResource.h" #include "PortsInternal.h" -#include "handles/IndexedHandleResource.h" namespace hal { constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock diff --git a/hal/lib/athena/AnalogOutput.cpp b/hal/lib/athena/AnalogOutput.cpp index d4cb653628..97f5be6022 100644 --- a/hal/lib/athena/AnalogOutput.cpp +++ b/hal/lib/athena/AnalogOutput.cpp @@ -9,9 +9,9 @@ #include "AnalogInternal.h" #include "HAL/Errors.h" +#include "HAL/handles/HandlesInternal.h" +#include "HAL/handles/IndexedHandleResource.h" #include "PortsInternal.h" -#include "handles/HandlesInternal.h" -#include "handles/IndexedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/AnalogTrigger.cpp b/hal/lib/athena/AnalogTrigger.cpp index 37c8b46fbd..ec0ef2ece4 100644 --- a/hal/lib/athena/AnalogTrigger.cpp +++ b/hal/lib/athena/AnalogTrigger.cpp @@ -10,9 +10,9 @@ #include "AnalogInternal.h" #include "HAL/AnalogInput.h" #include "HAL/Errors.h" +#include "HAL/handles/HandlesInternal.h" +#include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" -#include "handles/HandlesInternal.h" -#include "handles/LimitedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/Compressor.cpp b/hal/lib/athena/Compressor.cpp index 0621a71199..dffebcfded 100644 --- a/hal/lib/athena/Compressor.cpp +++ b/hal/lib/athena/Compressor.cpp @@ -8,10 +8,10 @@ #include "HAL/Compressor.h" #include "HAL/Errors.h" +#include "HAL/handles/HandlesInternal.h" #include "PCMInternal.h" #include "PortsInternal.h" #include "ctre/PCM.h" -#include "handles/HandlesInternal.h" using namespace hal; diff --git a/hal/lib/athena/Counter.cpp b/hal/lib/athena/Counter.cpp index 70d69bd855..5080b6e068 100644 --- a/hal/lib/athena/Counter.cpp +++ b/hal/lib/athena/Counter.cpp @@ -10,8 +10,8 @@ #include "ConstantsInternal.h" #include "DigitalInternal.h" #include "HAL/HAL.h" +#include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" -#include "handles/LimitedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/DIO.cpp b/hal/lib/athena/DIO.cpp index ceb56dbc3d..bf62b7e18d 100644 --- a/hal/lib/athena/DIO.cpp +++ b/hal/lib/athena/DIO.cpp @@ -10,9 +10,9 @@ #include #include "DigitalInternal.h" +#include "HAL/handles/HandlesInternal.h" +#include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" -#include "handles/HandlesInternal.h" -#include "handles/LimitedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/DigitalInternal.h b/hal/lib/athena/DigitalInternal.h index 3a8dc93585..68b03aff79 100644 --- a/hal/lib/athena/DigitalInternal.h +++ b/hal/lib/athena/DigitalInternal.h @@ -13,9 +13,9 @@ #include "HAL/AnalogTrigger.h" #include "HAL/Ports.h" #include "HAL/Types.h" +#include "HAL/handles/DigitalHandleResource.h" +#include "HAL/handles/HandlesInternal.h" #include "PortsInternal.h" -#include "handles/DigitalHandleResource.h" -#include "handles/HandlesInternal.h" namespace hal { constexpr uint32_t kMXPDigitalPWMOffset = 6; // MXP pins when used as digital diff --git a/hal/lib/athena/Encoder.cpp b/hal/lib/athena/Encoder.cpp index c696fa2c15..5fc5aa6af8 100644 --- a/hal/lib/athena/Encoder.cpp +++ b/hal/lib/athena/Encoder.cpp @@ -12,8 +12,8 @@ #include "FPGAEncoder.h" #include "HAL/Counter.h" #include "HAL/Errors.h" +#include "HAL/handles/LimitedClassedHandleResource.h" #include "PortsInternal.h" -#include "handles/LimitedClassedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/FPGAEncoder.cpp b/hal/lib/athena/FPGAEncoder.cpp index 4bbd34551c..a86a27fc18 100644 --- a/hal/lib/athena/FPGAEncoder.cpp +++ b/hal/lib/athena/FPGAEncoder.cpp @@ -8,8 +8,8 @@ #include "FPGAEncoder.h" #include "DigitalInternal.h" +#include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" -#include "handles/LimitedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/HALAthena.cpp b/hal/lib/athena/HALAthena.cpp index 10440dfa10..961b274dad 100644 --- a/hal/lib/athena/HALAthena.cpp +++ b/hal/lib/athena/HALAthena.cpp @@ -25,8 +25,8 @@ #include "HAL/Errors.h" #include "HAL/cpp/priority_condition_variable.h" #include "HAL/cpp/priority_mutex.h" +#include "HAL/handles/HandlesInternal.h" #include "ctre/ctre.h" -#include "handles/HandlesInternal.h" #include "visa/visa.h" static tGlobal* global = nullptr; @@ -113,6 +113,10 @@ const char* HAL_GetErrorMessage(int32_t code) { return NO_AVAILABLE_RESOURCES_MESSAGE; case RESOURCE_IS_ALLOCATED: return RESOURCE_IS_ALLOCATED_MESSAGE; + case RESOURCE_OUT_OF_RANGE: + return RESOURCE_OUT_OF_RANGE_MESSAGE; + case HAL_INVALID_ACCUMULATOR_CHANNEL: + return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE; case HAL_HANDLE_ERROR: return HAL_HANDLE_ERROR_MESSAGE; case NULL_PARAMETER: diff --git a/hal/lib/athena/Interrupts.cpp b/hal/lib/athena/Interrupts.cpp index edc6bc2104..71db14b193 100644 --- a/hal/lib/athena/Interrupts.cpp +++ b/hal/lib/athena/Interrupts.cpp @@ -13,9 +13,9 @@ #include "DigitalInternal.h" #include "HAL/Errors.h" +#include "HAL/handles/HandlesInternal.h" +#include "HAL/handles/LimitedHandleResource.h" #include "PortsInternal.h" -#include "handles/HandlesInternal.h" -#include "handles/LimitedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/Notifier.cpp b/hal/lib/athena/Notifier.cpp index f9bd8051b3..3693971b6f 100644 --- a/hal/lib/athena/Notifier.cpp +++ b/hal/lib/athena/Notifier.cpp @@ -17,7 +17,7 @@ #include "ChipObject.h" #include "HAL/HAL.h" #include "HAL/cpp/priority_mutex.h" -#include "handles/UnlimitedHandleResource.h" +#include "HAL/handles/UnlimitedHandleResource.h" static const uint32_t kTimerInterruptNumber = 28; diff --git a/hal/lib/athena/PCMInternal.cpp b/hal/lib/athena/PCMInternal.cpp index a2da8c3811..0a2676f674 100644 --- a/hal/lib/athena/PCMInternal.cpp +++ b/hal/lib/athena/PCMInternal.cpp @@ -16,7 +16,7 @@ PCM* PCM_modules[kNumPCMModules] = {nullptr}; void initializePCM(int32_t module, int32_t* status) { if (!HAL_CheckSolenoidModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; + *status = RESOURCE_OUT_OF_RANGE; return; } if (!PCM_modules[module]) { diff --git a/hal/lib/athena/PDP.cpp b/hal/lib/athena/PDP.cpp index 601538f7e6..f2f68314bd 100644 --- a/hal/lib/athena/PDP.cpp +++ b/hal/lib/athena/PDP.cpp @@ -20,7 +20,7 @@ extern "C" { void HAL_InitializePDP(int32_t module, int32_t* status) { if (!HAL_CheckPDPModule(module)) { - *status = PARAMETER_OUT_OF_RANGE; + *status = RESOURCE_OUT_OF_RANGE; return; } if (!pdp[module]) { diff --git a/hal/lib/athena/PWM.cpp b/hal/lib/athena/PWM.cpp index bdd1ad2f07..7bc2c4d412 100644 --- a/hal/lib/athena/PWM.cpp +++ b/hal/lib/athena/PWM.cpp @@ -9,8 +9,8 @@ #include "ConstantsInternal.h" #include "DigitalInternal.h" +#include "HAL/handles/HandlesInternal.h" #include "PortsInternal.h" -#include "handles/HandlesInternal.h" using namespace hal; diff --git a/hal/lib/athena/Relay.cpp b/hal/lib/athena/Relay.cpp index ba53801bf4..5fbf418f58 100644 --- a/hal/lib/athena/Relay.cpp +++ b/hal/lib/athena/Relay.cpp @@ -8,8 +8,8 @@ #include "HAL/Relay.h" #include "DigitalInternal.h" +#include "HAL/handles/IndexedHandleResource.h" #include "PortsInternal.h" -#include "handles/IndexedHandleResource.h" using namespace hal; diff --git a/hal/lib/athena/Solenoid.cpp b/hal/lib/athena/Solenoid.cpp index 33d7243016..556ec0538d 100644 --- a/hal/lib/athena/Solenoid.cpp +++ b/hal/lib/athena/Solenoid.cpp @@ -11,11 +11,11 @@ #include "FRC_NetworkCommunication/LoadOut.h" #include "HAL/Errors.h" #include "HAL/Ports.h" +#include "HAL/handles/HandlesInternal.h" +#include "HAL/handles/IndexedHandleResource.h" #include "PCMInternal.h" #include "PortsInternal.h" #include "ctre/PCM.h" -#include "handles/HandlesInternal.h" -#include "handles/IndexedHandleResource.h" namespace { struct Solenoid { @@ -44,7 +44,7 @@ HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle port_handle, // initializePCM will check the module if (!HAL_CheckSolenoidPin(pin)) { - *status = PARAMETER_OUT_OF_RANGE; + *status = RESOURCE_OUT_OF_RANGE; return HAL_kInvalidHandle; } diff --git a/hal/lib/athena/handles/HandlesInternal.cpp b/hal/lib/shared/handles/HandlesInternal.cpp similarity index 90% rename from hal/lib/athena/handles/HandlesInternal.cpp rename to hal/lib/shared/handles/HandlesInternal.cpp index 354abab900..af19aa97c5 100644 --- a/hal/lib/athena/handles/HandlesInternal.cpp +++ b/hal/lib/shared/handles/HandlesInternal.cpp @@ -5,10 +5,7 @@ /* the project. */ /*----------------------------------------------------------------------------*/ -#include "HandlesInternal.h" -#include "IndexedHandleResource.h" -#include "LimitedHandleResource.h" -#include "UnlimitedHandleResource.h" +#include "HAL/handles/HandlesInternal.h" namespace hal { HAL_PortHandle createPortHandle(uint8_t pin, uint8_t module) { diff --git a/wpilibc/athena/src/AnalogInput.cpp b/wpilibc/athena/src/AnalogInput.cpp index c914b63449..f0d1f8bd2a 100644 --- a/wpilibc/athena/src/AnalogInput.cpp +++ b/wpilibc/athena/src/AnalogInput.cpp @@ -38,7 +38,8 @@ AnalogInput::AnalogInput(uint32_t channel) { int32_t status = 0; m_port = HAL_InitializeAnalogInputPort(port, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumAnalogInputs(), channel, + HAL_GetErrorMessage(status)); m_channel = std::numeric_limits::max(); m_port = HAL_kInvalidHandle; return; diff --git a/wpilibc/athena/src/AnalogOutput.cpp b/wpilibc/athena/src/AnalogOutput.cpp index 8f5273f8f9..65357fa964 100644 --- a/wpilibc/athena/src/AnalogOutput.cpp +++ b/wpilibc/athena/src/AnalogOutput.cpp @@ -37,7 +37,8 @@ AnalogOutput::AnalogOutput(uint32_t channel) { int32_t status = 0; m_port = HAL_InitializeAnalogOutputPort(port, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumAnalogOutputs(), channel, + HAL_GetErrorMessage(status)); m_channel = std::numeric_limits::max(); m_port = HAL_kInvalidHandle; return; diff --git a/wpilibc/athena/src/Compressor.cpp b/wpilibc/athena/src/Compressor.cpp index c7177a1352..52a7005089 100644 --- a/wpilibc/athena/src/Compressor.cpp +++ b/wpilibc/athena/src/Compressor.cpp @@ -19,7 +19,8 @@ Compressor::Compressor(uint8_t pcmID) : m_module(pcmID) { int32_t status = 0; m_compressorHandle = HAL_InitializeCompressor(m_module, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumPCMModules(), pcmID, + HAL_GetErrorMessage(status)); return; } SetClosedLoopControl(true); diff --git a/wpilibc/athena/src/DigitalInput.cpp b/wpilibc/athena/src/DigitalInput.cpp index 129ca41c43..0405ce10fd 100644 --- a/wpilibc/athena/src/DigitalInput.cpp +++ b/wpilibc/athena/src/DigitalInput.cpp @@ -35,7 +35,8 @@ DigitalInput::DigitalInput(uint32_t channel) { int32_t status = 0; m_handle = HAL_InitializeDIOPort(HAL_GetPort(channel), true, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumDigitalPins(), channel, + HAL_GetErrorMessage(status)); m_handle = HAL_kInvalidHandle; m_channel = std::numeric_limits::max(); return; diff --git a/wpilibc/athena/src/DigitalOutput.cpp b/wpilibc/athena/src/DigitalOutput.cpp index 86b744e7e0..2d14d139d1 100644 --- a/wpilibc/athena/src/DigitalOutput.cpp +++ b/wpilibc/athena/src/DigitalOutput.cpp @@ -36,7 +36,8 @@ DigitalOutput::DigitalOutput(uint32_t channel) { int32_t status = 0; m_handle = HAL_InitializeDIOPort(HAL_GetPort(channel), false, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumDigitalPins(), channel, + HAL_GetErrorMessage(status)); m_channel = std::numeric_limits::max(); m_handle = HAL_kInvalidHandle; return; diff --git a/wpilibc/athena/src/DoubleSolenoid.cpp b/wpilibc/athena/src/DoubleSolenoid.cpp index 2e7d8bfa99..f155fc4c82 100644 --- a/wpilibc/athena/src/DoubleSolenoid.cpp +++ b/wpilibc/athena/src/DoubleSolenoid.cpp @@ -56,7 +56,8 @@ DoubleSolenoid::DoubleSolenoid(uint8_t moduleNumber, uint32_t forwardChannel, m_forwardHandle = HAL_InitializeSolenoidPort( HAL_GetPortWithModule(moduleNumber, m_forwardChannel), &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidPins(), + forwardChannel, HAL_GetErrorMessage(status)); m_forwardHandle = HAL_kInvalidHandle; m_reverseHandle = HAL_kInvalidHandle; return; @@ -65,7 +66,8 @@ DoubleSolenoid::DoubleSolenoid(uint8_t moduleNumber, uint32_t forwardChannel, m_reverseHandle = HAL_InitializeSolenoidPort( HAL_GetPortWithModule(moduleNumber, m_reverseChannel), &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidPins(), + reverseChannel, HAL_GetErrorMessage(status)); // free forward solenoid HAL_FreeSolenoidPort(m_forwardHandle); m_forwardHandle = HAL_kInvalidHandle; diff --git a/wpilibc/athena/src/PWM.cpp b/wpilibc/athena/src/PWM.cpp index 767f9d2a4b..fba79d0946 100644 --- a/wpilibc/athena/src/PWM.cpp +++ b/wpilibc/athena/src/PWM.cpp @@ -35,7 +35,8 @@ PWM::PWM(uint32_t channel) { int32_t status = 0; m_handle = HAL_InitializePWMPort(HAL_GetPort(channel), &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumPWMPins(), channel, + HAL_GetErrorMessage(status)); m_channel = std::numeric_limits::max(); m_handle = HAL_kInvalidHandle; return; diff --git a/wpilibc/athena/src/PowerDistributionPanel.cpp b/wpilibc/athena/src/PowerDistributionPanel.cpp index 05c764b441..c451e3c603 100644 --- a/wpilibc/athena/src/PowerDistributionPanel.cpp +++ b/wpilibc/athena/src/PowerDistributionPanel.cpp @@ -22,7 +22,8 @@ PowerDistributionPanel::PowerDistributionPanel(uint8_t module) int32_t status = 0; HAL_InitializePDP(m_module, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumPDPModules(), module, + HAL_GetErrorMessage(status)); m_module = -1; return; } diff --git a/wpilibc/athena/src/Relay.cpp b/wpilibc/athena/src/Relay.cpp index 98a73fefc3..3637a2ac03 100644 --- a/wpilibc/athena/src/Relay.cpp +++ b/wpilibc/athena/src/Relay.cpp @@ -38,7 +38,8 @@ Relay::Relay(uint32_t channel, Relay::Direction direction) int32_t status = 0; m_forwardHandle = HAL_InitializeRelayPort(portHandle, true, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumRelayPins(), channel, + HAL_GetErrorMessage(status)); m_forwardHandle = HAL_kInvalidHandle; m_reverseHandle = HAL_kInvalidHandle; return; @@ -49,7 +50,8 @@ Relay::Relay(uint32_t channel, Relay::Direction direction) int32_t status = 0; m_reverseHandle = HAL_InitializeRelayPort(portHandle, false, &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumRelayPins(), channel, + HAL_GetErrorMessage(status)); m_forwardHandle = HAL_kInvalidHandle; m_reverseHandle = HAL_kInvalidHandle; return; diff --git a/wpilibc/athena/src/Solenoid.cpp b/wpilibc/athena/src/Solenoid.cpp index d48d61112c..a9504da332 100644 --- a/wpilibc/athena/src/Solenoid.cpp +++ b/wpilibc/athena/src/Solenoid.cpp @@ -44,7 +44,8 @@ Solenoid::Solenoid(uint8_t moduleNumber, uint32_t channel) m_solenoidHandle = HAL_InitializeSolenoidPort( HAL_GetPortWithModule(moduleNumber, channel), &status); if (status != 0) { - wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); + wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidPins(), channel, + HAL_GetErrorMessage(status)); m_solenoidHandle = HAL_kInvalidHandle; return; } diff --git a/wpilibc/shared/include/ErrorBase.h b/wpilibc/shared/include/ErrorBase.h index 2f04c7378b..5277a1528e 100644 --- a/wpilibc/shared/include/ErrorBase.h +++ b/wpilibc/shared/include/ErrorBase.h @@ -26,6 +26,12 @@ if ((code) != 0) \ this->SetError((code), (context), __FILE__, __FUNCTION__, __LINE__); \ } while (0) +#define wpi_setErrorWithContextRange(code, min, max, req, context) \ + do { \ + if ((code) != 0) \ + this->SetErrorRange((code), (min), (max), (req), (context), __FILE__, \ + __FUNCTION__, __LINE__); \ + } while (0) #define wpi_setError(code) wpi_setErrorWithContext(code, "") #define wpi_setStaticErrorWithContext(object, code, context) \ do { \ @@ -82,6 +88,11 @@ class ErrorBase { virtual void SetError(Error::Code code, llvm::StringRef contextMessage, llvm::StringRef filename, llvm::StringRef function, uint32_t lineNumber) const; + virtual void SetErrorRange(Error::Code code, int32_t minRange, + int32_t maxRange, int32_t requestedValue, + llvm::StringRef contextMessage, + llvm::StringRef filename, llvm::StringRef function, + uint32_t lineNumber) const; virtual void SetWPIError(llvm::StringRef errorMessage, Error::Code code, llvm::StringRef contextMessage, llvm::StringRef filename, llvm::StringRef function, diff --git a/wpilibc/shared/src/ErrorBase.cpp b/wpilibc/shared/src/ErrorBase.cpp index 2f9401056a..f7ce1d197d 100644 --- a/wpilibc/shared/src/ErrorBase.cpp +++ b/wpilibc/shared/src/ErrorBase.cpp @@ -119,6 +119,44 @@ void ErrorBase::SetError(Error::Code code, llvm::StringRef contextMessage, } } +/** + * @brief Set the current error information associated with this sensor. + * Range versions use for initialization code. + * + * @param code The error code + * @param minRange The minimum allowed allocation range + * @param maxRange The maximum allowed allocation range + * @param requestedValue The requested value to allocate + * @param contextMessage A custom message from the code that set the error. + * @param filename Filename of the error source + * @param function Function of the error source + * @param lineNumber Line number of the error source + */ +void ErrorBase::SetErrorRange(Error::Code code, int32_t minRange, + int32_t maxRange, int32_t requestedValue, + llvm::StringRef contextMessage, + llvm::StringRef filename, + llvm::StringRef function, + uint32_t lineNumber) const { + // If there was an error + if (code != 0) { + size_t size = contextMessage.size() + 100; + char* buf = new char[size]; + snprintf(buf, size, + "%s, Minimum Value: %d, Maximum Value: %d, Requested Value: %d", + contextMessage.data(), minRange, maxRange, requestedValue); + // Set the current error information for this object. + m_error.Set(code, buf, filename, function, lineNumber, this); + delete[] buf; + + // Update the global error if there is not one already set. + std::lock_guard mutex(_globalErrorMutex); + if (_globalError.GetCode() == 0) { + _globalError.Clone(m_error); + } + } +} + /** * @brief Set the current error information associated with this sensor. * diff --git a/wpilibj/src/athena/cpp/lib/AnalogGyroJNI.cpp b/wpilibj/src/athena/cpp/lib/AnalogGyroJNI.cpp index d6ce1a651f..df7a9c3b80 100644 --- a/wpilibj/src/athena/cpp/lib/AnalogGyroJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/AnalogGyroJNI.cpp @@ -13,6 +13,7 @@ #include "HAL/AnalogGyro.h" #include "HALUtil.h" +#include "HAL/handles/HandlesInternal.h" // set the logging level TLogLevel analogGyroJNILogLevel = logWARNING; @@ -37,6 +38,8 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogGyroJNI_initializeAn HAL_GyroHandle handle = HAL_InitializeAnalogGyro((HAL_AnalogInputHandle)id, &status); ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status; ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << handle; + // Analog input does range checking, so we don't need to do so. + CheckStatus(env, status); return (jint) handle; } diff --git a/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp b/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp index 9ca9e81df9..38a2bfe0a7 100644 --- a/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp @@ -15,7 +15,9 @@ #include "HAL/AnalogOutput.h" #include "HAL/AnalogAccumulator.h" #include "HAL/AnalogTrigger.h" +#include "HAL/Ports.h" #include "HALUtil.h" +#include "HAL/handles/HandlesInternal.h" // set the logging level TLogLevel analogJNILogLevel = logWARNING; @@ -41,7 +43,8 @@ Java_edu_wpi_first_wpilibj_hal_AnalogJNI_initializeAnalogInputPort( auto analog = HAL_InitializeAnalogInputPort((HAL_PortHandle)id, &status); ANALOGJNI_LOG(logDEBUG) << "Status = " << status; ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << analog; - CheckStatus(env, status); + CheckStatusRange(env, 0, HAL_GetNumAnalogInputs(), + hal::getPortHandlePin((HAL_PortHandle)id), status); return (jint)analog; } @@ -70,7 +73,8 @@ Java_edu_wpi_first_wpilibj_hal_AnalogJNI_initializeAnalogOutputPort( HAL_AnalogOutputHandle analog = HAL_InitializeAnalogOutputPort((HAL_PortHandle)id, &status); ANALOGJNI_LOG(logDEBUG) << "Status = " << status; ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << analog; - CheckStatus(env, status); + CheckStatusRange(env, 0, HAL_GetNumAnalogOutputs(), + hal::getPortHandlePin((HAL_PortHandle)id), status); return (jlong)analog; } diff --git a/wpilibj/src/athena/cpp/lib/CanTalonJNI.cpp b/wpilibj/src/athena/cpp/lib/CanTalonJNI.cpp index 5773863ce4..1829144ae2 100644 --- a/wpilibj/src/athena/cpp/lib/CanTalonJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/CanTalonJNI.cpp @@ -17,7 +17,7 @@ extern "C" { inline bool CheckCTRStatus(JNIEnv *env, CTR_Code status) { - if (status != CTR_OKAY) ReportError(env, (int32_t)status, false); + if (status != CTR_OKAY) ReportError(env, (int32_t)status, 0, 0, 0, false); return status == CTR_OKAY; } diff --git a/wpilibj/src/athena/cpp/lib/CompressorJNI.cpp b/wpilibj/src/athena/cpp/lib/CompressorJNI.cpp index 6e27bf3816..c6a33cc9df 100644 --- a/wpilibj/src/athena/cpp/lib/CompressorJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/CompressorJNI.cpp @@ -22,9 +22,7 @@ Java_edu_wpi_first_wpilibj_hal_CompressorJNI_initializeCompressor( JNIEnv *env, jclass, jbyte module) { int32_t status = 0; auto handle = HAL_InitializeCompressor(module, &status); - if (status == PARAMETER_OUT_OF_RANGE) { - ThrowBoundaryException(env, module, 0, HAL_GetNumPCMModules()); - } + CheckStatusRange(env, 0, HAL_GetNumPCMModules(), module, status); return (jint)handle; } diff --git a/wpilibj/src/athena/cpp/lib/DIOJNI.cpp b/wpilibj/src/athena/cpp/lib/DIOJNI.cpp index 71993aa5c9..8b2e6b5686 100644 --- a/wpilibj/src/athena/cpp/lib/DIOJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/DIOJNI.cpp @@ -14,6 +14,8 @@ #include "HAL/DIO.h" #include "HAL/PWM.h" #include "HALUtil.h" +#include "HAL/Ports.h" +#include "HAL/handles/HandlesInternal.h" // set the logging level TLogLevel dioJNILogLevel = logWARNING; @@ -41,7 +43,8 @@ Java_edu_wpi_first_wpilibj_hal_DIOJNI_initializeDIOPort( auto dio = HAL_InitializeDIOPort((HAL_PortHandle)id, (uint8_t)input, &status); DIOJNI_LOG(logDEBUG) << "Status = " << status; DIOJNI_LOG(logDEBUG) << "DIO Handle = " << dio; - CheckStatus(env, status); + CheckStatusRange(env, 0, HAL_GetNumDigitalPins(), + hal::getPortHandlePin((HAL_PortHandle)id), status); return (jint)dio; } diff --git a/wpilibj/src/athena/cpp/lib/HALUtil.cpp b/wpilibj/src/athena/cpp/lib/HALUtil.cpp index 02350aeb86..8097c29ab9 100644 --- a/wpilibj/src/athena/cpp/lib/HALUtil.cpp +++ b/wpilibj/src/athena/cpp/lib/HALUtil.cpp @@ -120,10 +120,13 @@ static void GetStackTrace(JNIEnv *env, std::string &res, std::string &func) { env->DeleteLocalRef(stackTrace); } -void ThrowAllocationException(JNIEnv *env, int32_t status) { +void ThrowAllocationException(JNIEnv *env, int32_t minRange, int32_t maxRange, + int32_t requestedValue, int32_t status) { const char *message = HAL_GetErrorMessage(status); - char *buf = new char[strlen(message) + 30]; - sprintf(buf, " Code: $%d. %s", status, message); + char *buf = new char[strlen(message) + 100]; + sprintf(buf, + " Code: $%d. %s, Minimum Value: %d, Maximum Value: %d, Requested Value: %d", + status, message, minRange, maxRange, requestedValue); env->ThrowNew(allocationExCls, buf); delete[] buf; } @@ -136,11 +139,13 @@ void ThrowHalHandleException(JNIEnv *env, int32_t status) { delete[] buf; } -void ReportError(JNIEnv *env, int32_t status, bool do_throw) { +void ReportError(JNIEnv *env, int32_t status, int32_t minRange, int32_t maxRange, + int32_t requestedValue, bool do_throw) { if (status == 0) return; if (status == NO_AVAILABLE_RESOURCES || - status == RESOURCE_IS_ALLOCATED) { - ThrowAllocationException(env, status); + status == RESOURCE_IS_ALLOCATED || + status == RESOURCE_OUT_OF_RANGE) { + ThrowAllocationException(env, minRange, maxRange, requestedValue, status); } if (status == HAL_HANDLE_ERROR) { ThrowHalHandleException(env, status); diff --git a/wpilibj/src/athena/cpp/lib/HALUtil.h b/wpilibj/src/athena/cpp/lib/HALUtil.h index dfe83ab90d..b6447c19ed 100644 --- a/wpilibj/src/athena/cpp/lib/HALUtil.h +++ b/wpilibj/src/athena/cpp/lib/HALUtil.h @@ -14,10 +14,19 @@ extern JavaVM *jvm; -void ReportError(JNIEnv *env, int32_t status, bool do_throw = true); +void ReportError(JNIEnv *env, int32_t status, int32_t minRange, int32_t maxRange, + int32_t requestedValue, bool do_throw = true); inline bool CheckStatus(JNIEnv *env, int32_t status, bool do_throw = true) { - if (status != 0) ReportError(env, status, do_throw); + if (status != 0) ReportError(env, status, 0, 0, 0, do_throw); + return status == 0; +} + +inline bool CheckStatusRange(JNIEnv *env, int32_t status, int32_t minRange, + int32_t maxRange, int32_t requestedValue, + bool do_throw = true) { + if (status != 0) ReportError(env, status, minRange, maxRange, requestedValue, + do_throw); return status == 0; } diff --git a/wpilibj/src/athena/cpp/lib/PDPJNI.cpp b/wpilibj/src/athena/cpp/lib/PDPJNI.cpp index 548099ed98..c16cfdd1fe 100644 --- a/wpilibj/src/athena/cpp/lib/PDPJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/PDPJNI.cpp @@ -6,6 +6,7 @@ /*----------------------------------------------------------------------------*/ #include "HAL/PDP.h" +#include "HAL/Ports.h" #include "HALUtil.h" #include "edu_wpi_first_wpilibj_hal_PDPJNI.h" @@ -20,7 +21,7 @@ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_initializePDP( JNIEnv *env, jclass, jint module) { int32_t status = 0; HAL_InitializePDP(module, &status); - CheckStatus(env, status); + CheckStatusRange(env, 0, HAL_GetNumPDPModules(), module, status); } /* diff --git a/wpilibj/src/athena/cpp/lib/PWMJNI.cpp b/wpilibj/src/athena/cpp/lib/PWMJNI.cpp index 4f07c59f53..7f209952a4 100644 --- a/wpilibj/src/athena/cpp/lib/PWMJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/PWMJNI.cpp @@ -13,7 +13,9 @@ #include "HAL/DIO.h" #include "HAL/PWM.h" +#include "HAL/Ports.h" #include "HALUtil.h" +#include "HAL/handles/HandlesInternal.h" // set the logging level TLogLevel pwmJNILogLevel = logWARNING; @@ -40,7 +42,8 @@ Java_edu_wpi_first_wpilibj_hal_PWMJNI_initializePWMPort( auto pwm = HAL_InitializePWMPort((HAL_PortHandle)id, &status); PWMJNI_LOG(logDEBUG) << "Status = " << status; PWMJNI_LOG(logDEBUG) << "PWM Handle = " << pwm; - CheckStatus(env, status); + CheckStatusRange(env, 0, HAL_GetNumPWMPins(), + hal::getPortHandlePin((HAL_PortHandle)id), status); return (jint)pwm; } diff --git a/wpilibj/src/athena/cpp/lib/RelayJNI.cpp b/wpilibj/src/athena/cpp/lib/RelayJNI.cpp index ab94c30cf2..c36ce19624 100644 --- a/wpilibj/src/athena/cpp/lib/RelayJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/RelayJNI.cpp @@ -12,7 +12,9 @@ #include "edu_wpi_first_wpilibj_hal_RelayJNI.h" #include "HAL/Relay.h" +#include "HAL/Ports.h" #include "HALUtil.h" +#include "HAL/handles/HandlesInternal.h" // set the logging level TLogLevel relayJNILogLevel = logWARNING; @@ -39,6 +41,8 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_initializeRelayPo HAL_RelayHandle handle = HAL_InitializeRelayPort((HAL_PortHandle)id, (uint8_t) fwd, &status); RELAYJNI_LOG(logDEBUG) << "Status = " << status; RELAYJNI_LOG(logDEBUG) << "Relay Handle = " << handle; + CheckStatusRange(env, 0, HAL_GetNumRelayPins(), + hal::getPortHandlePin((HAL_PortHandle)id), status); return (jint) handle; } diff --git a/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp b/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp index 9fbb42e300..44d17827ae 100644 --- a/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp @@ -7,6 +7,7 @@ #include #include "HAL/HAL.h" +#include "HAL/handles/HandlesInternal.h" #include "Log.h" #include "edu_wpi_first_wpilibj_hal_SolenoidJNI.h" @@ -30,19 +31,21 @@ extern "C" { */ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_SolenoidJNI_initializeSolenoidPort( - JNIEnv *env, jclass, jint port_handle) { + JNIEnv *env, jclass, jint id) { SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort"; - SOLENOIDJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)port_handle; + SOLENOIDJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id; int32_t status = 0; HAL_SolenoidHandle handle = - HAL_InitializeSolenoidPort((HAL_PortHandle)port_handle, &status); + HAL_InitializeSolenoidPort((HAL_PortHandle)id, &status); SOLENOIDJNI_LOG(logDEBUG) << "Status = " << status; SOLENOIDJNI_LOG(logDEBUG) << "Solenoid Port Handle = " << handle; - CheckStatus(env, status); + // Use solenoid pins, as we have to pick one. + CheckStatusRange(env, 0, HAL_GetNumSolenoidPins(), + hal::getPortHandlePin((HAL_PortHandle)id), status);; return (jint)handle; }