From 489b993e607728177c7073e6c618671f8452a3d8 Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 11 Jun 2026 16:14:40 -0700 Subject: [PATCH] [hal,wpilib] Switch CANBusMap to Enum, use it for CAN API (#8977) Will make it easier to solve https://github.com/wpilibsuite/SystemcoreTesting/issues/286 --- .../org/wpilib/hardware/hal/CANBusMap.java | 37 ---------- .../main/native/include/wpi/hal/CANBusMap.h | 45 ------------ hal/src/test/native/cpp/can/CANTest.cpp | 5 +- wpilibc/robotpy_pybind_build_info.bzl | 8 +++ .../src/main/native/cpp/hardware/bus/CAN.cpp | 8 ++- .../native/include/wpi/hardware/bus/CAN.hpp | 5 +- .../include/wpi/hardware/bus/CANBusMap.hpp | 66 +++++++++++++++++ wpilibc/src/main/python/pyproject.toml | 1 + wpilibc/src/main/python/semiwrap/CAN.yml | 4 +- .../src/main/python/semiwrap/CANBusMap.yml | 2 + wpilibc/src/main/python/wpilib/__init__.py | 2 + .../java/org/wpilib/hardware/bus/CAN.java | 6 +- .../org/wpilib/hardware/bus/CANBusMap.java | 70 +++++++++++++++++++ 13 files changed, 165 insertions(+), 94 deletions(-) delete mode 100644 hal/src/main/java/org/wpilib/hardware/hal/CANBusMap.java delete mode 100644 hal/src/main/native/include/wpi/hal/CANBusMap.h create mode 100644 wpilibc/src/main/native/include/wpi/hardware/bus/CANBusMap.hpp create mode 100644 wpilibc/src/main/python/semiwrap/CANBusMap.yml create mode 100644 wpilibj/src/main/java/org/wpilib/hardware/bus/CANBusMap.java diff --git a/hal/src/main/java/org/wpilib/hardware/hal/CANBusMap.java b/hal/src/main/java/org/wpilib/hardware/hal/CANBusMap.java deleted file mode 100644 index baa41dd71f..0000000000 --- a/hal/src/main/java/org/wpilib/hardware/hal/CANBusMap.java +++ /dev/null @@ -1,37 +0,0 @@ -// 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. - -package org.wpilib.hardware.hal; - -public final class CANBusMap { - public static final int CAN_S0 = 0; - public static final int CAN_S1 = 1; - public static final int CAN_S2 = 2; - public static final int CAN_S3 = 3; - public static final int CAN_S4 = 4; - public static final int CAN_D0 = 5; - public static final int CAN_D1 = 6; - public static final int CAN_D2 = 7; - public static final int CAN_D3 = 8; - public static final int CAN_D4 = 9; - public static final int CAN_D5 = 10; - public static final int CAN_D6 = 11; - public static final int CAN_D7 = 12; - public static final int CAN_D8 = 13; - public static final int CAN_D9 = 14; - public static final int CAN_D10 = 15; - public static final int CAN_D11 = 16; - public static final int CAN_D12 = 17; - public static final int CAN_D13 = 18; - public static final int CAN_D14 = 19; - public static final int CAN_D15 = 20; - public static final int CAN_D16 = 21; - public static final int CAN_D17 = 22; - public static final int CAN_D18 = 23; - public static final int CAN_D19 = 24; - - private CANBusMap() { - throw new UnsupportedOperationException("This is a utility class!"); - } -} diff --git a/hal/src/main/native/include/wpi/hal/CANBusMap.h b/hal/src/main/native/include/wpi/hal/CANBusMap.h deleted file mode 100644 index e290a6bccf..0000000000 --- a/hal/src/main/native/include/wpi/hal/CANBusMap.h +++ /dev/null @@ -1,45 +0,0 @@ -// 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. - -#pragma once - -#include - -#include "wpi/hal/Types.h" - -/** - * @defgroup hal_canapi CAN BUS Mapping Enums - * @ingroup hal_capi - * @{ - */ - -HAL_ENUM(HAL_CANBusMap) { - HAL_CAN_BUS_S0 = 0, - HAL_CAN_BUS_S1 = 1, - HAL_CAN_BUS_S2 = 2, - HAL_CAN_BUS_S3 = 3, - HAL_CAN_BUS_S4 = 4, - HAL_CAN_BUS_D0 = 5, - HAL_CAN_BUS_D1 = 6, - HAL_CAN_BUS_D2 = 7, - HAL_CAN_BUS_D3 = 8, - HAL_CAN_BUS_D4 = 9, - HAL_CAN_BUS_D5 = 10, - HAL_CAN_BUS_D6 = 11, - HAL_CAN_BUS_D7 = 12, - HAL_CAN_BUS_D8 = 13, - HAL_CAN_BUS_D9 = 14, - HAL_CAN_BUS_D10 = 15, - HAL_CAN_BUS_D11 = 16, - HAL_CAN_BUS_D12 = 17, - HAL_CAN_BUS_D13 = 18, - HAL_CAN_BUS_D14 = 19, - HAL_CAN_BUS_D15 = 20, - HAL_CAN_BUS_D16 = 21, - HAL_CAN_BUS_D17 = 22, - HAL_CAN_BUS_D18 = 23, - HAL_CAN_BUS_D19 = 24, -}; - -/** @} */ diff --git a/hal/src/test/native/cpp/can/CANTest.cpp b/hal/src/test/native/cpp/can/CANTest.cpp index 05a234b05b..9901627555 100644 --- a/hal/src/test/native/cpp/can/CANTest.cpp +++ b/hal/src/test/native/cpp/can/CANTest.cpp @@ -8,10 +8,11 @@ #include #include "wpi/hal/CANAPI.h" -#include "wpi/hal/CANBusMap.h" #include "wpi/hal/simulation/CanData.h" namespace wpi::hal { +static constexpr int32_t kCANBusS0 = 0; + struct CANTestStore { CANTestStore(int32_t busId, int32_t deviceId, int32_t* status) { this->deviceId = deviceId; @@ -45,7 +46,7 @@ struct CANSendCallbackStore { TEST(CANTest, CanIdPacking) { int32_t status = 0; int32_t deviceId = 12; - CANTestStore testStore(HAL_CAN_BUS_S0, deviceId, &status); + CANTestStore testStore(kCANBusS0, deviceId, &status); ASSERT_EQ(0, status); std::pair storePair; diff --git a/wpilibc/robotpy_pybind_build_info.bzl b/wpilibc/robotpy_pybind_build_info.bzl index 25b9ce5555..5599718d67 100644 --- a/wpilibc/robotpy_pybind_build_info.bzl +++ b/wpilibc/robotpy_pybind_build_info.bzl @@ -414,6 +414,14 @@ def wpilib_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ ("wpi::CAN", "wpi__CAN.hpp"), ], ), + struct( + class_name = "CANBusMap", + yml_file = "semiwrap/CANBusMap.yml", + header_root = "$(execpath :robotpy-native-wpilib.copy_headers)", + header_file = "$(execpath :robotpy-native-wpilib.copy_headers)/wpi/hardware/bus/CANBusMap.hpp", + tmpl_class_names = [], + trampolines = [], + ), struct( class_name = "I2C", yml_file = "semiwrap/I2C.yml", diff --git a/wpilibc/src/main/native/cpp/hardware/bus/CAN.cpp b/wpilibc/src/main/native/cpp/hardware/bus/CAN.cpp index ed82e09247..1c019104ae 100644 --- a/wpilibc/src/main/native/cpp/hardware/bus/CAN.cpp +++ b/wpilibc/src/main/native/cpp/hardware/bus/CAN.cpp @@ -12,13 +12,15 @@ using namespace wpi; -CAN::CAN(int busId, int deviceId) +CAN::CAN(CANBusMap busId, int deviceId) : CAN{busId, deviceId, TEAM_MANUFACTURER, TEAM_DEVICE_TYPE} {} -CAN::CAN(int busId, int deviceId, int deviceManufacturer, int deviceType) { +CAN::CAN(CANBusMap busId, int deviceId, int deviceManufacturer, + int deviceType) { int32_t status = 0; m_handle = HAL_InitializeCAN( - busId, static_cast(deviceManufacturer), deviceId, + static_cast(busId), + static_cast(deviceManufacturer), deviceId, static_cast(deviceType), &status); WPILIB_CheckErrorStatus(status, "device id {} mfg {} type {}", deviceId, deviceManufacturer, deviceType); diff --git a/wpilibc/src/main/native/include/wpi/hardware/bus/CAN.hpp b/wpilibc/src/main/native/include/wpi/hardware/bus/CAN.hpp index 061fc90248..a2cff75219 100644 --- a/wpilibc/src/main/native/include/wpi/hardware/bus/CAN.hpp +++ b/wpilibc/src/main/native/include/wpi/hardware/bus/CAN.hpp @@ -7,6 +7,7 @@ #include #include "wpi/hal/CANAPI.h" +#include "wpi/hardware/bus/CANBusMap.hpp" #include "wpi/util/Handle.hpp" namespace wpi { @@ -31,7 +32,7 @@ class CAN { * @param busId The bus id * @param deviceId The device id */ - CAN(int busId, int deviceId); + CAN(CANBusMap busId, int deviceId); /** * Create a new CAN communication interface with a specific device ID, @@ -43,7 +44,7 @@ class CAN { * @param deviceManufacturer The device manufacturer * @param deviceType The device type */ - CAN(int busId, int deviceId, int deviceManufacturer, int deviceType); + CAN(CANBusMap busId, int deviceId, int deviceManufacturer, int deviceType); CAN(CAN&&) = default; CAN& operator=(CAN&&) = default; diff --git a/wpilibc/src/main/native/include/wpi/hardware/bus/CANBusMap.hpp b/wpilibc/src/main/native/include/wpi/hardware/bus/CANBusMap.hpp new file mode 100644 index 0000000000..b90100e36a --- /dev/null +++ b/wpilibc/src/main/native/include/wpi/hardware/bus/CANBusMap.hpp @@ -0,0 +1,66 @@ +// 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. + +#pragma once + +namespace wpi { + +/** + * CAN bus mapping. + * + * S0-S4 are Systemcore CAN buses. D0-D19 are Motioncore CAN buses. + */ +enum class CANBusMap { + /// CAN bus S0. + CAN_S0 = 0, + /// CAN bus S1. + CAN_S1 = 1, + /// CAN bus S2. + CAN_S2 = 2, + /// CAN bus S3. + CAN_S3 = 3, + /// CAN bus S4. + CAN_S4 = 4, + /// CAN bus D0. + CAN_D0 = 5, + /// CAN bus D1. + CAN_D1 = 6, + /// CAN bus D2. + CAN_D2 = 7, + /// CAN bus D3. + CAN_D3 = 8, + /// CAN bus D4. + CAN_D4 = 9, + /// CAN bus D5. + CAN_D5 = 10, + /// CAN bus D6. + CAN_D6 = 11, + /// CAN bus D7. + CAN_D7 = 12, + /// CAN bus D8. + CAN_D8 = 13, + /// CAN bus D9. + CAN_D9 = 14, + /// CAN bus D10. + CAN_D10 = 15, + /// CAN bus D11. + CAN_D11 = 16, + /// CAN bus D12. + CAN_D12 = 17, + /// CAN bus D13. + CAN_D13 = 18, + /// CAN bus D14. + CAN_D14 = 19, + /// CAN bus D15. + CAN_D15 = 20, + /// CAN bus D16. + CAN_D16 = 21, + /// CAN bus D17. + CAN_D17 = 22, + /// CAN bus D18. + CAN_D18 = 23, + /// CAN bus D19. + CAN_D19 = 24, +}; +} // namespace wpi diff --git a/wpilibc/src/main/python/pyproject.toml b/wpilibc/src/main/python/pyproject.toml index 25e328f705..1296443042 100644 --- a/wpilibc/src/main/python/pyproject.toml +++ b/wpilibc/src/main/python/pyproject.toml @@ -146,6 +146,7 @@ AnalogAccelerometer = "wpi/hardware/accelerometer/AnalogAccelerometer.hpp" # wpi/hardware/bus CAN = "wpi/hardware/bus/CAN.hpp" +CANBusMap = "wpi/hardware/bus/CANBusMap.hpp" I2C = "wpi/hardware/bus/I2C.hpp" SerialPort = "wpi/hardware/bus/SerialPort.hpp" diff --git a/wpilibc/src/main/python/semiwrap/CAN.yml b/wpilibc/src/main/python/semiwrap/CAN.yml index 7b9ee8c477..3ee3973d1b 100644 --- a/wpilibc/src/main/python/semiwrap/CAN.yml +++ b/wpilibc/src/main/python/semiwrap/CAN.yml @@ -6,8 +6,8 @@ classes: methods: CAN: overloads: - int, int: - int, int, int, int: + CANBusMap, int: + CANBusMap, int, int, int: WritePacket: WritePacketNoError: WritePacketRepeating: diff --git a/wpilibc/src/main/python/semiwrap/CANBusMap.yml b/wpilibc/src/main/python/semiwrap/CANBusMap.yml new file mode 100644 index 0000000000..8dce9c459e --- /dev/null +++ b/wpilibc/src/main/python/semiwrap/CANBusMap.yml @@ -0,0 +1,2 @@ +enums: + CANBusMap: diff --git a/wpilibc/src/main/python/wpilib/__init__.py b/wpilibc/src/main/python/wpilib/__init__.py index 9eea4d9da9..6a083d1ea8 100644 --- a/wpilibc/src/main/python/wpilib/__init__.py +++ b/wpilibc/src/main/python/wpilib/__init__.py @@ -13,6 +13,7 @@ from ._wpilib import ( AnalogPotentiometer, BooleanEvent, CAN, + CANBusMap, CANStatus, Compressor, CompressorConfigType, @@ -129,6 +130,7 @@ __all__ = [ "AnalogPotentiometer", "BooleanEvent", "CAN", + "CANBusMap", "CANStatus", "Compressor", "CompressorConfigType", diff --git a/wpilibj/src/main/java/org/wpilib/hardware/bus/CAN.java b/wpilibj/src/main/java/org/wpilib/hardware/bus/CAN.java index 2351013716..5f7075e7ef 100644 --- a/wpilibj/src/main/java/org/wpilib/hardware/bus/CAN.java +++ b/wpilibj/src/main/java/org/wpilib/hardware/bus/CAN.java @@ -36,7 +36,7 @@ public class CAN implements Closeable { * @param busId The bus ID * @param deviceId The device id */ - public CAN(int busId, int deviceId) { + public CAN(CANBusMap busId, int deviceId) { this(busId, deviceId, TEAM_MANUFACTURER, TEAM_DEVICE_TYPE); } @@ -49,8 +49,8 @@ public class CAN implements Closeable { * @param deviceManufacturer The device manufacturer * @param deviceType The device type */ - public CAN(int busId, int deviceId, int deviceManufacturer, int deviceType) { - m_handle = CANAPIJNI.initializeCAN(busId, deviceManufacturer, deviceId, deviceType); + public CAN(CANBusMap busId, int deviceId, int deviceManufacturer, int deviceType) { + m_handle = CANAPIJNI.initializeCAN(busId.value, deviceManufacturer, deviceId, deviceType); HAL.reportUsage("CAN[" + deviceType + "][" + deviceManufacturer + "][" + deviceId + "]", ""); } diff --git a/wpilibj/src/main/java/org/wpilib/hardware/bus/CANBusMap.java b/wpilibj/src/main/java/org/wpilib/hardware/bus/CANBusMap.java new file mode 100644 index 0000000000..ccea903cc7 --- /dev/null +++ b/wpilibj/src/main/java/org/wpilib/hardware/bus/CANBusMap.java @@ -0,0 +1,70 @@ +// 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. + +package org.wpilib.hardware.bus; + +/** + * CAN bus mapping. + * + *

S0-S4 are Systemcore CAN buses. D0-D19 are Motioncore CAN buses. + */ +public enum CANBusMap { + /** CAN bus S0. */ + CAN_S0(0), + /** CAN bus S1. */ + CAN_S1(1), + /** CAN bus S2. */ + CAN_S2(2), + /** CAN bus S3. */ + CAN_S3(3), + /** CAN bus S4. */ + CAN_S4(4), + /** CAN bus D0. */ + CAN_D0(5), + /** CAN bus D1. */ + CAN_D1(6), + /** CAN bus D2. */ + CAN_D2(7), + /** CAN bus D3. */ + CAN_D3(8), + /** CAN bus D4. */ + CAN_D4(9), + /** CAN bus D5. */ + CAN_D5(10), + /** CAN bus D6. */ + CAN_D6(11), + /** CAN bus D7. */ + CAN_D7(12), + /** CAN bus D8. */ + CAN_D8(13), + /** CAN bus D9. */ + CAN_D9(14), + /** CAN bus D10. */ + CAN_D10(15), + /** CAN bus D11. */ + CAN_D11(16), + /** CAN bus D12. */ + CAN_D12(17), + /** CAN bus D13. */ + CAN_D13(18), + /** CAN bus D14. */ + CAN_D14(19), + /** CAN bus D15. */ + CAN_D15(20), + /** CAN bus D16. */ + CAN_D16(21), + /** CAN bus D17. */ + CAN_D17(22), + /** CAN bus D18. */ + CAN_D18(23), + /** CAN bus D19. */ + CAN_D19(24); + + /** CAN bus ID. */ + public final int value; + + CANBusMap(int value) { + this.value = value; + } +}