diff --git a/crossConnIntegrationTests/src/main/native/cpp/AnalogTests.cpp b/crossConnIntegrationTests/src/main/native/cpp/AnalogTests.cpp new file mode 100644 index 0000000000..cbb85df352 --- /dev/null +++ b/crossConnIntegrationTests/src/main/native/cpp/AnalogTests.cpp @@ -0,0 +1,112 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include +#include +#include + +#include "CrossConnects.h" +#include "LifetimeWrappers.h" +#include "gtest/gtest.h" + +using namespace hlt; + +class AnalogCrossTest : public ::testing::TestWithParam> {}; + +TEST_P(AnalogCrossTest, TestAnalogCross) { + auto param = GetParam(); + + int32_t status = 0; + AnalogInputHandle input{param.first, &status}; + ASSERT_EQ(0, status); + AnalogOutputHandle output{param.second, &status}; + ASSERT_EQ(0, status); + + for (double i = 0; i < 5; i += 0.1) { + HAL_SetAnalogOutput(output, i, &status); + ASSERT_EQ(0, status); + usleep(1000); + ASSERT_NEAR(i, HAL_GetAnalogVoltage(input, &status), 0.01); + ASSERT_EQ(0, status); + } + + for (double i = 5; i > 0; i -= 0.1) { + HAL_SetAnalogOutput(output, i, &status); + ASSERT_EQ(0, status); + usleep(1000); + ASSERT_NEAR(i, HAL_GetAnalogVoltage(input, &status), 0.01); + ASSERT_EQ(0, status); + } +} + +TEST(AnalogInputTest, TestAllocateAll) { + wpi::SmallVector analogHandles; + for (int i = 0; i < HAL_GetNumAnalogInputs(); i++) { + int32_t status = 0; + analogHandles.emplace_back(AnalogInputHandle(i, &status)); + ASSERT_EQ(status, 0); + } +} + +TEST(AnalogInputTest, TestMultipleAllocateFails) { + int32_t status = 0; + AnalogInputHandle handle(0, &status); + ASSERT_NE(handle, HAL_kInvalidHandle); + ASSERT_EQ(status, 0); + + AnalogInputHandle handle2(0, &status); + ASSERT_EQ(handle2, HAL_kInvalidHandle); + ASSERT_LAST_ERROR_STATUS(status, RESOURCE_IS_ALLOCATED); +} + +TEST(AnalogInputTest, TestOverAllocateFails) { + int32_t status = 0; + AnalogInputHandle handle(HAL_GetNumAnalogInputs(), &status); + ASSERT_EQ(handle, HAL_kInvalidHandle); + ASSERT_LAST_ERROR_STATUS(status, RESOURCE_OUT_OF_RANGE); +} + +TEST(AnalogInputTest, TestUnderAllocateFails) { + int32_t status = 0; + AnalogInputHandle handle(-1, &status); + ASSERT_EQ(handle, HAL_kInvalidHandle); + ASSERT_LAST_ERROR_STATUS(status, RESOURCE_OUT_OF_RANGE); +} + +TEST(AnalogOutputTest, TestAllocateAll) { + wpi::SmallVector analogHandles; + for (int i = 0; i < HAL_GetNumAnalogOutputs(); i++) { + int32_t status = 0; + analogHandles.emplace_back(AnalogOutputHandle(i, &status)); + ASSERT_EQ(status, 0); + } +} + +TEST(AnalogOutputTest, TestMultipleAllocateFails) { + int32_t status = 0; + AnalogOutputHandle handle(0, &status); + ASSERT_NE(handle, HAL_kInvalidHandle); + ASSERT_EQ(status, 0); + + AnalogOutputHandle handle2(0, &status); + ASSERT_EQ(handle2, HAL_kInvalidHandle); + ASSERT_LAST_ERROR_STATUS(status, RESOURCE_IS_ALLOCATED); +} + +TEST(AnalogOutputTest, TestOverAllocateFails) { + int32_t status = 0; + AnalogOutputHandle handle(HAL_GetNumAnalogOutputs(), &status); + ASSERT_EQ(handle, HAL_kInvalidHandle); + ASSERT_LAST_ERROR_STATUS(status, RESOURCE_OUT_OF_RANGE); +} + +TEST(AnalogOutputTest, TestUnderAllocateFails) { + int32_t status = 0; + AnalogOutputHandle handle(-1, &status); + ASSERT_EQ(handle, HAL_kInvalidHandle); + ASSERT_LAST_ERROR_STATUS(status, RESOURCE_OUT_OF_RANGE); +} + +INSTANTIATE_TEST_SUITE_P(AnalogCrossConnectsTest, AnalogCrossTest, + ::testing::ValuesIn(AnalogCrossConnects)); diff --git a/crossConnIntegrationTests/src/main/native/cpp/RelayAnalogTests.cpp b/crossConnIntegrationTests/src/main/native/cpp/RelayAnalogTests.cpp new file mode 100644 index 0000000000..bed92eec36 --- /dev/null +++ b/crossConnIntegrationTests/src/main/native/cpp/RelayAnalogTests.cpp @@ -0,0 +1,50 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include +#include +#include + +#include "CrossConnects.h" +#include "LifetimeWrappers.h" +#include "gtest/gtest.h" + +using namespace hlt; + +class RelayAnalogTest : public ::testing::TestWithParam> {}; + +TEST_P(RelayAnalogTest, TestRelayAnalogCross) { + auto param = GetParam(); + + int32_t status = 0; + RelayHandle relay{param.first, true, &status}; + ASSERT_EQ(0, status); + AnalogInputHandle analog{param.second, &status}; + ASSERT_EQ(0, status); + AnalogTriggerHandle trigger{analog, &status}; + ASSERT_EQ(0, status); + HAL_SetAnalogTriggerLimitsVoltage(trigger, 1.5, 3.0, &status); + ASSERT_EQ(0, status); + + HAL_SetRelay(relay, false, &status); + ASSERT_EQ(0, status); + usleep(1000); + ASSERT_FALSE(HAL_GetAnalogTriggerTriggerState(trigger, &status)); + ASSERT_EQ(0, status); + + HAL_SetRelay(relay, true, &status); + ASSERT_EQ(0, status); + usleep(1000); + ASSERT_TRUE(HAL_GetAnalogTriggerTriggerState(trigger, &status)); + ASSERT_EQ(0, status); + + HAL_SetRelay(relay, false, &status); + ASSERT_EQ(0, status); + usleep(1000); + ASSERT_FALSE(HAL_GetAnalogTriggerTriggerState(trigger, &status)); + ASSERT_EQ(0, status); +} + +INSTANTIATE_TEST_SUITE_P(RelayAnalogCrossConnectsTest, RelayAnalogTest, + ::testing::ValuesIn(RelayAnalogCrossConnects)); diff --git a/crossConnIntegrationTests/src/main/native/include/CrossConnects.h b/crossConnIntegrationTests/src/main/native/include/CrossConnects.h index 957b4b6ee5..f77a8f20c6 100644 --- a/crossConnIntegrationTests/src/main/native/include/CrossConnects.h +++ b/crossConnIntegrationTests/src/main/native/include/CrossConnects.h @@ -55,4 +55,8 @@ struct RelayCross { constexpr static std::array RelayCrossConnects{ RelayCross{0, 23, 22}}; +// input on left +constexpr static std::array, 2> AnalogCrossConnects{ + std::pair{2, 0}, std::pair{4, 1}}; + } // namespace hlt diff --git a/crossConnIntegrationTests/src/main/native/include/LifetimeWrappers.h b/crossConnIntegrationTests/src/main/native/include/LifetimeWrappers.h index 5f0954d10a..199d8614b0 100644 --- a/crossConnIntegrationTests/src/main/native/include/LifetimeWrappers.h +++ b/crossConnIntegrationTests/src/main/native/include/LifetimeWrappers.h @@ -45,6 +45,66 @@ struct DMAHandle { HAL_DMAHandle handle = 0; }; +struct AnalogInputHandle { + public: + AnalogInputHandle(int32_t port, int32_t* status) { + handle = HAL_InitializeAnalogInputPort(HAL_GetPort(port), nullptr, status); + } + AnalogInputHandle(const AnalogInputHandle&) = delete; + AnalogInputHandle operator=(const AnalogInputHandle&) = delete; + + AnalogInputHandle(AnalogInputHandle&&) = default; + AnalogInputHandle& operator=(AnalogInputHandle&&) = default; + + ~AnalogInputHandle() { HAL_FreeAnalogInputPort(handle); } + + operator HAL_AnalogInputHandle() const { return handle; } + + private: + HAL_AnalogInputHandle handle = 0; +}; + +struct AnalogOutputHandle { + public: + AnalogOutputHandle(int32_t port, int32_t* status) { + handle = HAL_InitializeAnalogOutputPort(HAL_GetPort(port), nullptr, status); + } + AnalogOutputHandle(const AnalogOutputHandle&) = delete; + AnalogOutputHandle operator=(const AnalogOutputHandle&) = delete; + + AnalogOutputHandle(AnalogOutputHandle&&) = default; + AnalogOutputHandle& operator=(AnalogOutputHandle&&) = default; + + ~AnalogOutputHandle() { HAL_FreeAnalogOutputPort(handle); } + + operator HAL_AnalogOutputHandle() const { return handle; } + + private: + HAL_AnalogOutputHandle handle = 0; +}; + +struct AnalogTriggerHandle { + public: + explicit AnalogTriggerHandle(HAL_AnalogInputHandle port, int32_t* status) { + handle = HAL_InitializeAnalogTrigger(port, status); + } + AnalogTriggerHandle(const AnalogTriggerHandle&) = delete; + AnalogTriggerHandle operator=(const AnalogTriggerHandle&) = delete; + + AnalogTriggerHandle(AnalogTriggerHandle&&) = default; + AnalogTriggerHandle& operator=(AnalogTriggerHandle&&) = default; + + ~AnalogTriggerHandle() { + int32_t status = 0; + HAL_CleanAnalogTrigger(handle, &status); + } + + operator HAL_AnalogTriggerHandle() const { return handle; } + + private: + HAL_AnalogTriggerHandle handle = 0; +}; + struct DIOHandle { public: DIOHandle() {}