Squashed 'third_party/allwpilib/' changes from e4b91005cf..83f1860047
83f1860047 [wpilib] Add/update documentation to PneumaticBase and subclasses (NFC) (#4881)
9872e676d8 [commands] Make Subsystem destructor virtual (#4892)
25db20e49d [hal] Fix segfault in various HAL functions (#4891)
b0c6724eed [glass] Add hamburger menu icon to titlebars (#4874)
f0fa8205ac Add missing compiler flags and fix warnings (#4889)
42fc4cb6bc [wpiutil] SafeThread: Provide start/stop hooks (#4880)
cc166c98d2 [templates] Add Command-based skeleton template (#4861)
3f51f10ad3 [build] Update to 2023v3 image (#4886)
1562eae74a [ntcore] Refactor meta-topic decoding from glass (#4809)
b632b288a3 Fix usages of std::min and std::max to be windows safe (#4887)
c11bd2720f [wpilibc] Add internal function to reset Shuffleboard instance (#4884)
f1151d375f [ntcore] Add method to get server time offset (#4847)
fe1b62647f [hal,wpilib] Update documentation for getComments (NFC) (#4879)
c49a45abbd [build] Fix examples linking in incorrect jni library (#4873)
bc3d01a721 [build] Add platform check to doxygen plugin (#4862)
bc473240ae Add Jetbrains Fleet folder to .gitignore (#4872)
2121bd5fb8 [wpimath] Remove RKF45 (#4870)
835f8470d6 [build] Fix roborio cross-compiler on arm hosts (#4864)
6cfe5de00d [ntcore] Don't deadlock server on early destroy (#4863)
2ac41f3edc [hal, wpilib] Add RobotController.getComments() (#4463)
26bdbf3d41 Java optimization and formatting fixes (#4857)
92149efa11 Spelling and grammar cleanups (#4849)
176fddeb4c [commands] Add functions to HID classes to allow use of axes as BooleanEvents/Triggers (#4762)
87a34af367 [templates] Add bindings to command-based template (#4838)
4534e75787 [examples] Remove redundant MotorControl example (#4837)
1cbebaa2f7 [commands] Remove final semicolon from test macro definition (#4859)
6efb9ee405 [commands] Add constructor for SwerveControllerCommand that takes a HolonomicDriveController (#4785)
1e7fcd5637 [cscore] Change run loop functions to not be mac specific (#4854)
1f940e2b60 [apriltag] Add C++ wrappers, rewrite Java/JNI to match (#4842)
a6d127aedf [build] Add missing task dependency in wpilibjExamples (#4852)
b893b3d6d3 [cscore] Add support for USB cameras on macOS (#4846)
1696a490fa [glass] Add support for alternate NT ports (#4848)
40a22d69bc [glass] Add support for alternate NT ports (#4848)
e84dbfede0 [wpilib] GenericHID: Add rumble both option (#4843)
8aa9dbfa90 [examples] Link apriltag package in examples build.gradle (#4845)
eda2fa8a17 [build] Update Spotless (#4840)
d20594db0d Fix typos (#4839)
dd8ecfdd54 [commands] Fix typo in waitUntil docs (NFC) (#4841)
17ceebfff4 [apriltag] Clean up apriltag JNI (#4823)
8b74ab389d [examples] RapidReactCommandBot: Fix array indices (#4833)
1aad3489c2 [sim] Implement PD total current and power (#4830)
2744991771 [wpimath] Fix docs in SwerveModulePosition (#4825)
ffbf6a1fa2 [commands] Disable regularly failing unit test (#4824)
fbabd0ef15 [commands] Enhance Command Sendable implementations (#4822)
7713f68772 [hal] Use atomic rather then mutex for DS Data updates (#4787)
701995d6cc [examples] Update Command-based starter project (#4778)
bf7068ac27 [wpilibc] Add missing PPS implementation for C++ (#4821)
aae0f52ca6 [ntcore] NetworkTable: fix visibility of get/set value (#4820)
ee02fb7ba7 [hal] Add support for Pulse-Per-Second signal (#4819)
518916ba02 [wpilib] Fix DS mode thread event being manual reset accidentally (#4818)
3997c6635b [hal] Update to new image, use new TCP notify callback and new duty cycle API (#4774)
cc8675a4e5 [examples] Add comment on how to view elevator sim (NFC) (#4482)
fb2c170b6e [ntcore] Simplify local startup (#4803)
7ba8a9ee1f [wpimath] ProfiledPIDController: Add to SendableRegistry (#4656)
c569d8e523 [wpilib] Joystick.getMagnitude(): use hypot() function (#4816)
2a5e89fa97 [apriltag] Improve description of pose coordinates (NFC) (#4810)
cc003c6c38 [apriltag] Fix AprilTagFieldLayout JSON name (#4814)
5522916123 [commands] CommandXBoxController bumper documentation fix (NFC) (#4815)
967b30de3a [glass] Fix NT view UpdateClients() bug (#4808)
3270d4fc86 [wpimath] Rewrite pose estimator docs (#4807)
be39678447 [apriltag] Add test to ensure apriltagjni loads (#4805)
61c75deb2a [commands] Test no-op behavior of scheduling a scheduled command (#4806)
a865f48e96 [ntcore] Pass pub/sub options as a unified PubSubOptions struct (#4794)
f66a667321 [commands] Fix incorrect Trigger docs (NFC) (#4792)
f8d4e9866e [ntcore] Clean up ntcore_test.h (#4804)
7e84ea891f [wpimath] Fix ComputerVisionUtil transform example in parameter docs (NFC) (#4800)
da3ec1be10 [wpimath] Change terminology for ArmFeedforward gravity gain (NFC) (#4791)
944dd7265d [wpilibc] Add C++ Notifier error handling, update java notifier error message (#4795)
6948cea67a [wpiutil] Fix MemoryBuffer initialization (#4797)
a31459bce6 [wpiutil] Fix UnescapeCString overflow when inputSize < 2 (#4796)
4a0ad6b48c [wpimath] Rotation2d: Add reference to angleModulus in docs (NFC) (#4786)
e6552d272e [ntcore] Remove table multi-subscriber (#4789)
bde383f763 [hal] Replace const char* with std::string_view in Driver Station sim functions (#4532)
5a52b51443 [hal] Add RobotController.getSerialNumber() (#4783)
69a66ec5ec [wpilib] Fix multiple motor safety issues (#4784)
989c9fb29a [wpimath] Revert Rotation2D change that limits angles (#4781)
0f5b08ec69 [wpigui] Update imgui to 1.89.1+ (#4780)
fba191099c [examples] AddressableLED: Add unit test (#4779)
b390cad095 [wpilibj] Consistently use ErrorMessages.requireNonNullParam (#4776)
b9772214d9 [wpilib] Sendable: Don't call setter for getter changes
342c375a71 [ntcore] Add subscriber option to exclude single publisher
b0e4053087 [ntcore] Use int for options instead of double
f3e666b7bb [cscore] Convert YUYV and UYVY directly to grayscale (#4777)
b300518bd1 [hal] Add CAN Stream API to Java through JNI bindings (#4193)
be27171236 [wpilibj] Shuffleboard: Check for null sendable (#4772)
4bbdbdfb48 [commands] Move GroupedCommands to CommandScheduler (#4728)
f18fd41ac3 [wpimath] Remove broken and obsoleted ComputerVisionUtil functions (#4775)
2d0faecf4f [glass] DataSource: Add spinlock to protect value (#4771)
348bd107fc [hal] Add CANManufacturer for The Thrifty Bot (#4773)
3149dc64b8 [examples] HatchbotInlined: Use Subsystem factories (#4765)
8618dd4160 [glass, wpilib] Replace remaining references to Speed Controller with Motor Controller (#4769)
72e21a1ed1 [apriltag] Use wpilibsuite fork of apriltag (#4764)
eab0d929e6 [commands] CommandGenericHID POV methods: Fix docs (NFC) (#4760)
6789869663 [wpilib] Call set(0) rather than disable for stopMotor (#4763)
c9dea2968d [cscore] Emit warning that USB Camera isn't supported on OSX (#4766)
8f402645f5 [commands] Fix PIDSubsystem setSetpoint behavior (#4759)
f24ad1d715 [build] Upgrade to googletest 1.12.1 (#4752)
ff88756864 [wpimath] Add new DCMotor functions for alternative calculations and reduction calculation (#4749)
f58873db8e [wpimath] Remove extra terms in matrix for pose estimator docs (#4756)
37e969b41a [wpimath] Add constructors to pose estimators with default standard deviations (#4754)
13cdc29382 [ci] Rename comment command from "/wpiformat" to "/format" (#4755)
6e23985ae6 [examples] Add main include directory to test builds (#4751)
66bb0ffb2c [examples] Add unit testing infrastructure (#4646)
74cc86c4c5 [wpimath] Make transform tests use pose/transform equality operators (#4675)
e22d8cc343 [wpimath] Use Odometry for internal state in Pose Estimation (#4668)
68dba92630 [ci] Update mac and windows builds to Java 17 (#4750)
23bfc2d9ab [sim] Remove unmaintained Gazebo support (#4736)
1f1461e254 [wpilib] Add method to enable/disable LiveWindow in test mode (#4678)
eae68fc165 [wpimath] Add tolerance for Rotation3d rotation matrix special orthogonality (#4744)
4c4545fb4b [apriltag] Suppress warning (#4743)
16ffaa754d [docs] Generate docs for apriltag subproject (#4745)
5e74ff26d8 [apriltag, build] Update native utils, add apriltag impl and JNI (#4733)
53875419a1 [hal] Allow overriding stderr printing by HAL_SendError (#4742)
aa6499e920 [ntcore] Fix special topic multi-subscriber handling (#4740)
df70351107 [build] Fix cmake install of thirdparty includes (#4741)
e9bd50ff9b [glass] NT view: clear meta-topic info on disconnect (#4732)
9b319fd56b [ntcore] Add sub option for local vs remote changes (#4731)
18d28ec5e3 [ntcore] Remove duplicate value checking from ClientImpl
bdfb625211 [ntcore] Send duplicate values to network if necessary
21003e34eb [commands] Update Subsystem factories and example to return CommandBase (#4729)
70080457d5 [commands] Refactor ProxyScheduleCommand, SelectCommand into ProxyCommand (#4534)
e82cd5147b [wpilib] Tweak Color HSV formula and use in AddressableLED (#4724)
ec124bb662 [commands] Allow unsetting a subsystem's default command (#4621)
2b2aa8eef7 [examples] Update all examples to use NWU coordinate conventions (#4725)
cb38bacfe8 [commands] Revert to original Trigger implementation (#4673)
15561338d5 [commands] Remove one more default command isFinished check (#4727)
ca35a2e097 Add simgui files to .gitignore (#4726)
20dbae0cee [examples] Renovate command-based examples (#4409)
1a59737f40 [commands] Add convenience factories (#4460)
42b6d4e3f7 Use defaulted comparison operators in C++ (#4723)
135c13958f [wpigui] Add FontAwesome (#4713)
ffbfc61532 [ntcore] Add NetworkTable table-specific listeners (#4640)
8958b2a4da [commands] Add property tests for command compositions (#4715)
e4ac09077c [wpilib] Add link to MotorSafety article (#4720)
f40de0c120 [commands] Add C++ factory templates (#4686)
51fa3e851f [build] cmake: Use FetchContent instead of ExternalProject (#4714)
1da84b2255 [wpigui] Reload fonts to scale rather than preloading (#4712)
e43e2fbc84 [wpiutil] StringExtras: Add UnescapeCString (#4707)
5804d8fa84 [ntcore] Server: Properly handle multiple subscribers (#4717)
169ef5fabf [glass] Update NT view for topicsOnly and sendAll changes (#4718)
148759ef54 [examples] CANPDP: Expand properties shown (#4687)
58ed112b51 [commands] RepeatCommand: restart on following iteration (#4706)
dd1da77d20 [readme] Fix broken CI badge (#4710)
7cda85df20 [build] Check Gradle plugin repo last to fix CI (#4711)
7ed9b13277 [build] Bump version plugin to fix null tag (#4705)
6b4f26225d [apriltag] Fix pluralization of apriltag artifacts (#4671)
b2d2924b72 [cscore] Add Y16 image support (#4702)
34ec89c041 [wpilibc] Shuffleboard SimpleWidget: Return pointer instead of reference (#4703)
e15200068d [ci] Disable HW testbench runs (#4704)
d5200db6cd [wpimath] Rename HolonomicDriveController.calculate params (#4683)
2ee3d86de4 [wpimath] Clarify Rotation3d roll-pitch-yaw direction (#4699)
9f0a8b930f [cscore] Use MFVideoFormat_L8 for Gray on Windows (#4701)
2bca43779e [cscore] Add UYVY image support (#4700)
4307d0ee8b [glass] Plot: allow for more than 11 plots (#4685)
3fe8d355a1 [examples] StateSpaceDifferentialDriveSimulation: Use encoder reversed constants (#4682)
b44034dadc [ntcore] Allow duplicate client IDs on server (#4676)
52d2c53888 [commands] Rename Java factory wait() to waitSeconds() (#4684)
76e918f71e [build] Fix JNI artifacts linking to incorrect libraries (#4680)
0bee875aff [commands] Change C++ CommandPtr to use CommandBase (#4677)
98e922313b [glass] Don't check IsConnected for NT widgets (#4674)
9a36373b8f [apriltag] Switch 2022 apriltag layout length and width values (#4670)
cf8faa9e67 [wpilib] Update values on controllable sendables (#4667)
5ec067c1f8 [ntcore] Implement keep duplicates pub/sub flag (#4666)
e962fd2916 [ntcore] Allow numeric-compatible value sets (#4620)
88bd67e7de [ci] Update clang repositories to jammy (#4665)
902e8686d3 [wpimath] Rework odometry APIs to improve feature parity (#4645)
e2d49181da Update to native utils 2023.8.0 (#4664)
149bac55b1 [cscore] Add Arducam OV9281 exposure quirk (#4663)
88f7a3ccb9 [wpimath] Fix Pose relativeTo documentation (#4661)
8acce443f0 [examples] Fix swerve examples to use getDistance for turning encoder (#4652)
295a1f8f3b [ntcore] Fix WaitForListenerQueue (#4662)
388e7a4265 [ntcore] Provide mechanism to reset internals of NT instance (#4653)
13aceea8dc [apriltag] Fix FieldDimensions argument order (#4659)
c203f3f0a9 [apriltag] Fix documentation for AprilTagFieldLayout (#4657)
f54d495c90 Fix non initialized hal functionality during motor safety init (#4658)
e6392a1570 [cmd] Change factories return type to CommandBase (#4655)
53904e7cf4 [apriltag] Split AprilTag functionality to a separate library (#4578)
2e88a496c2 [wpimath] Add support for swerve joystick normalization (#4516)
ce4c45df13 [wpimath] Rework function signatures for Pose Estimation / Odometry (#4642)
0401597d3b [readme] Add wpinet to MavenArtifacts.md (#4651)
2e5f9e45bb [wpimath] Remove encoder reset comments on Swerve, Mecanum Odometry and Pose Estimation (#4643)
e4b5795fc7 [docs] Disable Doxygen for memory to fix search (#4636)
03d0ea188c [build] cmake: Add missing wpinet to installed config file (#4637)
3082bd236b [build] Move version file to its own source set (#4638)
b7ca860417 [build] Use build cache for sign step (#4635)
64838e6367 [commands] Remove unsafe default command isFinished check (#4411)
1269d2b901 [myRobot] Disable spotbugs (#4565)
14d8506b72 [wpimath] Fix units docs for LinearSystemId::IdentifyDrivetrainSystem() (#4600)
d1d458db2b [wpimath] Constrain Rotation2d range to -pi to pi (#4611)
f656e99245 [readme] Add links to development build documentation (#4481)
6dd937cef7 [commands] Fix Trigger API docs (NFC) (#4599)
49047c85b9 [commands] Report error on C++ CommandPtr use-after-move (#4575)
d07267fed1 [ci] Upgrade containers to Ubuntu 22.04 and remove libclang installation (#4633)
b53ce1d3f0 [build, wpiutil] Switch macos to universal binaries (#4628)
5a320c326b [upstream_util, wpiutil] Refactor python scripts (#4614)
c4e526d315 [glass] Fix NT Mechanism2D (#4626)
d122e4254f [ci] Run spotlessApply after wpiformat in comment command (#4623)
5a1e7ea036 [wpilibj] FieldObject2d: Add null check to close() (#4619)
179f569113 [ntcore] Notify locally on SetDefault (#4617)
b0f6dc199d [wpilibc] ShuffleboardComponent.WithProperties: Update type (#4615)
7836f661cd [wpimath] Add missing open curly brace to units/base.h (#4613)
dbcc1de37f [wpimath] Add DifferentialDriveFeedforward classes which wrap LinearPlantInversionFeedforward (#4598)
93890c528b [wpimath] Add additional angular acceleration units (#4610)
3d8d5936f9 [wpimath] Add macro for disabling units fmt support (#4609)
2b04159dec [wpimath] Update units/base.h license header (#4608)
2764004fad [wpinet] Fix incorrect jni definitions (#4605)
85f1bb8f2b [wpiutil] Reenable jni check task (#4606)
231ae2c353 [glass] Plot: Fix Y-axis not being saved (#4594)
e92b6dd5f9 [wpilib] Fix AprilTagFieldLayout JSON property name typos (#4597)
2a8e0e1cc8 Update all dependencies that use grgit (#4596)
7d06e517e9 [commands] Move SelectCommand factory impl to header (#4581)
323524fed6 [wpimath] Remove deprecated units/units.h header (#4572)
d426873ed1 [commands] Add missing PS4 triangle methods (#4576)
5be5869b2f [apriltags] Use map as internal data model (#4577)
b1b4c1e9e7 [wpimath] Fix Pose3d transformBy rotation type (#4545)
a4054d702f [commands] Allow composing two triggers directly (#4580)
0190301e09 [wpilibc] Explicitly mark EventLoop as non-copyable/non-movable (#4579)
9d1ce6a6d9 [ntcore] Catch file open error when saving preferences (#4571)
5005e2ca04 [ntcore] Change Java event mask to EnumSet (#4564)
fa44a07938 [upstream-utils][mpack] Add upstream util for mpack (#4500)
4ba16db645 [ntcore] Various fixes and cleanups (#4544)
837415abfd [hal] Fix joysticks either crashing or returning 0 (#4570)
2c20fd0d09 [wpilib] SingleJointedArmSim: Check angle equals limit on wouldHit (#4567)
64a7136e08 [wpimath] SwerveDrivePoseEstimator: Restore comment about encoder reset (#4569)
b2b473b24a [wpilib] Add AprilTag and AprilTagFieldLayout (#4421)
7aab8fa93a [build] Update to Native Utils 2023.6.0 (#4563)
12c2851856 [commands] WrapperCommand: inherit from CommandBase (#4561)
0da169dd84 [wpimath] Remove template argument from ElevatorFeedforward (#4554)
2416827c25 [wpimath] Fix docs for pose estimator local measurement models (#4558)
1177a3522e [wpilib] Fix Xbox/PS4 POV sim for port number constructors (#4548)
102344e27a [commands] HID classes: Add missing methods, tweak return types (#4557)
1831ef3e19 [wpilib] Fix Shuffleboard SuppliedValueWidget (#4559)
a9606ce870 [wpilib] Fix Xbox/PS4 POV sim (#4546)
6c80d5eab3 [wpimath] Remove unused SymbolExports.h include from units/base.h (#4541)
b114006543 [ntcore] Unify listeners (#4536)
32fbfb7da6 [build] cmake: Install ntcore generated include files (#4540)
02465920fb [build] Update native utils to 2023.4.0 (#4539)
3a5a376465 [wpimath] Increase constexpr support in geometry data types (#4231)
1c3c86e9f1 [ntcore] Cache GetEntry(name) values (#4531)
dcda09f90a [command] Rename trigger methods (#4210)
66157397c1 [wpilib] Make drive classes follow NWU axes convention (#4079)
9e22ffbebf [ntcore] Fix null deref in NT3 client (#4530)
648ab6115c [wpigui,dlt,glass,ov] Support arm in GUI tools (#4527)
8bc3b04f5b [wpimath] Make ComputerVisionUtil use 3D geometry classes (#4528)
cfb84a6083 [wpilibc] Don't hang waiting for NT server to start (#4524)
02c47726e1 [wpimath] Remove unused odometry instance from DifferentialDrivePoseEstimator test (#4522)
b2a0093294 [ci] Revert upgrade of github-pages-deploy-action (#4521)
2a98d6b5d7 [wpimath] PIDController: Add getters for position & velocity tolerances (#4458)
9f36301dc8 [ci] Write wpiformat patch to job summary (#4519)
901fc555f4 [wpimath] Position Delta Odometry for Mecanum (#4514)
4170ec6107 [wpimath] Position Delta Odometry for Swerve (#4493)
fe400f68c5 [docs] Add wpinet to docs build (#4517)
794669b346 [ntcore] Revamp listeners (#4511)
dcfa85a5d5 [ci] Build sanitizers with clang-14 (#4518)
15ad855f1d [ntcore] Add UnitTopic<T> (C++ only) (#4497)
11244a49d9 [wpilib] Add IsConnected function to all gyros (#4465)
1d2e8eb153 [build] Update myRobot deployment (#4515)
ad53fb19b4 [hal] Use new HMB api for addressable LED (#4479)
ba850bac3b [hal] Add more shutdown checks and motor safety shutdown (#4510)
023a5989f8 [ntcore] Fix typo in NetworkServer client connect message (#4512)
c970011ccc [docs] Add Doxygen aliases used by Foonathan memory (#4509)
07a43c3d9a [readme] Document clang-format version and /wpiformat (#4503)
a05b212b04 [ci] Revert changes to wpiformat task from #4501 (#4508)
09faf31b67 [commands] Replace Command HID inheritance with delegation (#4470)
9e1f9c1133 [commands] Add command factories (#4476)
f19d2b9b84 [ci] Add NUMBER environment variable to comment command commit script (#4507)
a28f93863c [ci] Push comment command commit directly to PR (#4506)
c9f61669b8 [ci] Fix comment command commit push (#4505)
dcce5ad3b3 [ci] Update github-script API usage (#4504)
6836e5923d [wpilibc] Restore get duty cycle scale factor (#4502)
335188c652 [dlt] Add deselect/select all buttons to download view (#4499)
60a29dcb99 [glass] Field2D: Add "hidden" option for objects (#4498)
b55d5b3034 [ci] Update deprecated github actions (#4501)
10ed4b3969 [ntcore] Various NT4 fixes (#4474)
4a401b89d7 [hal, wpilib] New DS thread model and implementation (#3787)
c195b4fc46 [wpimath] Clean up PoseEstimator nominal dt docs (#4496)
8f2e34c6a3 [build] Remove wpilib prefix from CMake flat install (#4492)
150d692df7 [wpimath] Remove unused private PoseEstimator function (#4495)
3e5bfff1b5 [wpimath] FromFieldRelativeSpeeds: Add ChassisSpeeds overload (#4494)
9c7e66a27d [commands] C++: Add CommandPtr overload for SetDefaultCommand (#4488)
0ca274866b [build] Fix CMake system library opt-ins (#4487)
dc037f8d41 [commands] Remove EndlessCommand (#4483)
16cdc741cf [wpimath] Add Pose3d(Pose2d) constructor (#4485)
9d5055176d [build] cmake: Allow disabling ntcore build (#4486)
d1e66e1296 [build] Compile all java code with inline string concatenation (#4490)
1fc098e696 Enable log macros to work with no args (#4475)
878cc8defb [wpilib] LiveWindow: Add enableAllTelemetry() (#4480)
8153911160 [build] Fix MSVC runtime archiver to grab default runtime (#4478)
fbdc810887 Upgrade to C++20 (#4239)
396143004c [ntcore] Add ntcoreffi binary (#4471)
1f45732700 [build] Update to 2023.2.4 native-utils and new dependencies (#4473)
574cb41c18 [ntcore] Various fixes (#4469)
d9d6c425e7 [build] Force Java 11 source compatibility (#4472)
58b6484dbe Switch away from NI interrupt manager to custom implementation (#3705)
ca43fe2798 [wpimath] Use Units conversions in ComputerVisionUtil docs (NFC) (#4464)
87a64ccedc [hal] Convert DutyCycle Raw output to be a high time measurement (#4466)
89a3d00297 [commands] Add FinallyDo and HandleInterrupt decorators (#4412)
1497665f96 [commands] Add C++ versions of Java-only decorators (#4457)
27b173374e [wpimath] Add minLinearAccel parameter to DifferentialDriveAccelerationLimiter (#4422)
2a13dba8ac [wpilib] TrajectoryUtil: Fix ambiguous documentation (NFC) (#4461)
77301b126c [ntcore] NetworkTables 4 (#3217)
90cfa00115 [build] cmake: Fix libssh include directory order (#4459)
5cf961edb9 [commands] Refactor lambda-based commands to inherit FunctionalCommand (#4451)
b2276e47de [wpimath] Enable continuous angle input for HolonomicDriveController (#4453)
893b46139a [fieldImages] Add utilities to simplify loading of fields (#4456)
60e29627c0 [commands] C++ unique_ptr migration (#4319)
3b81cf6c35 [wpilib] Improve Color.toString (#4450)
5c067d30a0 [wpinet] WebSocket: Add SendFrames() (#4445)
ceaf493811 [wpiutil] MakeJByteArray: Use span<uint8> instead of string_view (#4446)
10e04e2b13 [examples] FrisbeeBot: Fix reference capture (#4449)
726f67c64b [build] Add exeSplitSetup (#4444)
c7b7624c1c [wpiutil] Add MessagePack utility functions (#4448)
d600529ec0 [wpinet] uv::Async: Add UnsafeSend() (#4447)
b53b3526a2 [wpimath] Add CoordinateSystem conversion for Transform3d (#4443)
38bb23eb18 [wpimath] Add scalar multiply and divide operators to all geometry classes (#4438)
3937ff8221 [wpilib] Remove deprecated Controller class (#4440)
abbfe244b5 [wpilib] Improve Color FromHSV (#4439)
4ddb8aa0dd [sim] Provide function that resets all simulation data (#4016)
a791470de7 Clean up Java warning suppressions (#4433)
17f504f548 [hal,wpilib] Fix SPI Mode Setting (#4434)
773198537c [wpiutil] Add wpi::scope_exit (#4432)
5ac658c8f0 [wpiutil] Logger: Conditionalize around WPI_LOG (#4431)
8767e4a941 [wpiutil] DataLog: Fix SetMetadata output (#4430)
8c4af073f4 [wpiutil] Synchronization: shutdown race protection (#4429)
c79f38584a [build] Fix Java integration tests (#4428)
36c08dd97c [build] Fix cmake install of fmtlib (#4426)
69b7b3dd7d [ci] Remove the Windows cmake job (#4425)
738c75fed8 [readme] Fix formatting/linting link (#4423)
4eb1d03fb3 [wpimath] Document C++ LinearFilter exception (#4417)
ba4ec6c967 [build] Fix clang-tidy false positive on Linux (#4406)
97836f0e55 [commands] Fix ProfiledPIDSubsystem setGoal behavior (#4414)
fdfb85f695 [wpimath] Remove Java LQR constructor that takes a controller gain matrix (#4419)
ab1baf4832 [wpimath] Add rotation matrix constructor to Rotation3d (#4413)
9730032866 [wpimath] Document LQR and KalmanFilter exceptions (#4418)
5b656eecf6 [wpimath] Fix HTML5 entity (#4420)
9ae38eaa7c [commands] Add owning overload to ProxyScheduleCommand (#4405)
cb33bd71df [commands] deprecate withInterrupt decorator (#4407)
d9b4e7b8bf [commands] Revert "Change grouping decorator impl to flatten nested group structures (#3335)" (#4402)
0389bf5214 [hal] REVPH: Improve handling of disconnected CAN Bus (#4169)
4267fa08d1 [wpilibc] ADIS IMUs: Fix memory leak (#4170)
65c8fbd452 [wpilib] MotorControllerGroup: Override setVoltage (#4403)
f36162fddc [wpimath] Improve Discretization internal docs (#4400)
5149f7d894 [wpimath] Add two-vector Rotation3d constructor (#4398)
20b5bed1cb [wpimath] Clean up Java Quaternion class (#4399)
f18dd1905d [build] Include all thirdparty sources in distribution (#4397)
aa9d7f1cdc [wpiutil] Import foonathan memory (#4306)
2742662254 [ci] Remove a couple of obsolete clang-tidy checks (#4396)
a5df391166 [hal, wpilib] Fix up DIO pulse API (#4387)
59e6706b75 [glass] Turn on docking by default
8461bb1e03 [glass] Add support for saving docking info
b873e208b4 [wpigui] Add support for imgui config flags
873e72df8c [build] Update imgui to 1.88 docking branch
c8bd6fc5b4 [ci] Fix comment-command (take 2) (#4395)
fed68b83b4 [ci] Fix comment-command action not running runners (#4393)
0ef8a4e1df [wpimath] Support formatting more Eigen types (#4391)
c393b3b367 [build] Update to native utils 2023.1.0 and Gradle 7.5.1 (#4392)
b5a17f762c [wpimath] Add direction to slew rate limiter (#4377)
fafc81ed1a [wpiutil] Upgrade to fmt 9.1.0 (#4389)
cc56bdc787 [wpiutil] SafeThread: Add Synchronization object variant (#4382)
4254438d8d [commands] Mark command group lifecycle methods as final (#4385)
97c15af238 [wpimath] LinearSystemId: Fix docs, move C++ impls out of header (#4388)
d22ff8a158 [wpiutil] Add JNI access to C++ stderr (#4381)
fdb5a2791f [wpiutil] jni_util: Add Mac-friendly MakeJLongArray/JArrayRef (#4383)
c3a93fb995 [commands] Revamp Interruptible (#4192)
f2a8d38d2a [commands] Rename Command.repeat to repeatedly (#4379)
9e24c6eac0 [wpiutil] Logger: paren-protect instance usage in macro (#4384)
fe4d12ce22 [wpimath] Add LTV controller derivations and make enums private (#4380)
eb08486039 [build] Fix MacOS binary rpath generation (#4376)
ccf83c634a [build] Use native-utils platform names instead of raw strings (#4375)
3fd69749e7 [docs] Upgrade to doxygen 1.9.4 (#4370)
594df5fc08 [wpinet] uv/util.h: Pull in ws2_32.lib on Windows for ntohs (#4371)
539070820d [ci] Enable asan for wpinet and wpiutil (#4369)
564a56d99b [wpinet] Fix memory leak in WorkerThreadTest (#4368)
5adf50d93c [upstream_utils] Refactor upstream_utils scripts (#4367)
d80e8039d7 [wpiutil] Suppress fmtlib clang-tidy warning in C++20 consteval contexts (#4364)
0e6d67b23b [upstream_utils] Remove yapf format disable comment (#4366)
be5270697a [build] Suppress enum-enum deprecation warning in OpenCV (#4365)
8d28851263 Add Rosetta install command to build requirements (#4363)
3d2115c93e [wpinet] include-what-you-use in MulticastTest (#4360)
91002ae3cc [wpimath] Upgrade to Drake 1.6.0 (#4361)
148c18e658 [wpinet] Upgrade to libuv 1.44.2 (#4362)
a2a5c926b6 Fix clang-tidy warnings (#4359)
ea6b1d8449 [wpiutil] Remove unused ManagedStatic class (#4358)
ac9be78e27 Use stricter C++ type conversions (#4357)
151dabb2af [wpiutil] Upgrade to fmt 9.0.0 (#4337)
340465c929 [ci] Upgrade to clang-format and clang-tidy 14 (NFC) (#4347)
d45bcddd15 [examples] Add comments to StateSpaceDifferentialDrive (#4341)
0e0786331a Update LLVM libraries to 14.0.6 (#4350)
c5db23f296 [wpimath] Add Eigen sparse matrix and iterative solver support (#4349)
44abc8dfa6 [upstream_utils] Remove git version from upstream patches (#4351)
3fdb2f767d [wpimath] Add comments with Ramsete equations (#4348)
0485f05da9 [wpilibjExamples] Upgrade jacoco to match allwpilib (#4346)
0a5eb65231 [wpinet] Handle empty txt block for mdns announcer (#4072)
19ffebaf3e [wpilib] Add reference to I2C Lockup to API Docs (NFC) (#4340)
ce1a90d639 [hal] Replace SerialHelper "goto done" with continue (#4342)
d25af48797 [ci] Make upstream_utils CI fail on untracked files (#4339)
ebb836dacb [examples] Fix negations in event loop examples (#4334)
d83e202f00 [upstream_utils] Update paths in update_fmt.py (#4338)
3ccf806064 [wpimath] Remove redundant LinearFilter.finiteDifference() argument (#4335)
6f1e01f8bd [wpimath] Document example of online filtering for LinearFilter.finiteDifference() (#4336)
1023c34b1c [readme] Update location of ni-libraries (#4333)
faa29d596c [wpilib] Improve Notifier docs (NFC) (#4326)
add00a96ed [wpimath] Improve DifferentialDriveAccelerationLimiter docs (NFC) (#4323)
82fac41244 [wpimath] Better document trackwidth parameters (NFC) (#4324)
5eb44e22a9 Format Python scripts with black (NFC) (#4325)
2e09fa7325 [build] Fix mpack cmake (#4322)
fe3c24b1ee [command] Add ignoringDisable decorator (#4305)
aa221597bc [build] Add M1 builds, change arm name, update to 2023 deps (#4315)
579a8ee229 [ci] Use one worker for Windows release Gradle build (#4318)
5105c5eab6 [wpilibj] Change "final" to "exit" in the IterativeRobotBase JavaDoc (NFC) (#4317)
787fe6e7a5 [wpiutil] Separate third party libraries (#4190)
6671f8d099 [wpigui] Update portable file dialogs (#4316)
9ac9b69aa2 [command] Reorder Scheduler operations (#4261)
e61028cb18 [build] halsim_gui: Add wpinet dependency (#4313)
661d23eaf5 [glass] Add precision setting for NetworkTable view (#4311)
666040e3e5 [hal] Throw exceptions for invalid sizes in I2C and SPI JNI (#4312)
aebc272449 [build] Upgrade to spotbugs Gradle plugin 5.0.8 (#4310)
fd884581e4 [wpilib] Add BooleanEvent/Trigger factories on HID classes (#4247)
9b1bf5c7f1 [wpimath] Move Drake and Eigen to thirdparty folders (#4307)
c9e620a920 [wpilibc] Change EventLoop data structure to vector (#4304)
41d40dd62f [wpinet] Fix libuv unused variable warning on Mac (#4299)
30f5b68264 [wpinet] Fix JNI loading error (#4295)
f7b3f4b90e [examples] Getting Started: Change Joystick to XboxController (#4194)
a99c11c14c [wpimath] Replace UKF implementation with square root form (#4168)
45b7fc445b [wpilib] Add EventLoop (#4104)
16a4888c52 [wpilib] Default off LiveWindow telemetry (#4301)
17752f1337 [ci] Split debug and release Windows builds (#4277)
abb45a68db [commands] Remove custom test wrappers (#4296)
1280a54ef3 [upstream_utils]: Make work with Python 3.8 (#4298)
f2d243fa68 [build] Change defaults for Java lints (#4300)
a4787130f4 Update using development build to work with 2023 gradlerio (#4294)
af7985e46c [wpiutil] Use invoke_result_t instead of result_of in future.h (#4293)
e9d1b5c2d0 [hal] Remove deprecated SimDevice functions (#4209)
45b598d236 [wpilibj] Add toString() methods to Color and Color8Bit (#4286)
fc37265da5 [wpimath] Add angle measurement convention to ArmFeedforward docs (NFC) (#4285)
a4ec13eb0e [wpilibjexamples] Remove unnecessary voltage desaturation
2fa52007af [wpilibc] Use GetBatteryVoltage() in MotorController::SetVoltage
d9f9cd1140 [wpimath] Reset prev_time on pose estimator reset (#4283)
8b6df88783 [wpilibj] Tachometer.getFrequency(): Fix bug (#4281)
345cff08c0 [wpiutil] Make wpi::array constexpr (#4278)
57428112ac [wpimath] Upgrade to Drake v1.3.0 (#4279)
a18d4ff154 [build] Fix tools not being copied when built with -Ponly* (#4276)
d1cd07b9f3 [wpigui] Add OpenURL (#4273)
e67f8e917a [glass] Use glfwSetKeyCallback for Enter key remap (#4275)
be2fedfe50 [wpimath] Add stdexcept include for std::invalid_argument (IWYU) (#4274)
7ad2be172e [build] Update native-utils to 2023.0.1 (#4272)
abc605c9c9 [ci] Update workflows to 20.04 base image (#4271)
3e94805220 [wpiutil] Reduce llvm collections patches (#4268)
db2e1d170e [upstream_utils] Document how to update thirdparty libraries (#4253)
96ebdcaf16 [wpimath] Remove unused Eigen AutoDiff module (#4267)
553b2a3b12 [upstream_utils] Fix stackwalker (#4265)
3e13ef42eb [wpilibc] Add missing std::array #include (include-what-you-use) (#4266)
d651a1fcec Fix internal deprecation warnings (#4257)
b193b318c1 [commands] Add unless() decorator (#4244)
ef3714223b [commands] Remove docs reference to obsolete interrupted() method (NFC) (#4262)
3d8dbbbac3 [readme] Add quickstart (#4225)
013efdde25 [wpinet] Wrap a number of newer libuv features (#4260)
816aa4e465 [wpilib] Add Pneumatics sim classes (#4033)
046c2c8972 [wpilibc] Rename SpeedControllerGroupTest.cpp (#4258)
d80e9cdf64 [upstream_utils] Use shallow clones for thirdparty repos (#4255)
7576136b4a [upstream_utils] Make update_llvm.py executable (#4254)
c3b223ce60 [wpiutil] Vendor llvm and update to 13.0.0 (#4224)
5aa67f56e6 [wpimath] Clean up math comments (#4252)
fff4d1f44e [wpimath] Extend Eigen warning suppression to GCC 12 (#4251)
0d9956273c [wpimath] Add CoordinateSystem.convert() translation and rotation overloads (#4227)
3fada4e0b4 [wpinet] Update to libuv 1.44.1 (#4232)
65b23ac45e [wpilibc] Fix return value of DriverStation::GetJoystickAxisType() (#4230)
4ac34c0141 [upstream_utils] Cleanup update_libuv.py (#4249)
8bd614bb1e [upstream_utils] Use "git am" instead of "git apply" for patches (#4248)
4253d6d5f0 [upstream_utils] Apply "git am" patches individually (#4250)
6a4752dcdc Fix GCC 12.1 warning false positives (#4246)
5876b40f08 [wpimath] Memoize CoordinateSystem and CoordinateAxis statics (#4241)
5983434a70 [cameraserver] Replace IterativeRobot in comment sample code with TimedRobot (#4238)
a3d44a1e69 [wpimath] Add Translation2d.getAngle() (#4217)
d364bbd5a7 [upstream_utils] Give vendor update scripts execute permissions (#4226)
f341e1b2be [wpimath] Document standard coordinate systems better (NFC) (#4228)
9af389b200 [wpinet] AddrToName: Initialize name (#4229)
2ae4adf2d7 [ci] Add wpiformat command to PRs (#4223)
178b2a1e88 Contributing.md: Correct version of clang-format used (#4222)
18db343cdc [wpiutil, wpinet] Vendor libuv, stack walker (#4219)
f0c821282a [build] Use artifactory mirror (#4220)
d673ead481 [wpinet] Move network portions of wpiutil into new wpinet library (#4077)
b33715db15 [wpimath] Add CoordinateSystem class (#4214)
99424ad562 [sim] Allow creating a PWMSim object from a PWMMotorController (#4039)
dc6f641fd2 [wpimath] PIDController: Reset position and velocity error when reset() is called. (#4064)
f20a20f3f1 [wpimath] Add 3D geometry classes (#4175)
708a4bc3bc [wpimath] Conserve previously calculated swerve module angles when updating states for stationary ChassisSpeeds (#4208)
ef7ed21a9d [wpimath] Improve accuracy of ComputerVisionUtil.calculateDistanceToTarget() (#4215)
b1abf455c1 [wpimath] LTVUnicycleController: Use LUT, provide default hyperparameters (#4213)
d5456cf278 [wpimath] LTVDifferentialDriveController: Remove unused variable (#4212)
99343d40ba [command] Remove old command-based framework (#4211)
ee03a7ad3b Remove most 2022 deprecations (#4205)
ce1a7d698a [wpimath] Refactor WheelVoltages inner class to a separate file (#4203)
87bf70fa8e [wpimath] Add LTV controllers (#4094)
ebd2a303bf [wpimath] Remove deprecated MakeMatrix() function (#4202)
e28776d361 [wpimath] LinearSystemLoop: Add extern templates for common cases
dac1429aa9 [wpimath] LQR: Use extern template instead of Impl class
e767605e94 [wpimath] Add typedefs for common types
97c493241f [wpimath] UnscentedKalmanFilter: Move implementation out-of-line
8ea90d8bc9 [wpimath] ExtendedKalmanFilter: Move implementation out-of-line
ae7b1851ec [wpimath] KalmanFilter: Use extern template instead of Impl class
e3d62c22d3 [wpimath] Add extern templates for common cases
7200c4951d [wpiutil] SymbolExports: Add WPILIB_IMPORTS for dllimport
84056c9347 [wpiutil] SymbolExports: Add EXPORT_TEMPLATE_DECLARE/DEFINE
09cf6eeecb [wpimath] ApplyDeadband: add a scale param (#3865)
03230fc842 [build,ci] Enable artifactory build cache (#4200)
63cf3aaa3f [examples] Don't square ArcadeDrive inputs in auto (#4201)
18ff694f02 [wpimath] Add Rotation2d.fromRadians factory (#4178)
4f79ceedd9 [wpilibc] Add missing #include (#4198)
f7ca72fb41 [command] Rename PerpetualCommand to EndlessCommand (#4177)
a06b3f0307 [hal] Correct documentation on updateNotifierAlarm (#4156)
d926dd1610 [wpimath] Fix pose estimator performance (#4111)
51bc893bc5 [wpiutil] CircularBuffer: Change Java package-private methods to public (#4181)
fbe761f7f6 [build] Increase Gradle JVM heap size (#4172)
5ebe911933 [wpimath] Add DifferentialDriveAccelerationLimiter (#4091)
3919250da2 [wpilibj] Remove finalizers (#4158)
b3aee28388 [commands] Allow BooleanSupplier for Trigger operations (#4103)
9d20ab3024 [wpilib] Allow disabling ElevatorSim gravity (#4145)
aaa69f6717 [ci] Remove 32-bit Windows builds (#4078)
355a11a414 Update Java linters and fix new PMD errors (#4157)
ffc69d406c [examples] Reduce suggested acceleration in Ramsete example (#4171)
922d50079a [wpimath] Units: fix comment in degreesToRotations (NFC) (#4159)
dd163b62ae [wpimath] Rotation2d: Add factory method that uses rotations (#4166)
bd80e220b9 [ci] Upgrade CMake actions (#4161)
aef4b16d4c [wpimath] Remove unnecessary NOLINT in LinearPlantInversionFeedforward (NFC) (#4155)
975171609e [wpilib] Compressor: Rename enabled to isEnabled (#4147)
5bf46a9093 [wpimath] Add ComputerVisionUtil (#4124)
f27a1f9bfb [commands] Fix JoystickButton.getAsBoolean (#4131)
1b26e2d5da [commands] Add RepeatCommand (#4009)
88222daa3d [hal] Fix misspelling in AnalogInput/Output docs (NFC) (#4153)
81c5b41ce1 [wpilibj] Document MechanismLigament2d angle unit (NFC) (#4142)
9650e6733e [wpiutil] DataLog: Document finish and thread safety (NFC) (#4140)
c8905ec29a [wpimath] Remove ImplicitModelFollower dt argument (#4119)
b4620f01f9 [wpimath] Fix Rotation2d interpolation in Java (#4125)
2e462a19d3 [wpimath] Constexprify units unary operators (#4138)
069f932e59 [build] Fix gl3w cmake build (#4139)
126e3de91a [wpilibc] Remove unused SetPriority() call from Ultrasonic (#4123)
ba0dccaae4 [wpimath] Fix reference to Rotation2d.fromRadians() (#4118)
e1b6e5f212 [wpilib] Improve MotorSafety documentation (NFC) (#4120)
8d79dc8738 [wpimath] Add ImplicitModelFollower (#4056)
78108c2aba [wpimath] Fix PIDController having incorrect error after calling SetSetpoint() (#4070)
cdafc723fb [examples] Remove unused LinearPlantInversionFeedforward includes (#4069)
0d70884dce [wpimath] Add InterpolatedTreeMap (#4073)
765efa325e [wpimath] Remove redundant column index from vectors (#4116)
89ffcbbe41 [wpimath] Update TrapezoidProfile class name in comment (NFC) (#4107)
95ae23b0e7 [wpimath] Improve EKF numerical stability (#4093)
d5cb6fed67 [wpimath] Support zero cost entries in MakeCostMatrix() (#4100)
d0fef18378 [wpimath] Remove redundant `this.` from ExtendedKalmanFilter.java (#4115)
d640c0f41f [wpimath] Fix pose estimator local measurement standard deviation docs (NFC) (#4113)
a2fa5e3ff7 [wpilibc] BatterySim: Provide non-initializer list versions of Calculate (#4076)
a3eea9958e [hal] Add link to FRC CAN Spec (NFC) (#4086)
db27331d7b [wpilib] Update DifferentialDrive docs (NFC) (#4085)
fdfb31f164 [dlt] Export boolean[] values (#4082)
f93c3331b3 [wpigui] disable changing directory when initializing on MacOS (#4092)
ab7ac4fbb9 [build] Fix various warnings in cmake builds (#4081)
bc39a1a293 [wpilibc] Fix moved pneumatics objects not destructing properly (#4068)
2668130e70 [wpimath] Remove SwerveDrivePoseEstimator encoder reset warning (#4066)
d27ed3722b [ci] Set actions workflow concurrency (#4060)
dae18308c9 [wpimath] Minor fixes to Rotation2d docs (NFC) (#4055)
d66555e42f [datalogtool] Add datalogtool
9f52d8a3b1 [wpilib] DriverStation: Add DataLog support for modes and joystick data
757ea91932 [wpilib] Add DataLogManager
02a804f1c5 [ntcore] Add DataLog support
9b500df0d9 [wpiutil] Add high speed data logging
5a89575b3a [wpiutil] Import customized LLVM MemoryBuffer
b8c4d7527b [wpiutil] Add MappedFileRegion
ac5d46cfa7 [wpilibc] Fix ProfiledPID SetTolerance default velocity value (#4054)
bc9e96e86f [wpilib] Absolute Encoder API and behavior fixes (#4052)
f88c435dd0 [hal] Add mechanism to cancel all periodic callbacks (#4049)
Change-Id: I49aa5b08abbefc7a045e99e19d48ce2cd8fc4d1b
git-subtree-dir: third_party/allwpilib
git-subtree-split: 83f1860047c86aa3330fcb41caf3b2047e074804
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/hal/src/dev/native/cpp/main.cpp b/hal/src/dev/native/cpp/main.cpp
index 721c0f6..8614aba 100644
--- a/hal/src/dev/native/cpp/main.cpp
+++ b/hal/src/dev/native/cpp/main.cpp
@@ -8,5 +8,5 @@
int main() {
fmt::print("Hello World\n");
- fmt::print("{}\n", HAL_GetRuntimeType());
+ fmt::print("{}\n", static_cast<int32_t>(HAL_GetRuntimeType()));
}
diff --git a/hal/src/generate/FRCNetComm.java.in b/hal/src/generate/FRCNetComm.java.in
index ce21889..703e034 100644
--- a/hal/src/generate/FRCNetComm.java.in
+++ b/hal/src/generate/FRCNetComm.java.in
@@ -7,7 +7,6 @@
/**
* JNI wrapper for library <b>FRC_NetworkCommunication</b><br>.
*/
-@SuppressWarnings({"MethodName", "LineLength"})
public class FRCNetComm {
/**
* Resource type from UsageReporting.
diff --git a/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java b/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java
index 9340748..441ce9f 100644
--- a/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java
+++ b/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java
@@ -5,12 +5,11 @@
package edu.wpi.first.hal;
/** Structure for holding the values stored in an accumulator. */
+@SuppressWarnings("MemberName")
public class AccumulatorResult {
/** The total value accumulated. */
- @SuppressWarnings("MemberName")
public long value;
/** The number of sample value was accumulated over. */
- @SuppressWarnings("MemberName")
public long count;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/AddressableLEDJNI.java b/hal/src/main/java/edu/wpi/first/hal/AddressableLEDJNI.java
index c732ec6..1dd80a7 100644
--- a/hal/src/main/java/edu/wpi/first/hal/AddressableLEDJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/AddressableLEDJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class AddressableLEDJNI extends JNIWrapper {
public static native int initialize(int pwmHandle);
diff --git a/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java b/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java
index e2deadd..b80388d 100644
--- a/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java
@@ -111,6 +111,5 @@
public static native boolean getAnalogTriggerOutput(int analogTriggerHandle, int type);
- @SuppressWarnings("AbbreviationAsWordInName")
public static native int getAnalogTriggerFPGAIndex(int analogTriggerHandle);
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java b/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java
index 31cf973..227da4d 100644
--- a/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class CANAPIJNI extends JNIWrapper {
public static native int initializeCAN(int manufacturer, int deviceId, int deviceType);
diff --git a/hal/src/main/java/edu/wpi/first/hal/CANData.java b/hal/src/main/java/edu/wpi/first/hal/CANData.java
index 94e9f57..0a644f6 100644
--- a/hal/src/main/java/edu/wpi/first/hal/CANData.java
+++ b/hal/src/main/java/edu/wpi/first/hal/CANData.java
@@ -4,14 +4,10 @@
package edu.wpi.first.hal;
+@SuppressWarnings("MemberName")
public class CANData {
- @SuppressWarnings("MemberName")
public final byte[] data = new byte[8];
-
- @SuppressWarnings("MemberName")
public int length;
-
- @SuppressWarnings("MemberName")
public long timestamp;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/CANStreamMessage.java b/hal/src/main/java/edu/wpi/first/hal/CANStreamMessage.java
new file mode 100644
index 0000000..bdb2112
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/CANStreamMessage.java
@@ -0,0 +1,35 @@
+// 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 edu.wpi.first.hal;
+
+public class CANStreamMessage {
+ @SuppressWarnings("MemberName")
+ public final byte[] data = new byte[8];
+
+ @SuppressWarnings("MemberName")
+ public int length;
+
+ @SuppressWarnings("MemberName")
+ public long timestamp;
+
+ @SuppressWarnings("MemberName")
+ public int messageID;
+
+ /**
+ * API used from JNI to set the data.
+ *
+ * @param length Length of packet in bytes.
+ * @param messageID CAN message ID of the message.
+ * @param timestamp CAN frame timestamp in microseconds.
+ * @return Buffer containing CAN frame.
+ */
+ @SuppressWarnings("PMD.MethodReturnsInternalArray")
+ public byte[] setStreamData(int length, int messageID, long timestamp) {
+ this.messageID = messageID;
+ this.length = length;
+ this.timestamp = timestamp;
+ return data;
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/CTREPCMJNI.java b/hal/src/main/java/edu/wpi/first/hal/CTREPCMJNI.java
index 20d5cb8..e94b183 100644
--- a/hal/src/main/java/edu/wpi/first/hal/CTREPCMJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/CTREPCMJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class CTREPCMJNI extends JNIWrapper {
public static native int initialize(int module);
diff --git a/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java b/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java
index dab1aaf..689a95e 100644
--- a/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class DIOJNI extends JNIWrapper {
public static native int initializeDIOPort(int halPortHandle, boolean input);
@@ -22,7 +21,9 @@
public static native boolean getDIODirection(int dioPortHandle);
- public static native void pulse(int dioPortHandle, double pulseLength);
+ public static native void pulse(int dioPortHandle, double pulseLengthSeconds);
+
+ public static native void pulseMultiple(long channelMask, double pulseLengthSeconds);
public static native boolean isPulsing(int dioPortHandle);
@@ -38,5 +39,7 @@
public static native void setDigitalPWMDutyCycle(int pwmGenerator, double dutyCycle);
+ public static native void setDigitalPWMPPS(int pwmGenerator, double dutyCycle);
+
public static native void setDigitalPWMOutputChannel(int pwmGenerator, int channel);
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/DMAJNI.java b/hal/src/main/java/edu/wpi/first/hal/DMAJNI.java
index 21c06f1..9a0cfeb 100644
--- a/hal/src/main/java/edu/wpi/first/hal/DMAJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/DMAJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class DMAJNI extends JNIWrapper {
public static native int initialize();
diff --git a/hal/src/main/java/edu/wpi/first/hal/DMAJNISample.java b/hal/src/main/java/edu/wpi/first/hal/DMAJNISample.java
index 78a0e99..22f21c8 100644
--- a/hal/src/main/java/edu/wpi/first/hal/DMAJNISample.java
+++ b/hal/src/main/java/edu/wpi/first/hal/DMAJNISample.java
@@ -7,7 +7,6 @@
import java.util.HashMap;
import java.util.Map;
-@SuppressWarnings("AbbreviationAsWordInName")
public class DMAJNISample {
private static final int kEnable_Accumulator0 = 8;
private static final int kEnable_Accumulator1 = 9;
diff --git a/hal/src/main/java/edu/wpi/first/hal/DriverStationJNI.java b/hal/src/main/java/edu/wpi/first/hal/DriverStationJNI.java
new file mode 100644
index 0000000..f40a38c
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/DriverStationJNI.java
@@ -0,0 +1,137 @@
+// 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 edu.wpi.first.hal;
+
+import java.nio.ByteBuffer;
+
+public class DriverStationJNI extends JNIWrapper {
+ public static native void observeUserProgramStarting();
+
+ public static native void observeUserProgramDisabled();
+
+ public static native void observeUserProgramAutonomous();
+
+ public static native void observeUserProgramTeleop();
+
+ public static native void observeUserProgramTest();
+
+ public static void report(int resource, int instanceNumber) {
+ report(resource, instanceNumber, 0, "");
+ }
+
+ public static void report(int resource, int instanceNumber, int context) {
+ report(resource, instanceNumber, context, "");
+ }
+
+ /**
+ * Report the usage of a resource of interest.
+ *
+ * <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
+ * char*)</code>
+ *
+ * @param resource one of the values in the tResourceType above (max value 51).
+ * @param instanceNumber an index that identifies the resource instance.
+ * @param context an optional additional context number for some cases (such as module number).
+ * Set to 0 to omit.
+ * @param feature a string to be included describing features in use on a specific resource.
+ * Setting the same resource more than once allows you to change the feature string.
+ * @return TODO
+ */
+ public static native int report(int resource, int instanceNumber, int context, String feature);
+
+ public static native int nativeGetControlWord();
+
+ @SuppressWarnings("MissingJavadocMethod")
+ public static void getControlWord(ControlWord controlWord) {
+ int word = nativeGetControlWord();
+ controlWord.update(
+ (word & 1) != 0,
+ ((word >> 1) & 1) != 0,
+ ((word >> 2) & 1) != 0,
+ ((word >> 3) & 1) != 0,
+ ((word >> 4) & 1) != 0,
+ ((word >> 5) & 1) != 0);
+ }
+
+ private static native int nativeGetAllianceStation();
+
+ public static final int kRed1AllianceStation = 0;
+ public static final int kRed2AllianceStation = 1;
+ public static final int kRed3AllianceStation = 2;
+ public static final int kBlue1AllianceStation = 3;
+ public static final int kBlue2AllianceStation = 4;
+ public static final int kBlue3AllianceStation = 5;
+
+ @SuppressWarnings("MissingJavadocMethod")
+ public static AllianceStationID getAllianceStation() {
+ switch (nativeGetAllianceStation()) {
+ case kRed1AllianceStation:
+ return AllianceStationID.Red1;
+ case kRed2AllianceStation:
+ return AllianceStationID.Red2;
+ case kRed3AllianceStation:
+ return AllianceStationID.Red3;
+ case kBlue1AllianceStation:
+ return AllianceStationID.Blue1;
+ case kBlue2AllianceStation:
+ return AllianceStationID.Blue2;
+ case kBlue3AllianceStation:
+ return AllianceStationID.Blue3;
+ default:
+ return null;
+ }
+ }
+
+ public static final int kMaxJoystickAxes = 12;
+ public static final int kMaxJoystickPOVs = 12;
+ public static final int kMaxJoysticks = 6;
+
+ public static native int getJoystickAxes(byte joystickNum, float[] axesArray);
+
+ public static native int getJoystickAxesRaw(byte joystickNum, int[] rawAxesArray);
+
+ public static native int getJoystickPOVs(byte joystickNum, short[] povsArray);
+
+ public static native int getJoystickButtons(byte joystickNum, ByteBuffer count);
+
+ public static native void getAllJoystickData(
+ float[] axesArray, byte[] rawAxesArray, short[] povsArray, long[] buttonsAndMetadata);
+
+ public static native int setJoystickOutputs(
+ byte joystickNum, int outputs, short leftRumble, short rightRumble);
+
+ public static native int getJoystickIsXbox(byte joystickNum);
+
+ public static native int getJoystickType(byte joystickNum);
+
+ public static native String getJoystickName(byte joystickNum);
+
+ public static native int getJoystickAxisType(byte joystickNum, byte axis);
+
+ public static native double getMatchTime();
+
+ public static native int getMatchInfo(MatchInfoData info);
+
+ public static native int sendError(
+ boolean isError,
+ int errorCode,
+ boolean isLVCode,
+ String details,
+ String location,
+ String callStack,
+ boolean printMsg);
+
+ public static native int sendConsoleLine(String line);
+
+ public static native void refreshDSData();
+
+ public static native void provideNewDataEventHandle(int handle);
+
+ public static native void removeNewDataEventHandle(int handle);
+
+ public static native boolean getOutputsActive();
+
+ private DriverStationJNI() {}
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/DutyCycleJNI.java b/hal/src/main/java/edu/wpi/first/hal/DutyCycleJNI.java
index a1bba6f..f2737d8 100644
--- a/hal/src/main/java/edu/wpi/first/hal/DutyCycleJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/DutyCycleJNI.java
@@ -13,10 +13,9 @@
public static native double getOutput(int handle);
- public static native int getOutputRaw(int handle);
+ public static native int getHighTime(int handle);
public static native int getOutputScaleFactor(int handle);
- @SuppressWarnings("AbbreviationAsWordInName")
public static native int getFPGAIndex(int handle);
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java b/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java
index f67e3a5..50ecc91 100644
--- a/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java
@@ -50,7 +50,6 @@
public static native void setEncoderIndexSource(
int encoderHandle, int digitalSourceHandle, int analogTriggerType, int indexingType);
- @SuppressWarnings("AbbreviationAsWordInName")
public static native int getEncoderFPGAIndex(int encoderHandle);
public static native int getEncoderEncodingScale(int encoderHandle);
diff --git a/hal/src/main/java/edu/wpi/first/hal/HAL.java b/hal/src/main/java/edu/wpi/first/hal/HAL.java
index 53198e0..68e6ec8 100644
--- a/hal/src/main/java/edu/wpi/first/hal/HAL.java
+++ b/hal/src/main/java/edu/wpi/first/hal/HAL.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -12,10 +11,7 @@
* JNI Wrapper for HAL<br>
* .
*/
-@SuppressWarnings({"AbbreviationAsWordInName", "MethodName"})
public final class HAL extends JNIWrapper {
- public static native void waitForDSData();
-
public static native boolean initialize(int timeout, int mode);
public static native void shutdown();
@@ -117,15 +113,13 @@
}
}
- public static native void observeUserProgramStarting();
+ public static native boolean getBrownedOut();
- public static native void observeUserProgramDisabled();
+ public static native boolean getSystemActive();
- public static native void observeUserProgramAutonomous();
+ public static native int getPortWithModule(byte module, byte channel);
- public static native void observeUserProgramTeleop();
-
- public static native void observeUserProgramTest();
+ public static native int getPort(byte channel);
public static void report(int resource, int instanceNumber) {
report(resource, instanceNumber, 0, "");
@@ -135,109 +129,9 @@
report(resource, instanceNumber, context, "");
}
- /**
- * Report the usage of a resource of interest.
- *
- * <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
- * char*)</code>
- *
- * @param resource one of the values in the tResourceType above (max value 51).
- * @param instanceNumber an index that identifies the resource instance.
- * @param context an optional additional context number for some cases (such as module number).
- * Set to 0 to omit.
- * @param feature a string to be included describing features in use on a specific resource.
- * Setting the same resource more than once allows you to change the feature string.
- * @return TODO
- */
- public static native int report(int resource, int instanceNumber, int context, String feature);
-
- public static native int nativeGetControlWord();
-
- @SuppressWarnings("MissingJavadocMethod")
- public static void getControlWord(ControlWord controlWord) {
- int word = nativeGetControlWord();
- controlWord.update(
- (word & 1) != 0,
- ((word >> 1) & 1) != 0,
- ((word >> 2) & 1) != 0,
- ((word >> 3) & 1) != 0,
- ((word >> 4) & 1) != 0,
- ((word >> 5) & 1) != 0);
+ public static int report(int resource, int instanceNumber, int context, String feature) {
+ return DriverStationJNI.report(resource, instanceNumber, context, feature);
}
- private static native int nativeGetAllianceStation();
-
- @SuppressWarnings("MissingJavadocMethod")
- public static AllianceStationID getAllianceStation() {
- switch (nativeGetAllianceStation()) {
- case 0:
- return AllianceStationID.Red1;
- case 1:
- return AllianceStationID.Red2;
- case 2:
- return AllianceStationID.Red3;
- case 3:
- return AllianceStationID.Blue1;
- case 4:
- return AllianceStationID.Blue2;
- case 5:
- return AllianceStationID.Blue3;
- default:
- return null;
- }
- }
-
- @SuppressWarnings("MissingJavadocMethod")
- public static native boolean isNewControlData();
-
- @SuppressWarnings("MissingJavadocMethod")
- public static native void releaseDSMutex();
-
- @SuppressWarnings("MissingJavadocMethod")
- public static native boolean waitForDSDataTimeout(double timeout);
-
- public static final int kMaxJoystickAxes = 12;
- public static final int kMaxJoystickPOVs = 12;
-
- public static native short getJoystickAxes(byte joystickNum, float[] axesArray);
-
- public static native short getJoystickPOVs(byte joystickNum, short[] povsArray);
-
- public static native int getJoystickButtons(byte joystickNum, ByteBuffer count);
-
- public static native int setJoystickOutputs(
- byte joystickNum, int outputs, short leftRumble, short rightRumble);
-
- public static native int getJoystickIsXbox(byte joystickNum);
-
- public static native int getJoystickType(byte joystickNum);
-
- public static native String getJoystickName(byte joystickNum);
-
- public static native int getJoystickAxisType(byte joystickNum, byte axis);
-
- public static native double getMatchTime();
-
- public static native boolean getSystemActive();
-
- public static native boolean getBrownedOut();
-
- public static native int getMatchInfo(MatchInfoData info);
-
- public static native int sendError(
- boolean isError,
- int errorCode,
- boolean isLVCode,
- String details,
- String location,
- String callStack,
- boolean printMsg);
-
- public static native int sendConsoleLine(String line);
-
- public static native int getPortWithModule(byte module, byte channel);
-
- public static native int getPort(byte channel);
-
private HAL() {}
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/HALUtil.java b/hal/src/main/java/edu/wpi/first/hal/HALUtil.java
index 4da20a2..7c0f41a 100644
--- a/hal/src/main/java/edu/wpi/first/hal/HALUtil.java
+++ b/hal/src/main/java/edu/wpi/first/hal/HALUtil.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public final class HALUtil extends JNIWrapper {
public static final int NULL_PARAMETER = -1005;
public static final int SAMPLE_RATE_TOO_HIGH = 1001;
@@ -23,6 +22,10 @@
public static native int getFPGARevision();
+ public static native String getSerialNumber();
+
+ public static native String getComments();
+
public static native long getFPGATime();
public static native int getHALRuntimeType();
diff --git a/hal/src/main/java/edu/wpi/first/hal/HALValue.java b/hal/src/main/java/edu/wpi/first/hal/HALValue.java
index ded57de..5f5441c 100644
--- a/hal/src/main/java/edu/wpi/first/hal/HALValue.java
+++ b/hal/src/main/java/edu/wpi/first/hal/HALValue.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public final class HALValue {
public static final int kUnassigned = 0;
public static final int kBoolean = 0x01;
diff --git a/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java b/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java
index 821c89b..63f32a0 100644
--- a/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java
@@ -6,7 +6,6 @@
import java.nio.ByteBuffer;
-@SuppressWarnings("AbbreviationAsWordInName")
public class I2CJNI extends JNIWrapper {
public static native void i2CInitialize(int port);
diff --git a/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java b/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java
index a47a364..7dc2e6d 100644
--- a/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java
@@ -11,9 +11,12 @@
public static native void cleanInterrupts(int interruptHandle);
- public static native int waitForInterrupt(
+ public static native long waitForInterrupt(
int interruptHandle, double timeout, boolean ignorePrevious);
+ public static native long waitForMultipleInterrupts(
+ int interruptHandle, long mask, double timeout, boolean ignorePrevious);
+
public static native long readInterruptRisingTimestamp(int interruptHandle);
public static native long readInterruptFallingTimestamp(int interruptHandle);
diff --git a/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java b/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java
index 6737c58..699ecc5 100644
--- a/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java
+++ b/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java
@@ -5,25 +5,21 @@
package edu.wpi.first.hal;
/** Structure for holding the match info data request. */
+@SuppressWarnings("MemberName")
public class MatchInfoData {
/** Stores the event name. */
- @SuppressWarnings("MemberName")
public String eventName = "";
/** Stores the game specific message. */
- @SuppressWarnings("MemberName")
public String gameSpecificMessage = "";
/** Stores the match number. */
- @SuppressWarnings("MemberName")
public int matchNumber;
/** Stores the replay number. */
- @SuppressWarnings("MemberName")
public int replayNumber;
/** Stores the match type. */
- @SuppressWarnings("MemberName")
public int matchType;
/**
@@ -35,7 +31,6 @@
* @param replayNumber Replay number.
* @param matchType Match type.
*/
- @SuppressWarnings("MissingJavadocMethod")
public void setData(
String eventName,
String gameSpecificMessage,
diff --git a/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java b/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java
index c8f4eef..648e8a2 100644
--- a/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java
@@ -52,7 +52,7 @@
public static native void cleanNotifier(int notifierHandle);
/**
- * Sets the notifier to wakeup the waiter in another triggerTime microseconds.
+ * Sets the notifier to wake up the waiter at triggerTime microseconds.
*
* @param notifierHandle Notifier handle.
* @param triggerTime Trigger time in microseconds.
diff --git a/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java b/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java
index e64d6da..ac3c8f94 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java
@@ -5,6 +5,7 @@
package edu.wpi.first.hal;
/** Structure for holding the config data result for PWM. */
+@SuppressWarnings("MemberName")
public class PWMConfigDataResult {
PWMConfigDataResult(int max, int deadbandMax, int center, int deadbandMin, int min) {
this.max = max;
@@ -15,22 +16,17 @@
}
/** The maximum PWM value. */
- @SuppressWarnings("MemberName")
public int max;
/** The deadband maximum PWM value. */
- @SuppressWarnings("MemberName")
public int deadbandMax;
/** The center PWM value. */
- @SuppressWarnings("MemberName")
public int center;
/** The deadband minimum PWM value. */
- @SuppressWarnings("MemberName")
public int deadbandMin;
/** The minimum PWM value. */
- @SuppressWarnings("MemberName")
public int min;
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java b/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java
index 946ad07..1ed562c 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class PWMJNI extends DIOJNI {
public static native int initializePWMPort(int halPortHandle);
diff --git a/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java b/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java
index 6a06ff9..b4bd6cf 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class PortsJNI extends JNIWrapper {
public static native int getNumAccumulators();
diff --git a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionFaults.java b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionFaults.java
index bdff599..aa2cac5 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionFaults.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionFaults.java
@@ -4,86 +4,60 @@
package edu.wpi.first.hal;
+@SuppressWarnings("MemberName")
public class PowerDistributionFaults {
- @SuppressWarnings("MemberName")
public final boolean Channel0BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel1BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel2BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel3BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel4BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel5BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel6BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel7BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel8BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel9BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel10BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel11BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel12BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel13BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel14BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel15BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel16BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel17BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel18BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel19BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel20BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel21BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel22BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel23BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Brownout;
- @SuppressWarnings("MemberName")
public final boolean CanWarning;
- @SuppressWarnings("MemberName")
public final boolean HardwareFault;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionJNI.java b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionJNI.java
index 00c4dd1..8280f93 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class PowerDistributionJNI extends JNIWrapper {
public static final int AUTOMATIC_TYPE = 0;
public static final int CTRE_TYPE = 1;
diff --git a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionStickyFaults.java b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionStickyFaults.java
index 0eb4a69..f60f8df 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionStickyFaults.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionStickyFaults.java
@@ -4,89 +4,62 @@
package edu.wpi.first.hal;
+@SuppressWarnings("MemberName")
public class PowerDistributionStickyFaults {
- @SuppressWarnings("MemberName")
public final boolean Channel0BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel1BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel2BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel3BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel4BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel5BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel6BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel7BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel8BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel9BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel10BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel11BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel12BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel13BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel14BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel15BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel16BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel17BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel18BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel19BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel20BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel21BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel22BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Channel23BreakerFault;
- @SuppressWarnings("MemberName")
public final boolean Brownout;
- @SuppressWarnings("MemberName")
public final boolean CanWarning;
- @SuppressWarnings("MemberName")
public final boolean CanBusOff;
- @SuppressWarnings("MemberName")
public final boolean HasReset;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionVersion.java b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionVersion.java
index 0c733a2..fdd1233 100644
--- a/hal/src/main/java/edu/wpi/first/hal/PowerDistributionVersion.java
+++ b/hal/src/main/java/edu/wpi/first/hal/PowerDistributionVersion.java
@@ -4,23 +4,18 @@
package edu.wpi.first.hal;
+@SuppressWarnings("MemberName")
public class PowerDistributionVersion {
- @SuppressWarnings("MemberName")
public final int firmwareMajor;
- @SuppressWarnings("MemberName")
public final int firmwareMinor;
- @SuppressWarnings("MemberName")
public final int firmwareFix;
- @SuppressWarnings("MemberName")
public final int hardwareMinor;
- @SuppressWarnings("MemberName")
public final int hardwareMajor;
- @SuppressWarnings("MemberName")
public final int uniqueId;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/REVPHFaults.java b/hal/src/main/java/edu/wpi/first/hal/REVPHFaults.java
index f71ef69..3419810 100644
--- a/hal/src/main/java/edu/wpi/first/hal/REVPHFaults.java
+++ b/hal/src/main/java/edu/wpi/first/hal/REVPHFaults.java
@@ -4,72 +4,50 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
+@SuppressWarnings("MemberName")
public class REVPHFaults {
- @SuppressWarnings("MemberName")
public final boolean Channel0Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel1Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel2Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel3Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel4Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel5Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel6Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel7Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel8Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel9Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel10Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel11Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel12Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel13Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel14Fault;
- @SuppressWarnings("MemberName")
public final boolean Channel15Fault;
- @SuppressWarnings("MemberName")
public final boolean CompressorOverCurrent;
- @SuppressWarnings("MemberName")
public final boolean CompressorOpen;
- @SuppressWarnings("MemberName")
public final boolean SolenoidOverCurrent;
- @SuppressWarnings("MemberName")
public final boolean Brownout;
- @SuppressWarnings("MemberName")
public final boolean CanWarning;
- @SuppressWarnings("MemberName")
public final boolean HardwareFault;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/REVPHJNI.java b/hal/src/main/java/edu/wpi/first/hal/REVPHJNI.java
index 17f0323..44c67a8 100644
--- a/hal/src/main/java/edu/wpi/first/hal/REVPHJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/REVPHJNI.java
@@ -4,7 +4,6 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
public class REVPHJNI extends JNIWrapper {
public static final int COMPRESSOR_CONFIG_TYPE_DISABLED = 0;
public static final int COMPRESSOR_CONFIG_TYPE_DIGITAL = 1;
diff --git a/hal/src/main/java/edu/wpi/first/hal/REVPHStickyFaults.java b/hal/src/main/java/edu/wpi/first/hal/REVPHStickyFaults.java
index 6bf9f4f..614389e 100644
--- a/hal/src/main/java/edu/wpi/first/hal/REVPHStickyFaults.java
+++ b/hal/src/main/java/edu/wpi/first/hal/REVPHStickyFaults.java
@@ -4,27 +4,20 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
+@SuppressWarnings("MemberName")
public class REVPHStickyFaults {
- @SuppressWarnings("MemberName")
public final boolean CompressorOverCurrent;
- @SuppressWarnings("MemberName")
public final boolean CompressorOpen;
- @SuppressWarnings("MemberName")
public final boolean SolenoidOverCurrent;
- @SuppressWarnings("MemberName")
public final boolean Brownout;
- @SuppressWarnings("MemberName")
public final boolean CanWarning;
- @SuppressWarnings("MemberName")
public final boolean CanBusOff;
- @SuppressWarnings("MemberName")
public final boolean HasReset;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/REVPHVersion.java b/hal/src/main/java/edu/wpi/first/hal/REVPHVersion.java
index 13471e7..86d0743 100644
--- a/hal/src/main/java/edu/wpi/first/hal/REVPHVersion.java
+++ b/hal/src/main/java/edu/wpi/first/hal/REVPHVersion.java
@@ -4,24 +4,18 @@
package edu.wpi.first.hal;
-@SuppressWarnings("AbbreviationAsWordInName")
+@SuppressWarnings("MemberName")
public class REVPHVersion {
- @SuppressWarnings("MemberName")
public final int firmwareMajor;
- @SuppressWarnings("MemberName")
public final int firmwareMinor;
- @SuppressWarnings("MemberName")
public final int firmwareFix;
- @SuppressWarnings("MemberName")
public final int hardwareMinor;
- @SuppressWarnings("MemberName")
public final int hardwareMajor;
- @SuppressWarnings("MemberName")
public final int uniqueId;
/**
diff --git a/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java b/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java
index 05ac08a..053f192 100644
--- a/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java
@@ -6,8 +6,19 @@
import java.nio.ByteBuffer;
-@SuppressWarnings("AbbreviationAsWordInName")
public class SPIJNI extends JNIWrapper {
+ public static final int INVALID_PORT = -1;
+ public static final int ONBOARD_CS0_PORT = 0;
+ public static final int ONBOARD_CS1_PORT = 1;
+ public static final int ONBOARD_CS2_PORT = 2;
+ public static final int ONBOARD_CS3_PORT = 3;
+ public static final int MXP_PORT = 4;
+
+ public static final int SPI_MODE0 = 0;
+ public static final int SPI_MODE1 = 1;
+ public static final int SPI_MODE2 = 2;
+ public static final int SPI_MODE3 = 3;
+
public static native void spiInitialize(int port);
public static native int spiTransaction(
@@ -28,8 +39,9 @@
public static native void spiSetSpeed(int port, int speed);
- public static native void spiSetOpts(
- int port, int msbFirst, int sampleOnTrailing, int clkIdleHigh);
+ public static native void spiSetMode(int port, int mode);
+
+ public static native int spiGetMode(int port);
public static native void spiSetChipSelectActiveHigh(int port);
diff --git a/hal/src/main/java/edu/wpi/first/hal/SimDevice.java b/hal/src/main/java/edu/wpi/first/hal/SimDevice.java
index 67c39fe..db3a587 100644
--- a/hal/src/main/java/edu/wpi/first/hal/SimDevice.java
+++ b/hal/src/main/java/edu/wpi/first/hal/SimDevice.java
@@ -112,22 +112,6 @@
* <p>Returns null if not in simulation.
*
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param initialValue initial value
- * @return simulated value object
- * @deprecated Use direction function instead
- */
- @Deprecated
- public SimValue createValue(String name, boolean readonly, HALValue initialValue) {
- return createValue(name, readonly ? Direction.kOutput : Direction.kInput, initialValue);
- }
-
- /**
- * Creates a value on the simulated device.
- *
- * <p>Returns null if not in simulation.
- *
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param initialValue initial value
* @return simulated value object
@@ -182,22 +166,6 @@
* <p>Returns null if not in simulation.
*
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param initialValue initial value
- * @return simulated double value object
- * @deprecated Use direction function instead
- */
- @Deprecated
- public SimDouble createDouble(String name, boolean readonly, double initialValue) {
- return createDouble(name, readonly ? Direction.kOutput : Direction.kInput, initialValue);
- }
-
- /**
- * Creates a double value on the simulated device.
- *
- * <p>Returns null if not in simulation.
- *
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param initialValue initial value
* @return simulated double value object
@@ -218,25 +186,6 @@
* <p>Returns null if not in simulation.
*
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param options array of option descriptions
- * @param initialValue initial value (selection)
- * @return simulated enum value object
- * @deprecated Use direction function instead
- */
- @Deprecated
- public SimEnum createEnum(String name, boolean readonly, String[] options, int initialValue) {
- return createEnum(name, readonly ? Direction.kOutput : Direction.kInput, options, initialValue);
- }
-
- /**
- * Creates an enumerated value on the simulated device.
- *
- * <p>Enumerated values are always in the range 0 to numOptions-1.
- *
- * <p>Returns null if not in simulation.
- *
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param options array of option descriptions
* @param initialValue initial value (selection)
@@ -282,22 +231,6 @@
* <p>Returns null if not in simulation.
*
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param initialValue initial value
- * @return simulated boolean value object
- * @deprecated Use direction function instead
- */
- @Deprecated
- public SimBoolean createBoolean(String name, boolean readonly, boolean initialValue) {
- return createBoolean(name, readonly ? Direction.kOutput : Direction.kInput, initialValue);
- }
-
- /**
- * Creates a boolean value on the simulated device.
- *
- * <p>Returns null if not in simulation.
- *
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param initialValue initial value
* @return simulated boolean value object
diff --git a/hal/src/main/java/edu/wpi/first/hal/SimDeviceJNI.java b/hal/src/main/java/edu/wpi/first/hal/SimDeviceJNI.java
index 4279916..8723cd3 100644
--- a/hal/src/main/java/edu/wpi/first/hal/SimDeviceJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/SimDeviceJNI.java
@@ -43,30 +43,6 @@
*
* @param device simulated device handle
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param initialValue initial value
- * @return simulated value handle
- * @deprecated Use direction-taking function instead
- */
- @Deprecated
- public static int createSimValue(
- int device, String name, boolean readonly, HALValue initialValue) {
- return createSimValueNative(
- device,
- name,
- readonly ? kOutput : kInput,
- initialValue.getType(),
- initialValue.getNativeLong(),
- initialValue.getNativeDouble());
- }
-
- /**
- * Creates a value on a simulated device.
- *
- * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
- *
- * @param device simulated device handle
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param initialValue initial value
* @return simulated value handle
@@ -118,25 +94,6 @@
*
* @param device simulated device handle
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param initialValue initial value
- * @return simulated value handle
- * @deprecated Use direction-taking function instead
- */
- @Deprecated
- public static int createSimValueDouble(
- int device, String name, boolean readonly, double initialValue) {
- return createSimValueNative(
- device, name, readonly ? kOutput : kInput, HALValue.kDouble, 0, initialValue);
- }
-
- /**
- * Creates a double value on a simulated device.
- *
- * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
- *
- * @param device simulated device handle
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param initialValue initial value
* @return simulated value handle
@@ -155,27 +112,6 @@
*
* @param device simulated device handle
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param options array of option descriptions
- * @param initialValue initial value (selection)
- * @return simulated value handle
- * @deprecated Use direction-taking function instead
- */
- @Deprecated
- public static int createSimValueEnum(
- int device, String name, boolean readonly, String[] options, int initialValue) {
- return createSimValueEnum(device, name, readonly ? kOutput : kInput, options, initialValue);
- }
-
- /**
- * Creates an enumerated value on a simulated device.
- *
- * <p>Enumerated values are always in the range 0 to numOptions-1.
- *
- * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
- *
- * @param device simulated device handle
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param options array of option descriptions
* @param initialValue initial value (selection)
@@ -214,25 +150,6 @@
*
* @param device simulated device handle
* @param name value name
- * @param readonly if the value should not be written from simulation side
- * @param initialValue initial value
- * @return simulated value handle
- * @deprecated Use direction-taking function instead
- */
- @Deprecated
- public static int createSimValueBoolean(
- int device, String name, boolean readonly, boolean initialValue) {
- return createSimValueNative(
- device, name, readonly ? kOutput : kInput, HALValue.kBoolean, initialValue ? 1 : 0, 0.0);
- }
-
- /**
- * Creates a boolean value on a simulated device.
- *
- * <p>Returns 0 if not in simulation; this can be used to avoid calls to Set/Get functions.
- *
- * @param device simulated device handle
- * @param name value name
* @param direction input/output/bidir (from perspective of user code)
* @param initialValue initial value
* @return simulated value handle
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java b/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java
index b4f344f..e0734dd 100644
--- a/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java
@@ -4,11 +4,12 @@
package edu.wpi.first.hal.can;
+import edu.wpi.first.hal.CANStreamMessage;
import edu.wpi.first.hal.JNIWrapper;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
-@SuppressWarnings("AbbreviationAsWordInName")
+@SuppressWarnings("MethodName")
public class CANJNI extends JNIWrapper {
public static final int CAN_SEND_PERIOD_NO_REPEAT = 0;
public static final int CAN_SEND_PERIOD_STOP_REPEATING = -1;
@@ -17,14 +18,18 @@
public static final int CAN_IS_FRAME_REMOTE = 0x80000000;
public static final int CAN_IS_FRAME_11BIT = 0x40000000;
- @SuppressWarnings("MethodName")
public static native void FRCNetCommCANSessionMuxSendMessage(
int messageID, byte[] data, int periodMs);
- @SuppressWarnings("MethodName")
public static native byte[] FRCNetCommCANSessionMuxReceiveMessage(
IntBuffer messageID, int messageIDMask, ByteBuffer timeStamp);
- @SuppressWarnings("MethodName")
public static native void getCANStatus(CANStatus status);
+
+ public static native int openCANStreamSession(int messageID, int messageIDMask, int maxMessages);
+
+ public static native void closeCANStreamSession(int sessionHandle);
+
+ public static native int readCANStreamSession(
+ int sessionHandle, CANStreamMessage[] messages, int messagesToRead);
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java b/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java
index 62df8e8..8ec89f7 100644
--- a/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java
@@ -5,28 +5,32 @@
package edu.wpi.first.hal.can;
/** Structure for holding the result of a CAN Status request. */
+@SuppressWarnings("MemberName")
public class CANStatus {
/** The utilization of the CAN Bus. */
- @SuppressWarnings("MemberName")
public double percentBusUtilization;
/** The CAN Bus off count. */
- @SuppressWarnings("MemberName")
public int busOffCount;
/** The CAN Bus TX full count. */
- @SuppressWarnings("MemberName")
public int txFullCount;
/** The CAN Bus receive error count. */
- @SuppressWarnings("MemberName")
public int receiveErrorCount;
/** The CAN Bus transmit error count. */
- @SuppressWarnings("MemberName")
public int transmitErrorCount;
- @SuppressWarnings("MissingJavadocMethod")
+ /**
+ * Set CAN bus status.
+ *
+ * @param percentBusUtilization CAN bus utilization as a percent.
+ * @param busOffCount Bus off event count.
+ * @param txFullCount TX buffer full event count.
+ * @param receiveErrorCount Receive error event count.
+ * @param transmitErrorCount Transmit error event count.
+ */
public void setStatus(
double percentBusUtilization,
int busOffCount,
diff --git a/hal/src/main/java/edu/wpi/first/hal/simulation/CTREPCMDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/simulation/CTREPCMDataJNI.java
index 9f60e7e..6d94438 100644
--- a/hal/src/main/java/edu/wpi/first/hal/simulation/CTREPCMDataJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/simulation/CTREPCMDataJNI.java
@@ -6,7 +6,6 @@
import edu.wpi.first.hal.JNIWrapper;
-@SuppressWarnings("AbbreviationAsWordInName")
public class CTREPCMDataJNI extends JNIWrapper {
public static native int registerInitializedCallback(
int index, NotifyCallback callback, boolean initialNotify);
diff --git a/hal/src/main/java/edu/wpi/first/hal/simulation/REVPHDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/simulation/REVPHDataJNI.java
index ee801f3..96b9701 100644
--- a/hal/src/main/java/edu/wpi/first/hal/simulation/REVPHDataJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/simulation/REVPHDataJNI.java
@@ -6,7 +6,6 @@
import edu.wpi.first.hal.JNIWrapper;
-@SuppressWarnings("AbbreviationAsWordInName")
public class REVPHDataJNI extends JNIWrapper {
public static native int registerInitializedCallback(
int index, NotifyCallback callback, boolean initialNotify);
diff --git a/hal/src/main/java/edu/wpi/first/hal/simulation/RoboRioDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/simulation/RoboRioDataJNI.java
index a822ede..ef06067 100644
--- a/hal/src/main/java/edu/wpi/first/hal/simulation/RoboRioDataJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/simulation/RoboRioDataJNI.java
@@ -7,17 +7,13 @@
import edu.wpi.first.hal.JNIWrapper;
public class RoboRioDataJNI extends JNIWrapper {
- @SuppressWarnings("AbbreviationAsWordInName")
public static native int registerFPGAButtonCallback(
NotifyCallback callback, boolean initialNotify);
- @SuppressWarnings("AbbreviationAsWordInName")
public static native void cancelFPGAButtonCallback(int uid);
- @SuppressWarnings("AbbreviationAsWordInName")
public static native boolean getFPGAButton();
- @SuppressWarnings("AbbreviationAsWordInName")
public static native void setFPGAButton(boolean fPGAButton);
public static native int registerVInVoltageCallback(
@@ -155,5 +151,13 @@
public static native void setBrownoutVoltage(double brownoutVoltage);
+ public static native String getSerialNumber();
+
+ public static native void setSerialNumber(String serialNumber);
+
+ public static native String getComments();
+
+ public static native void setComments(String comments);
+
public static native void resetData();
}
diff --git a/hal/src/main/java/edu/wpi/first/hal/simulation/SimDeviceDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/simulation/SimDeviceDataJNI.java
index ef6536a..092b955 100644
--- a/hal/src/main/java/edu/wpi/first/hal/simulation/SimDeviceDataJNI.java
+++ b/hal/src/main/java/edu/wpi/first/hal/simulation/SimDeviceDataJNI.java
@@ -28,18 +28,21 @@
public static native int getSimValueDeviceHandle(int handle);
+ @SuppressWarnings("MemberName")
public static class SimDeviceInfo {
- @SuppressWarnings("JavadocMethod")
+ public String name;
+ public int handle;
+
+ /**
+ * SimDeviceInfo constructor.
+ *
+ * @param name SimDevice name.
+ * @param handle SimDevice handle.
+ */
public SimDeviceInfo(String name, int handle) {
this.name = name;
this.handle = handle;
}
-
- @SuppressWarnings("MemberName")
- public String name;
-
- @SuppressWarnings("MemberName")
- public int handle;
}
public static native SimDeviceInfo[] enumerateSimDevices(String prefix);
@@ -70,32 +73,30 @@
public static native int getSimValueHandle(int device, String name);
+ @SuppressWarnings("MemberName")
public static class SimValueInfo {
- @SuppressWarnings("JavadocMethod")
+ public String name;
+ public int handle;
+ public int direction;
+ public HALValue value;
+
+ /**
+ * SimValueInfo constructor.
+ *
+ * @param name SimValue name.
+ * @param handle SimValue handle.
+ * @param direction SimValue direction.
+ * @param type SimValue type.
+ * @param value1 Value 1.
+ * @param value2 Value 2.
+ */
public SimValueInfo(
String name, int handle, int direction, int type, long value1, double value2) {
this.name = name;
this.handle = handle;
- this.readonly = direction == 1;
this.direction = direction;
this.value = HALValue.fromNative(type, value1, value2);
}
-
- @SuppressWarnings("MemberName")
- public String name;
-
- @SuppressWarnings("MemberName")
- public int handle;
-
- @SuppressWarnings("MemberName")
- @Deprecated
- public boolean readonly;
-
- @SuppressWarnings("MemberName")
- public int direction;
-
- @SuppressWarnings("MemberName")
- public HALValue value;
}
public static native SimValueInfo[] enumerateSimValues(int device);
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java b/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java
index e9f9a91..3591a5f 100644
--- a/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java
+++ b/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java
@@ -5,7 +5,6 @@
package edu.wpi.first.hal.util;
/** Exception indicating that the resource is already allocated. */
-@SuppressWarnings("serial")
public class AllocationException extends RuntimeException {
/**
* Create a new AllocationException.
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java b/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java
index 683980d..bbecbbe 100644
--- a/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java
+++ b/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java
@@ -7,7 +7,6 @@
/**
* This exception represents an error in which a lower limit was set as higher than an upper limit.
*/
-@SuppressWarnings("serial")
public class BoundaryException extends RuntimeException {
/**
* Create a new exception with the given message.
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java b/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java
index 6155f17..81de150 100644
--- a/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java
+++ b/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java
@@ -8,7 +8,6 @@
* Exception indicating that the resource is already allocated This is meant to be thrown by the
* resource class.
*/
-@SuppressWarnings("serial")
public class CheckedAllocationException extends Exception {
/**
* Create a new CheckedAllocationException.
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java b/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java
index 65c11f5..aee93bb 100644
--- a/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java
+++ b/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java
@@ -5,7 +5,6 @@
package edu.wpi.first.hal.util;
/** Exception indicating that an error has occurred with a HAL Handle. */
-@SuppressWarnings("serial")
public class HalHandleException extends RuntimeException {
/**
* Create a new HalHandleException.
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java b/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java
index 90650fc..7be73b4 100644
--- a/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java
+++ b/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java
@@ -5,7 +5,6 @@
package edu.wpi.first.hal.util;
/** Exception for bad status codes from the chip object. */
-@SuppressWarnings("serial")
public final class UncleanStatusException extends IllegalStateException {
private final int m_statusCode;
diff --git a/hal/src/main/native/athena/Accelerometer.cpp b/hal/src/main/native/athena/Accelerometer.cpp
index 73b1357..b8cc832 100644
--- a/hal/src/main/native/athena/Accelerometer.cpp
+++ b/hal/src/main/native/athena/Accelerometer.cpp
@@ -121,8 +121,9 @@
// Execute and wait until it's done (up to a millisecond)
initialTime = HAL_GetFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
- if (HAL_GetFPGATime(&status) > initialTime + 1000)
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) {
break;
+ }
}
// Send a stop transmit/receive message with the data
@@ -133,8 +134,9 @@
// Execute and wait until it's done (up to a millisecond)
initialTime = HAL_GetFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
- if (HAL_GetFPGATime(&status) > initialTime + 1000)
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) {
break;
+ }
}
}
@@ -151,8 +153,9 @@
// Execute and wait until it's done (up to a millisecond)
initialTime = HAL_GetFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
- if (HAL_GetFPGATime(&status) > initialTime + 1000)
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) {
break;
+ }
}
// Receive a message with the data and stop
@@ -163,8 +166,9 @@
// Execute and wait until it's done (up to a millisecond)
initialTime = HAL_GetFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
- if (HAL_GetFPGATime(&status) > initialTime + 1000)
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) {
break;
+ }
}
return accel->readDATI(&status);
diff --git a/hal/src/main/native/athena/AddressableLED.cpp b/hal/src/main/native/athena/AddressableLED.cpp
index 74a323a..5e55c93 100644
--- a/hal/src/main/native/athena/AddressableLED.cpp
+++ b/hal/src/main/native/athena/AddressableLED.cpp
@@ -6,11 +6,11 @@
#include <cstring>
-#include <FRC_FPGA_ChipObject/fpgainterfacecapi/NiFpga_HMB.h>
#include <fmt/format.h>
#include "ConstantsInternal.h"
#include "DigitalInternal.h"
+#include "FPGACalls.h"
#include "HALInitializer.h"
#include "HALInternal.h"
#include "PortsInternal.h"
@@ -44,6 +44,8 @@
}
} // namespace hal::init
+static constexpr const char* HmbName = "HMB_0_LED";
+
extern "C" {
HAL_AddressableLEDHandle HAL_InitializeAddressableLED(
@@ -101,8 +103,8 @@
uint32_t session = led->led->getSystemInterface()->getHandle();
- *status = NiFpga_OpenHostMemoryBuffer(session, "HMB_0_LED", &led->ledBuffer,
- &led->ledBufferSize);
+ *status = hal::HAL_NiFpga_OpenHmb(session, HmbName, &led->ledBufferSize,
+ &led->ledBuffer);
if (*status != 0) {
addressableLEDHandles->Free(handle);
@@ -113,6 +115,12 @@
}
void HAL_FreeAddressableLED(HAL_AddressableLEDHandle handle) {
+ auto led = addressableLEDHandles->Get(handle);
+ if (!led) {
+ return;
+ }
+ uint32_t session = led->led->getSystemInterface()->getHandle();
+ hal::HAL_NiFpga_CloseHmb(session, HmbName);
addressableLEDHandles->Free(handle);
}
diff --git a/hal/src/main/native/athena/AnalogAccumulator.cpp b/hal/src/main/native/athena/AnalogAccumulator.cpp
index 7ff7d47..32688a0 100644
--- a/hal/src/main/native/athena/AnalogAccumulator.cpp
+++ b/hal/src/main/native/athena/AnalogAccumulator.cpp
@@ -23,8 +23,9 @@
return false;
}
for (int32_t i = 0; i < kNumAccumulators; i++) {
- if (port->channel == kAccumulatorChannels[i])
+ if (port->channel == kAccumulatorChannels[i]) {
return true;
+ }
}
return false;
}
diff --git a/hal/src/main/native/athena/AnalogTrigger.cpp b/hal/src/main/native/athena/AnalogTrigger.cpp
index d9e2b92..47ef4f2 100644
--- a/hal/src/main/native/athena/AnalogTrigger.cpp
+++ b/hal/src/main/native/athena/AnalogTrigger.cpp
@@ -5,6 +5,7 @@
#include "hal/AnalogTrigger.h"
#include "AnalogInternal.h"
+#include "ConstantsInternal.h"
#include "DutyCycleInternal.h"
#include "HALInitializer.h"
#include "HALInternal.h"
@@ -147,16 +148,10 @@
return;
}
- int32_t scaleFactor =
- HAL_GetDutyCycleOutputScaleFactor(trigger->handle, status);
- if (*status != 0) {
- return;
- }
-
- trigger->trigger->writeLowerLimit(static_cast<int32_t>(scaleFactor * lower),
- status);
- trigger->trigger->writeUpperLimit(static_cast<int32_t>(scaleFactor * upper),
- status);
+ trigger->trigger->writeLowerLimit(
+ static_cast<int32_t>(kDutyCycleScaleFactor * lower), status);
+ trigger->trigger->writeUpperLimit(
+ static_cast<int32_t>(kDutyCycleScaleFactor * upper), status);
}
void HAL_SetAnalogTriggerLimitsVoltage(
diff --git a/hal/src/main/native/athena/CANAPI.cpp b/hal/src/main/native/athena/CANAPI.cpp
index a7c5b37..a3e4904 100644
--- a/hal/src/main/native/athena/CANAPI.cpp
+++ b/hal/src/main/native/athena/CANAPI.cpp
@@ -85,6 +85,9 @@
void HAL_CleanCAN(HAL_CANHandle handle) {
auto data = canHandles->Free(handle);
+ if (data == nullptr) {
+ return;
+ }
std::scoped_lock lock(data->mapMutex);
diff --git a/hal/src/main/native/athena/CTREPCM.cpp b/hal/src/main/native/athena/CTREPCM.cpp
index 37faf69..79c1ae3 100644
--- a/hal/src/main/native/athena/CTREPCM.cpp
+++ b/hal/src/main/native/athena/CTREPCM.cpp
@@ -233,9 +233,11 @@
return;
}
+ int32_t can_status = 0;
+
std::scoped_lock lock{pcm->lock};
pcm->control.bits.closedLoopEnable = enabled ? 1 : 0;
- SendControl(pcm.get(), status);
+ SendControl(pcm.get(), &can_status);
}
HAL_Bool HAL_GetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle,
@@ -394,9 +396,8 @@
}
std::scoped_lock lock{pcm->lock};
- pcm->oneShot.sol10MsPerUnit[index] =
- (std::min)(static_cast<uint32_t>(durMs) / 10,
- static_cast<uint32_t>(0xFF));
+ pcm->oneShot.sol10MsPerUnit[index] = (std::min)(
+ static_cast<uint32_t>(durMs) / 10, static_cast<uint32_t>(0xFF));
HAL_WriteCANPacketRepeating(pcm->canHandle, pcm->oneShot.sol10MsPerUnit, 8,
Control3, SendPeriod, status);
}
diff --git a/hal/src/main/native/athena/ConstantsInternal.h b/hal/src/main/native/athena/ConstantsInternal.h
index 21fece4..ca7241c 100644
--- a/hal/src/main/native/athena/ConstantsInternal.h
+++ b/hal/src/main/native/athena/ConstantsInternal.h
@@ -9,5 +9,6 @@
namespace hal {
constexpr int32_t kSystemClockTicksPerMicrosecond = 40;
+constexpr int32_t kDutyCycleScaleFactor = 4e7 - 1;
} // namespace hal
diff --git a/hal/src/main/native/athena/DIO.cpp b/hal/src/main/native/athena/DIO.cpp
index 7b26dd1..e6308fb 100644
--- a/hal/src/main/native/athena/DIO.cpp
+++ b/hal/src/main/native/athena/DIO.cpp
@@ -133,8 +133,9 @@
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.
- if (port == nullptr)
+ if (port == nullptr) {
return;
+ }
digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
// Wait for no other object to hold this handle.
@@ -239,6 +240,30 @@
}
}
+void HAL_SetDigitalPWMPPS(HAL_DigitalPWMHandle pwmGenerator, double dutyCycle,
+ int32_t* status) {
+ auto port = digitalPWMHandles->Get(pwmGenerator);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ int32_t id = *port;
+ digitalSystem->writePWMPeriodPower(0xffff, status);
+ double rawDutyCycle = 31.0 * dutyCycle;
+ if (rawDutyCycle > 30.5) {
+ rawDutyCycle = 30.5;
+ }
+ {
+ std::scoped_lock lock(digitalPwmMutex);
+ if (id < 4)
+ digitalSystem->writePWMDutyCycleA(id, static_cast<uint8_t>(rawDutyCycle),
+ status);
+ else
+ digitalSystem->writePWMDutyCycleB(
+ id - 4, static_cast<uint8_t>(rawDutyCycle), status);
+ }
+}
+
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
@@ -407,13 +432,24 @@
}
}
-void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
+void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLengthSeconds,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
+
+ uint32_t pulseLengthMicroseconds =
+ static_cast<uint32_t>(pulseLengthSeconds * 1e6);
+
+ if (pulseLengthMicroseconds <= 0 || pulseLengthMicroseconds > 0xFFFF) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ hal::SetLastError(status,
+ "Length must be between 1 and 65535 microseconds");
+ return;
+ }
+
tDIO::tPulse pulse;
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
@@ -425,9 +461,29 @@
}
digitalSystem->writePulseLength(
- static_cast<uint16_t>(1.0e9 * pulseLength /
- (pwmSystem->readLoopTiming(status) * 25)),
- status);
+ static_cast<uint16_t>(pulseLengthMicroseconds), status);
+ digitalSystem->writePulse(pulse, status);
+}
+
+void HAL_PulseMultiple(uint32_t channelMask, double pulseLengthSeconds,
+ int32_t* status) {
+ uint32_t pulseLengthMicroseconds =
+ static_cast<uint32_t>(pulseLengthSeconds * 1e6);
+
+ if (pulseLengthMicroseconds <= 0 || pulseLengthMicroseconds > 0xFFFF) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ hal::SetLastError(status,
+ "Length must be between 1 and 65535 microseconds");
+ return;
+ }
+
+ tDIO::tPulse pulse;
+ pulse.Headers = channelMask & 0x2FF;
+ pulse.MXP = (channelMask & 0xFFFF) >> 10;
+ pulse.SPIPort = (channelMask & 0x1F) >> 26;
+
+ digitalSystem->writePulseLength(
+ static_cast<uint16_t>(pulseLengthMicroseconds), status);
digitalSystem->writePulse(pulse, status);
}
diff --git a/hal/src/main/native/athena/DMA.cpp b/hal/src/main/native/athena/DMA.cpp
index f7d8b08..23e9264 100644
--- a/hal/src/main/native/athena/DMA.cpp
+++ b/hal/src/main/native/athena/DMA.cpp
@@ -130,8 +130,9 @@
auto dma = dmaHandles->Get(handle);
dmaHandles->Free(handle);
- if (!dma)
+ if (!dma) {
return;
+ }
int32_t status = 0;
if (dma->manager) {
@@ -709,6 +710,9 @@
void* HAL_GetDMADirectPointer(HAL_DMAHandle handle) {
auto dma = dmaHandles->Get(handle);
+ if (dma == nullptr) {
+ return nullptr;
+ }
return dma.get();
}
diff --git a/hal/src/main/native/athena/DigitalInternal.cpp b/hal/src/main/native/athena/DigitalInternal.cpp
index 63ea0aa..b9339ee 100644
--- a/hal/src/main/native/athena/DigitalInternal.cpp
+++ b/hal/src/main/native/athena/DigitalInternal.cpp
@@ -98,8 +98,9 @@
// Make sure that the 9403 IONode has had a chance to initialize before
// continuing.
- while (pwmSystem->readLoopTiming(status) == 0)
+ while (pwmSystem->readLoopTiming(status) == 0) {
std::this_thread::yield();
+ }
if (pwmSystem->readLoopTiming(status) != kExpectedLoopTiming) {
*status = LOOP_TIMING_ERROR; // NOTE: Doesn't display the error
diff --git a/hal/src/main/native/athena/DigitalInternal.h b/hal/src/main/native/athena/DigitalInternal.h
index 6b1e909..685987a 100644
--- a/hal/src/main/native/athena/DigitalInternal.h
+++ b/hal/src/main/native/athena/DigitalInternal.h
@@ -38,7 +38,7 @@
* reliably down to 10.0 ms; starting at about 8.5ms, the servo sometimes hums
* and get hot; by 5.0ms the hum is nearly continuous
* - 10ms periods work well for Victor 884
- * - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
+ * - 5ms periods allows higher update rates for Luminary Micro Jaguar motor
* controllers. Due to the shipping firmware on the Jaguar, we can't run the
* update period less than 5.05 ms.
*
diff --git a/hal/src/main/native/athena/DutyCycle.cpp b/hal/src/main/native/athena/DutyCycle.cpp
index 6d70570..4df14cb 100644
--- a/hal/src/main/native/athena/DutyCycle.cpp
+++ b/hal/src/main/native/athena/DutyCycle.cpp
@@ -6,6 +6,7 @@
#include <memory>
+#include "ConstantsInternal.h"
#include "DigitalInternal.h"
#include "DutyCycleInternal.h"
#include "HALInitializer.h"
@@ -30,8 +31,6 @@
} // namespace init
} // namespace hal
-static constexpr int32_t kScaleFactor = 4e7 - 1;
-
extern "C" {
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType triggerType,
@@ -90,12 +89,6 @@
double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
int32_t* status) {
- return HAL_GetDutyCycleOutputRaw(dutyCycleHandle, status) /
- static_cast<double>(kScaleFactor);
-}
-
-int32_t HAL_GetDutyCycleOutputRaw(HAL_DutyCycleHandle dutyCycleHandle,
- int32_t* status) {
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
if (!dutyCycle) {
*status = HAL_HANDLE_ERROR;
@@ -104,12 +97,31 @@
// TODO Handle Overflow
unsigned char overflow = 0;
- return dutyCycle->dutyCycle->readOutput(&overflow, status);
+ uint32_t output = dutyCycle->dutyCycle->readOutput(&overflow, status);
+ return output / static_cast<double>(kDutyCycleScaleFactor);
+}
+
+int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
+ if (!dutyCycle) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ // TODO Handle Overflow
+ unsigned char overflow = 0;
+ uint32_t highTime = dutyCycle->dutyCycle->readHighTicks(&overflow, status);
+ if (*status != 0) {
+ return 0;
+ }
+ // Output will be at max 4e7, so x25 will still fit in a 32 bit signed int.
+ return highTime * 25;
}
int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,
int32_t* status) {
- return kScaleFactor;
+ return kDutyCycleScaleFactor;
}
int32_t HAL_GetDutyCycleFPGAIndex(HAL_DutyCycleHandle dutyCycleHandle,
diff --git a/hal/src/main/native/athena/FPGACalls.cpp b/hal/src/main/native/athena/FPGACalls.cpp
new file mode 100644
index 0000000..0b04019
--- /dev/null
+++ b/hal/src/main/native/athena/FPGACalls.cpp
@@ -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.
+
+#include "FPGACalls.h"
+
+#include <cerrno>
+
+#include "dlfcn.h"
+#include "hal/Errors.h"
+
+static void* NiFpgaLibrary = nullptr;
+
+namespace hal {
+HAL_NiFpga_ReserveIrqContextFunc HAL_NiFpga_ReserveIrqContext;
+HAL_NiFpga_UnreserveIrqContextFunc HAL_NiFpga_UnreserveIrqContext;
+HAL_NiFpga_WaitOnIrqsFunc HAL_NiFpga_WaitOnIrqs;
+HAL_NiFpga_AcknowledgeIrqsFunc HAL_NiFpga_AcknowledgeIrqs;
+HAL_NiFpga_OpenHmbFunc HAL_NiFpga_OpenHmb;
+HAL_NiFpga_CloseHmbFunc HAL_NiFpga_CloseHmb;
+
+namespace init {
+int InitializeFPGA() {
+ NiFpgaLibrary = dlopen("libNiFpga.so", RTLD_LAZY);
+ if (!NiFpgaLibrary) {
+ return errno;
+ }
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+ HAL_NiFpga_ReserveIrqContext =
+ reinterpret_cast<HAL_NiFpga_ReserveIrqContextFunc>(
+ dlsym(NiFpgaLibrary, "NiFpgaDll_ReserveIrqContext"));
+ HAL_NiFpga_UnreserveIrqContext =
+ reinterpret_cast<HAL_NiFpga_UnreserveIrqContextFunc>(
+ dlsym(NiFpgaLibrary, "NiFpgaDll_UnreserveIrqContext"));
+ HAL_NiFpga_WaitOnIrqs = reinterpret_cast<HAL_NiFpga_WaitOnIrqsFunc>(
+ dlsym(NiFpgaLibrary, "NiFpgaDll_WaitOnIrqs"));
+ HAL_NiFpga_AcknowledgeIrqs = reinterpret_cast<HAL_NiFpga_AcknowledgeIrqsFunc>(
+ dlsym(NiFpgaLibrary, "NiFpgaDll_AcknowledgeIrqs"));
+ HAL_NiFpga_OpenHmb = reinterpret_cast<HAL_NiFpga_OpenHmbFunc>(
+ dlsym(NiFpgaLibrary, "NiFpgaDll_OpenHmb"));
+ HAL_NiFpga_CloseHmb = reinterpret_cast<HAL_NiFpga_CloseHmbFunc>(
+ dlsym(NiFpgaLibrary, "NiFpgaDll_CloseHmb"));
+#pragma GCC diagnostic pop
+
+ if (HAL_NiFpga_ReserveIrqContext == nullptr ||
+ HAL_NiFpga_UnreserveIrqContext == nullptr ||
+ HAL_NiFpga_WaitOnIrqs == nullptr ||
+ HAL_NiFpga_AcknowledgeIrqs == nullptr || HAL_NiFpga_OpenHmb == nullptr ||
+ HAL_NiFpga_CloseHmb == nullptr) {
+ HAL_NiFpga_ReserveIrqContext = nullptr;
+ HAL_NiFpga_UnreserveIrqContext = nullptr;
+ HAL_NiFpga_WaitOnIrqs = nullptr;
+ HAL_NiFpga_AcknowledgeIrqs = nullptr;
+ HAL_NiFpga_OpenHmb = nullptr;
+ HAL_NiFpga_CloseHmb = nullptr;
+ dlclose(NiFpgaLibrary);
+ NiFpgaLibrary = nullptr;
+ return NO_AVAILABLE_RESOURCES;
+ }
+
+ return HAL_SUCCESS;
+}
+} // namespace init
+} // namespace hal
diff --git a/hal/src/main/native/athena/FPGACalls.h b/hal/src/main/native/athena/FPGACalls.h
new file mode 100644
index 0000000..46e8ac4
--- /dev/null
+++ b/hal/src/main/native/athena/FPGACalls.h
@@ -0,0 +1,46 @@
+// 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 <FRC_FPGA_ChipObject/fpgainterfacecapi/NiFpga.h>
+
+namespace hal {
+namespace init {
+[[nodiscard]] int InitializeFPGA();
+} // namespace init
+
+using HAL_NiFpga_ReserveIrqContextFunc =
+ NiFpga_Status (*)(NiFpga_Session session, NiFpga_IrqContext* context);
+
+extern HAL_NiFpga_ReserveIrqContextFunc HAL_NiFpga_ReserveIrqContext;
+
+using HAL_NiFpga_UnreserveIrqContextFunc =
+ NiFpga_Status (*)(NiFpga_Session session, NiFpga_IrqContext context);
+
+extern HAL_NiFpga_UnreserveIrqContextFunc HAL_NiFpga_UnreserveIrqContext;
+
+using HAL_NiFpga_WaitOnIrqsFunc = NiFpga_Status (*)(
+ NiFpga_Session session, NiFpga_IrqContext context, uint32_t irqs,
+ uint32_t timeout, uint32_t* irqsAsserted, NiFpga_Bool* timedOut);
+
+extern HAL_NiFpga_WaitOnIrqsFunc HAL_NiFpga_WaitOnIrqs;
+
+using HAL_NiFpga_AcknowledgeIrqsFunc = NiFpga_Status (*)(NiFpga_Session session,
+ uint32_t irqs);
+
+extern HAL_NiFpga_AcknowledgeIrqsFunc HAL_NiFpga_AcknowledgeIrqs;
+
+using HAL_NiFpga_OpenHmbFunc = NiFpga_Status (*)(const NiFpga_Session session,
+ const char* memoryName,
+ size_t* memorySize,
+ void** virtualAddress);
+
+extern HAL_NiFpga_OpenHmbFunc HAL_NiFpga_OpenHmb;
+
+using HAL_NiFpga_CloseHmbFunc = NiFpga_Status (*)(const NiFpga_Session session,
+ const char* memoryName);
+
+extern HAL_NiFpga_CloseHmbFunc HAL_NiFpga_CloseHmb;
+} // namespace hal
diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp
index e7ef194..e8db9a5 100644
--- a/hal/src/main/native/athena/FRCDriverStation.cpp
+++ b/hal/src/main/native/athena/FRCDriverStation.cpp
@@ -13,39 +13,65 @@
#include <FRC_NetworkCommunication/FRCComm.h>
#include <FRC_NetworkCommunication/NetCommRPCProxy_Occur.h>
#include <fmt/format.h>
+#include <wpi/EventVector.h>
#include <wpi/SafeThread.h>
+#include <wpi/SmallVector.h>
#include <wpi/condition_variable.h>
#include <wpi/mutex.h>
+#include "HALInitializer.h"
#include "hal/DriverStation.h"
+#include "hal/Errors.h"
static_assert(sizeof(int32_t) >= sizeof(int),
"FRC_NetworkComm status variable is larger than 32 bits");
+namespace {
struct HAL_JoystickAxesInt {
int16_t count;
int16_t axes[HAL_kMaxJoystickAxes];
};
+} // namespace
-static constexpr int kJoystickPorts = 6;
+namespace {
+struct JoystickDataCache {
+ JoystickDataCache() { std::memset(this, 0, sizeof(*this)); }
+ void Update();
+
+ HAL_JoystickAxes axes[HAL_kMaxJoysticks];
+ HAL_JoystickPOVs povs[HAL_kMaxJoysticks];
+ HAL_JoystickButtons buttons[HAL_kMaxJoysticks];
+ HAL_AllianceStationID allianceStation;
+ float matchTime;
+};
+static_assert(std::is_standard_layout_v<JoystickDataCache>);
+// static_assert(std::is_trivial_v<JoystickDataCache>);
+
+struct FRCDriverStation {
+ wpi::EventVector newDataEvents;
+};
+} // namespace
+
+static ::FRCDriverStation* driverStation;
// Message and Data variables
static wpi::mutex msgMutex;
static int32_t HAL_GetJoystickAxesInternal(int32_t joystickNum,
HAL_JoystickAxes* axes) {
- HAL_JoystickAxesInt axesInt;
+ HAL_JoystickAxesInt netcommAxes;
int retVal = FRC_NetworkCommunication_getJoystickAxes(
- joystickNum, reinterpret_cast<JoystickAxes_t*>(&axesInt),
+ joystickNum, reinterpret_cast<JoystickAxes_t*>(&netcommAxes),
HAL_kMaxJoystickAxes);
// copy integer values to double values
- axes->count = axesInt.count;
+ axes->count = netcommAxes.count;
// current scaling is -128 to 127, can easily be patched in the future by
// changing this function.
- for (int32_t i = 0; i < axesInt.count; i++) {
- int8_t value = axesInt.axes[i];
+ for (int32_t i = 0; i < netcommAxes.count; i++) {
+ int8_t value = netcommAxes.axes[i];
+ axes->raw[i] = value;
if (value < 0) {
axes->axes[i] = value / 128.0;
} else {
@@ -68,6 +94,32 @@
return FRC_NetworkCommunication_getJoystickButtons(
joystickNum, &buttons->buttons, &buttons->count);
}
+
+void JoystickDataCache::Update() {
+ for (int i = 0; i < HAL_kMaxJoysticks; i++) {
+ HAL_GetJoystickAxesInternal(i, &axes[i]);
+ HAL_GetJoystickPOVsInternal(i, &povs[i]);
+ HAL_GetJoystickButtonsInternal(i, &buttons[i]);
+ }
+ FRC_NetworkCommunication_getAllianceStation(
+ reinterpret_cast<AllianceStationID_t*>(&allianceStation));
+ FRC_NetworkCommunication_getMatchTime(&matchTime);
+}
+
+#define CHECK_JOYSTICK_NUMBER(stickNum) \
+ if ((stickNum) < 0 || (stickNum) >= HAL_kMaxJoysticks) \
+ return PARAMETER_OUT_OF_RANGE
+
+static HAL_ControlWord newestControlWord;
+static JoystickDataCache caches[3];
+static JoystickDataCache* currentRead = &caches[0];
+static JoystickDataCache* currentReadLocal = &caches[0];
+static std::atomic<JoystickDataCache*> currentCache{&caches[1]};
+static JoystickDataCache* lastGiven = &caches[1];
+static JoystickDataCache* cacheToUpdate = &caches[2];
+
+static wpi::mutex cacheMutex;
+
/**
* Retrieve the Joystick Descriptor for particular slot.
*
@@ -102,12 +154,6 @@
return retval;
}
-static int32_t HAL_GetControlWordInternal(HAL_ControlWord* controlWord) {
- std::memset(controlWord, 0, sizeof(HAL_ControlWord));
- return FRC_NetworkCommunication_getControlWord(
- reinterpret_cast<ControlWord_t*>(controlWord));
-}
-
static int32_t HAL_GetMatchInfoInternal(HAL_MatchInfo* info) {
MatchType_t matchType = MatchType_t::kMatchType_none;
info->gameSpecificMessageSize = sizeof(info->gameSpecificMessage);
@@ -126,19 +172,55 @@
return status;
}
-static wpi::mutex* newDSDataAvailableMutex;
-static wpi::condition_variable* newDSDataAvailableCond;
-static int newDSDataAvailableCounter{0};
+namespace {
+struct TcpCache {
+ TcpCache() { std::memset(this, 0, sizeof(*this)); }
+ void Update(uint32_t mask);
+ void CloneTo(TcpCache* other) { std::memcpy(other, this, sizeof(*this)); }
+
+ HAL_MatchInfo matchInfo;
+ HAL_JoystickDescriptor descriptors[HAL_kMaxJoysticks];
+};
+static_assert(std::is_standard_layout_v<TcpCache>);
+} // namespace
+
+static std::atomic_uint32_t tcpMask{0xFFFFFFFF};
+static TcpCache tcpCache;
+static TcpCache tcpCurrent;
+static wpi::mutex tcpCacheMutex;
+
+constexpr uint32_t combinedMatchInfoMask = kTcpRecvMask_MatchInfoOld |
+ kTcpRecvMask_MatchInfo |
+ kTcpRecvMask_GameSpecific;
+
+void TcpCache::Update(uint32_t mask) {
+ if ((mask & combinedMatchInfoMask) != 0) {
+ HAL_GetMatchInfoInternal(&matchInfo);
+ }
+ for (int i = 0; i < HAL_kMaxJoysticks; i++) {
+ if ((mask & (1 << i)) != 0) {
+ HAL_GetJoystickDescriptorInternal(i, &descriptors[i]);
+ }
+ }
+}
namespace hal::init {
void InitializeFRCDriverStation() {
- static wpi::mutex newMutex;
- newDSDataAvailableMutex = &newMutex;
- static wpi::condition_variable newCond;
- newDSDataAvailableCond = &newCond;
+ std::memset(&newestControlWord, 0, sizeof(newestControlWord));
+ static FRCDriverStation ds;
+ driverStation = &ds;
}
} // namespace hal::init
+namespace hal {
+static void DefaultPrintErrorImpl(const char* line, size_t size) {
+ std::fwrite(line, size, 1, stderr);
+}
+} // namespace hal
+
+static std::atomic<void (*)(const char* line, size_t size)> gPrintErrorImpl{
+ hal::DefaultPrintErrorImpl};
+
extern "C" {
int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
@@ -216,7 +298,8 @@
if (callStack && callStack[0] != '\0') {
fmt::format_to(fmt::appender{buf}, "{}\n", callStack);
}
- std::fwrite(buf.data(), buf.size(), 1, stderr);
+ auto printError = gPrintErrorImpl.load();
+ printError(buf.data(), buf.size());
}
if (i == KEEP_MSGS) {
// replace the oldest one
@@ -235,6 +318,10 @@
return retval;
}
+void HAL_SetPrintErrorImpl(void (*func)(const char* line, size_t size)) {
+ gPrintErrorImpl.store(func ? func : hal::DefaultPrintErrorImpl);
+}
+
int32_t HAL_SendConsoleLine(const char* line) {
std::string_view lineRef{line};
if (lineRef.size() <= 65535) {
@@ -248,36 +335,58 @@
}
int32_t HAL_GetControlWord(HAL_ControlWord* controlWord) {
- return HAL_GetControlWordInternal(controlWord);
+ std::scoped_lock lock{cacheMutex};
+ *controlWord = newestControlWord;
+ return 0;
}
int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes) {
- return HAL_GetJoystickAxesInternal(joystickNum, axes);
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{cacheMutex};
+ *axes = currentRead->axes[joystickNum];
+ return 0;
}
int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
- return HAL_GetJoystickPOVsInternal(joystickNum, povs);
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{cacheMutex};
+ *povs = currentRead->povs[joystickNum];
+ return 0;
}
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
HAL_JoystickButtons* buttons) {
- return HAL_GetJoystickButtonsInternal(joystickNum, buttons);
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{cacheMutex};
+ *buttons = currentRead->buttons[joystickNum];
+ return 0;
+}
+
+void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs,
+ HAL_JoystickButtons* buttons) {
+ std::scoped_lock lock{cacheMutex};
+ std::memcpy(axes, currentRead->axes, sizeof(currentRead->axes));
+ std::memcpy(povs, currentRead->povs, sizeof(currentRead->povs));
+ std::memcpy(buttons, currentRead->buttons, sizeof(currentRead->buttons));
}
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
HAL_JoystickDescriptor* desc) {
- return HAL_GetJoystickDescriptorInternal(joystickNum, desc);
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{tcpCacheMutex};
+ *desc = tcpCurrent.descriptors[joystickNum];
+ return 0;
}
int32_t HAL_GetMatchInfo(HAL_MatchInfo* info) {
- return HAL_GetMatchInfoInternal(info);
+ std::scoped_lock lock{tcpCacheMutex};
+ *info = tcpCurrent.matchInfo;
+ return 0;
}
HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
- HAL_AllianceStationID allianceStation;
- *status = FRC_NetworkCommunication_getAllianceStation(
- reinterpret_cast<AllianceStationID_t*>(&allianceStation));
- return allianceStation;
+ std::scoped_lock lock{cacheMutex};
+ return currentRead->allianceStation;
}
HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum) {
@@ -327,14 +436,14 @@
int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble) {
+ CHECK_JOYSTICK_NUMBER(joystickNum);
return FRC_NetworkCommunication_setJoystickOutputs(joystickNum, outputs,
leftRumble, rightRumble);
}
double HAL_GetMatchTime(int32_t* status) {
- float matchTime;
- *status = FRC_NetworkCommunication_getMatchTime(&matchTime);
- return matchTime;
+ std::scoped_lock lock{cacheMutex};
+ return currentRead->matchTime;
}
void HAL_ObserveUserProgramStarting(void) {
@@ -357,103 +466,89 @@
FRC_NetworkCommunication_observeUserProgramTest();
}
-static int& GetThreadLocalLastCount() {
- // There is a rollover error condition here. At Packet# = n * (uintmax), this
- // will return false when instead it should return true. However, this at a
- // 20ms rate occurs once every 2.7 years of DS connected runtime, so not
- // worth the cycles to check.
- thread_local int lastCount{0};
- return lastCount;
-}
-
-HAL_Bool HAL_IsNewControlData(void) {
- std::scoped_lock lock{*newDSDataAvailableMutex};
- int& lastCount = GetThreadLocalLastCount();
- int currentCount = newDSDataAvailableCounter;
- if (lastCount == currentCount) {
- return false;
- }
- lastCount = currentCount;
- return true;
-}
-
-void HAL_WaitForDSData(void) {
- HAL_WaitForDSDataTimeout(0);
-}
-
-HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
- std::unique_lock lock{*newDSDataAvailableMutex};
- int& lastCount = GetThreadLocalLastCount();
- int currentCount = newDSDataAvailableCounter;
- if (lastCount != currentCount) {
- lastCount = currentCount;
- return true;
- }
- auto timeoutTime =
- std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
-
- while (newDSDataAvailableCounter == currentCount) {
- if (timeout > 0) {
- auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
- if (timedOut == std::cv_status::timeout) {
- return false;
- }
- } else {
- newDSDataAvailableCond->wait(lock);
- }
- }
- lastCount = newDSDataAvailableCounter;
- return true;
-}
-
// Constant number to be used for our occur handle
constexpr int32_t refNumber = 42;
+constexpr int32_t tcpRefNumber = 94;
-static void newDataOccur(uint32_t refNum) {
- // Since we could get other values, require our specific handle
- // to signal our threads
- if (refNum != refNumber) {
- return;
- }
- std::scoped_lock lock{*newDSDataAvailableMutex};
- // Notify all threads
- ++newDSDataAvailableCounter;
- newDSDataAvailableCond->notify_all();
+static void tcpOccur(void) {
+ uint32_t mask = FRC_NetworkCommunication_getNewTcpRecvMask();
+ tcpMask.fetch_or(mask);
}
-/*
- * Call this to initialize the driver station communication. This will properly
- * handle multiple calls. However note that this CANNOT be called from a library
- * that interfaces with LabVIEW.
- */
-void HAL_InitializeDriverStation(void) {
- static std::atomic_bool initialized{false};
- static wpi::mutex initializeMutex;
- // Initial check, as if it's true initialization has finished
- if (initialized) {
- return;
- }
+static void udpOccur(void) {
+ cacheToUpdate->Update();
- std::scoped_lock lock(initializeMutex);
- // Second check in case another thread was waiting
- if (initialized) {
- return;
+ JoystickDataCache* given = cacheToUpdate;
+ JoystickDataCache* prev = currentCache.exchange(cacheToUpdate);
+ if (prev == nullptr) {
+ cacheToUpdate = currentReadLocal;
+ currentReadLocal = lastGiven;
+ } else {
+ // Current read local does not update
+ cacheToUpdate = prev;
}
+ lastGiven = given;
+ driverStation->newDataEvents.Wakeup();
+}
+
+static void newDataOccur(uint32_t refNum) {
+ switch (refNum) {
+ case refNumber:
+ udpOccur();
+ break;
+
+ case tcpRefNumber:
+ tcpOccur();
+ break;
+
+ default:
+ std::printf("Unknown occur %u\n", refNum);
+ break;
+ }
+}
+
+void HAL_RefreshDSData(void) {
+ HAL_ControlWord controlWord;
+ std::memset(&controlWord, 0, sizeof(controlWord));
+ FRC_NetworkCommunication_getControlWord(
+ reinterpret_cast<ControlWord_t*>(&controlWord));
+ std::scoped_lock lock{cacheMutex};
+ JoystickDataCache* prev = currentCache.exchange(nullptr);
+ if (prev != nullptr) {
+ currentRead = prev;
+ }
+ newestControlWord = controlWord;
+
+ uint32_t mask = tcpMask.exchange(0);
+ if (mask != 0) {
+ tcpCache.Update(mask);
+ std::scoped_lock tcpLock(tcpCacheMutex);
+ tcpCache.CloneTo(&tcpCurrent);
+ }
+}
+
+void HAL_ProvideNewDataEventHandle(WPI_EventHandle handle) {
+ hal::init::CheckInit();
+ driverStation->newDataEvents.Add(handle);
+}
+
+void HAL_RemoveNewDataEventHandle(WPI_EventHandle handle) {
+ driverStation->newDataEvents.Remove(handle);
+}
+
+HAL_Bool HAL_GetOutputsEnabled(void) {
+ return FRC_NetworkCommunication_getWatchdogActive();
+}
+
+} // extern "C"
+
+namespace hal {
+void InitializeDriverStation() {
// Set up the occur function internally with NetComm
NetCommRPCProxy_SetOccurFuncPointer(newDataOccur);
// Set up our occur reference number
setNewDataOccurRef(refNumber);
-
- initialized = true;
+ FRC_NetworkCommunication_setNewTcpDataOccurRef(tcpRefNumber);
}
-
-/*
- * Releases the DS Mutex to allow proper shutdown of any threads that are
- * waiting on it.
- */
-void HAL_ReleaseDSMutex(void) {
- newDataOccur(refNumber);
-}
-
-} // extern "C"
+} // namespace hal
diff --git a/hal/src/main/native/athena/HAL.cpp b/hal/src/main/native/athena/HAL.cpp
index 93e5c15..3a8cefd 100644
--- a/hal/src/main/native/athena/HAL.cpp
+++ b/hal/src/main/native/athena/HAL.cpp
@@ -18,9 +18,14 @@
#include <FRC_NetworkCommunication/LoadOut.h>
#include <FRC_NetworkCommunication/UsageReporting.h>
#include <fmt/format.h>
+#include <wpi/MemoryBuffer.h>
+#include <wpi/SmallString.h>
+#include <wpi/StringExtras.h>
+#include <wpi/fs.h>
#include <wpi/mutex.h>
#include <wpi/timestamp.h>
+#include "FPGACalls.h"
#include "HALInitializer.h"
#include "HALInternal.h"
#include "hal/ChipObject.h"
@@ -28,6 +33,7 @@
#include "hal/Errors.h"
#include "hal/Notifier.h"
#include "hal/handles/HandlesInternal.h"
+#include "hal/roborio/InterruptManager.h"
#include "visa/visa.h"
using namespace hal;
@@ -36,9 +42,14 @@
static std::unique_ptr<tSysWatchdog> watchdog;
static uint64_t dsStartTime;
+static char roboRioCommentsString[64];
+static size_t roboRioCommentsStringSize;
+static bool roboRioCommentsStringInitialized;
+
using namespace hal;
namespace hal {
+void InitializeDriverStation();
namespace init {
void InitializeHAL() {
InitializeCTREPCM();
@@ -79,6 +90,7 @@
} // namespace init
void ReleaseFPGAInterrupt(int32_t interruptNumber) {
+ hal::init::CheckInit();
if (!global) {
return;
}
@@ -249,6 +261,7 @@
}
int32_t HAL_GetFPGAVersion(int32_t* status) {
+ hal::init::CheckInit();
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
@@ -257,6 +270,7 @@
}
int64_t HAL_GetFPGARevision(int32_t* status) {
+ hal::init::CheckInit();
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
@@ -264,7 +278,83 @@
return global->readRevision(status);
}
+size_t HAL_GetSerialNumber(char* buffer, size_t size) {
+ const char* serialNum = std::getenv("serialnum");
+ if (serialNum) {
+ std::strncpy(buffer, serialNum, size);
+ buffer[size - 1] = '\0';
+ return std::strlen(buffer);
+ } else {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ return 0;
+ }
+}
+
+void InitializeRoboRioComments(void) {
+ if (!roboRioCommentsStringInitialized) {
+ std::error_code ec;
+ std::unique_ptr<wpi::MemoryBuffer> fileBuffer =
+ wpi::MemoryBuffer::GetFile("/etc/machine-info", ec);
+
+ std::string_view fileContents;
+ if (fileBuffer && !ec) {
+ fileContents =
+ std::string_view(reinterpret_cast<const char*>(fileBuffer->begin()),
+ fileBuffer->size());
+ } else {
+ roboRioCommentsStringSize = 0;
+ roboRioCommentsStringInitialized = true;
+ return;
+ }
+ std::string_view searchString = "PRETTY_HOSTNAME=\"";
+
+ size_t start = fileContents.find(searchString);
+ if (start == std::string_view::npos) {
+ roboRioCommentsStringSize = 0;
+ roboRioCommentsStringInitialized = true;
+ return;
+ }
+ start += searchString.size();
+ size_t end = fileContents.find("\"", start);
+ if (end == std::string_view::npos) {
+ end = fileContents.size();
+ }
+ std::string_view escapedComments = wpi::slice(fileContents, start, end);
+ wpi::SmallString<64> buf;
+ auto [unescapedComments, rem] = wpi::UnescapeCString(escapedComments, buf);
+ unescapedComments.copy(roboRioCommentsString,
+ sizeof(roboRioCommentsString));
+
+ if (unescapedComments.size() > sizeof(roboRioCommentsString)) {
+ roboRioCommentsStringSize = sizeof(roboRioCommentsString);
+ } else {
+ roboRioCommentsStringSize = unescapedComments.size();
+ }
+ roboRioCommentsStringInitialized = true;
+ }
+}
+
+size_t HAL_GetComments(char* buffer, size_t size) {
+ if (!roboRioCommentsStringInitialized) {
+ InitializeRoboRioComments();
+ }
+ size_t toCopy = size;
+ if (size > roboRioCommentsStringSize) {
+ toCopy = roboRioCommentsStringSize;
+ }
+ std::memcpy(buffer, roboRioCommentsString, toCopy);
+ if (toCopy < size) {
+ buffer[toCopy] = '\0';
+ } else {
+ buffer[toCopy - 1] = '\0';
+ }
+ return toCopy;
+}
+
uint64_t HAL_GetFPGATime(int32_t* status) {
+ hal::init::CheckInit();
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
@@ -311,6 +401,7 @@
}
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
+ hal::init::CheckInit();
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
@@ -319,6 +410,7 @@
}
HAL_Bool HAL_GetSystemActive(int32_t* status) {
+ hal::init::CheckInit();
if (!watchdog) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
@@ -327,6 +419,7 @@
}
HAL_Bool HAL_GetBrownedOut(int32_t* status) {
+ hal::init::CheckInit();
if (!watchdog) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
@@ -392,6 +485,11 @@
return true;
}
+ int fpgaInit = hal::init::InitializeFPGA();
+ if (fpgaInit != HAL_SUCCESS) {
+ return false;
+ }
+
hal::init::InitializeHAL();
hal::init::HAL_IsInitialized.store(true);
@@ -424,7 +522,9 @@
return false;
}
- HAL_InitializeDriverStation();
+ InterruptManager::Initialize(global->getSystemInterface());
+
+ hal::InitializeDriverStation();
dsStartTime = HAL_GetFPGATime(&status);
if (status != 0) {
diff --git a/hal/src/main/native/athena/InterruptManager.cpp b/hal/src/main/native/athena/InterruptManager.cpp
new file mode 100644
index 0000000..420f806
--- /dev/null
+++ b/hal/src/main/native/athena/InterruptManager.cpp
@@ -0,0 +1,72 @@
+// 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 "hal/roborio/InterruptManager.h"
+
+#include <fmt/format.h>
+
+#include "FPGACalls.h"
+#include "HALInternal.h"
+#include "dlfcn.h"
+#include "hal/Errors.h"
+
+using namespace hal;
+
+InterruptManager& InterruptManager::GetInstance() {
+ static InterruptManager manager;
+ return manager;
+}
+
+void InterruptManager::Initialize(tSystemInterface* baseSystem) {
+ auto& manager = GetInstance();
+ manager.fpgaSession = baseSystem->getHandle();
+}
+
+NiFpga_IrqContext InterruptManager::GetContext() noexcept {
+ NiFpga_IrqContext context;
+ HAL_NiFpga_ReserveIrqContext(fpgaSession, &context);
+ return context;
+}
+
+void InterruptManager::ReleaseContext(NiFpga_IrqContext context) noexcept {
+ HAL_NiFpga_UnreserveIrqContext(fpgaSession, context);
+}
+
+uint32_t InterruptManager::WaitForInterrupt(NiFpga_IrqContext context,
+ uint32_t mask, bool ignorePrevious,
+ uint32_t timeoutMs,
+ int32_t* status) {
+ {
+ // Make sure we can safely use this
+ std::scoped_lock lock(currentMaskMutex);
+ if ((currentMask & mask) != 0) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ hal::SetLastError(
+ status, fmt::format("Interrupt mask {} has bits {} already in use",
+ mask, (currentMask & mask)));
+ return 0;
+ }
+ currentMask |= mask;
+ }
+
+ if (ignorePrevious) {
+ HAL_NiFpga_AcknowledgeIrqs(fpgaSession, mask);
+ }
+
+ uint32_t irqsAsserted = 0;
+ NiFpga_Bool timedOut = 0;
+ *status = HAL_NiFpga_WaitOnIrqs(fpgaSession, context, mask, timeoutMs,
+ &irqsAsserted, &timedOut);
+
+ if (!timedOut) {
+ HAL_NiFpga_AcknowledgeIrqs(fpgaSession, irqsAsserted);
+ }
+
+ {
+ std::scoped_lock lock(currentMaskMutex);
+ currentMask &= ~mask;
+ }
+
+ return irqsAsserted;
+}
diff --git a/hal/src/main/native/athena/Interrupts.cpp b/hal/src/main/native/athena/Interrupts.cpp
index 943a1aa..e40c6f4 100644
--- a/hal/src/main/native/athena/Interrupts.cpp
+++ b/hal/src/main/native/athena/Interrupts.cpp
@@ -17,6 +17,7 @@
#include "hal/HALBase.h"
#include "hal/handles/HandlesInternal.h"
#include "hal/handles/LimitedHandleResource.h"
+#include "hal/roborio/InterruptManager.h"
using namespace hal;
@@ -24,7 +25,9 @@
struct Interrupt {
std::unique_ptr<tInterrupt> anInterrupt;
- std::unique_ptr<tInterruptManager> manager;
+ InterruptManager& manager = InterruptManager::GetInstance();
+ NiFpga_IrqContext irqContext = nullptr;
+ uint32_t mask;
};
} // namespace
@@ -55,8 +58,8 @@
// Expects the calling leaf class to allocate an interrupt index.
anInterrupt->anInterrupt.reset(tInterrupt::create(interruptIndex, status));
anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
- anInterrupt->manager = std::make_unique<tInterruptManager>(
- (1u << interruptIndex) | (1u << (interruptIndex + 8u)), true, status);
+ anInterrupt->irqContext = anInterrupt->manager.GetContext();
+ anInterrupt->mask = (1u << interruptIndex) | (1u << (interruptIndex + 8u));
return handle;
}
@@ -66,6 +69,9 @@
if (anInterrupt == nullptr) {
return;
}
+ if (anInterrupt->irqContext) {
+ anInterrupt->manager.ReleaseContext(anInterrupt->irqContext);
+ }
}
int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
@@ -78,8 +84,33 @@
return 0;
}
- result = anInterrupt->manager->watch(static_cast<int32_t>(timeout * 1e3),
- ignorePrevious, status);
+ result = anInterrupt->manager.WaitForInterrupt(
+ anInterrupt->irqContext, anInterrupt->mask, ignorePrevious,
+ static_cast<uint32_t>(timeout * 1e3), status);
+
+ // Don't report a timeout as an error - the return code is enough to tell
+ // that a timeout happened.
+ if (*status == -NiFpga_Status_IrqTimeout) {
+ *status = NiFpga_Status_Success;
+ }
+
+ return result;
+}
+
+int64_t HAL_WaitForMultipleInterrupts(HAL_InterruptHandle interruptHandle,
+ int64_t mask, double timeout,
+ HAL_Bool ignorePrevious,
+ int32_t* status) {
+ uint32_t result;
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ result = anInterrupt->manager.WaitForInterrupt(
+ anInterrupt->irqContext, mask, ignorePrevious,
+ static_cast<uint32_t>(timeout * 1e3), status);
// Don't report a timeout as an error - the return code is enough to tell
// that a timeout happened.
diff --git a/hal/src/main/native/athena/Notifier.cpp b/hal/src/main/native/athena/Notifier.cpp
index d684031..9c818d8 100644
--- a/hal/src/main/native/athena/Notifier.cpp
+++ b/hal/src/main/native/athena/Notifier.cpp
@@ -20,6 +20,7 @@
#include "hal/HAL.h"
#include "hal/Threads.h"
#include "hal/handles/UnlimitedHandleResource.h"
+#include "hal/roborio/InterruptManager.h"
using namespace hal;
@@ -106,15 +107,21 @@
}
static void notifierThreadMain() {
- tRioStatusCode status = 0;
- tInterruptManager manager{1 << kTimerInterruptNumber, true, &status};
+ InterruptManager& manager = InterruptManager::GetInstance();
+ NiFpga_IrqContext context = manager.GetContext();
+ uint32_t mask = 1 << kTimerInterruptNumber;
+ int32_t status = 0;
+
while (notifierRunning) {
- auto triggeredMask = manager.watch(10000, false, &status);
+ status = 0;
+ auto triggeredMask =
+ manager.WaitForInterrupt(context, mask, false, 10000, &status);
if (!notifierRunning) {
break;
}
- if (triggeredMask == 0)
+ if (triggeredMask == 0) {
continue;
+ }
alarmCallback();
}
}
@@ -195,8 +202,9 @@
void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
- if (!notifier)
+ if (!notifier) {
return;
+ }
{
std::scoped_lock lock(notifier->mutex);
@@ -209,8 +217,9 @@
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
auto notifier = notifierHandles->Free(notifierHandle);
- if (!notifier)
+ if (!notifier) {
return;
+ }
// Just in case HAL_StopNotifier() wasn't called...
{
@@ -244,8 +253,9 @@
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
uint64_t triggerTime, int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
- if (!notifier)
+ if (!notifier) {
return;
+ }
{
std::scoped_lock lock(notifier->mutex);
@@ -270,8 +280,9 @@
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
- if (!notifier)
+ if (!notifier) {
return;
+ }
{
std::scoped_lock lock(notifier->mutex);
@@ -282,8 +293,9 @@
uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
- if (!notifier)
+ if (!notifier) {
return 0;
+ }
std::unique_lock lock(notifier->mutex);
notifier->cond.wait(lock, [&] {
return !notifier->active || notifier->triggeredTime != UINT64_MAX;
diff --git a/hal/src/main/native/athena/PortsInternal.h b/hal/src/main/native/athena/PortsInternal.h
index 18ce569..ff57703 100644
--- a/hal/src/main/native/athena/PortsInternal.h
+++ b/hal/src/main/native/athena/PortsInternal.h
@@ -23,7 +23,8 @@
kNumDigitalHeaders + kNumDigitalMXPChannels + kNumDigitalSPIPortChannels;
constexpr int32_t kNumPWMChannels = tPWM::kNumMXPRegisters + kNumPWMHeaders;
constexpr int32_t kNumDigitalPWMOutputs =
- tDIO::kNumPWMDutyCycleAElements + tDIO::kNumPWMDutyCycleBElements;
+ static_cast<int32_t>(tDIO::kNumPWMDutyCycleAElements) +
+ static_cast<int32_t>(tDIO::kNumPWMDutyCycleBElements);
constexpr int32_t kNumEncoders = tEncoder::kNumSystems;
constexpr int32_t kNumInterrupts = tInterrupt::kNumSystems;
constexpr int32_t kNumRelayChannels = 8;
diff --git a/hal/src/main/native/athena/REVPH.cpp b/hal/src/main/native/athena/REVPH.cpp
index 5b18de6..ae3f460 100644
--- a/hal/src/main/native/athena/REVPH.cpp
+++ b/hal/src/main/native/athena/REVPH.cpp
@@ -228,18 +228,19 @@
sizeof(hph->desiredSolenoidsState));
std::memset(&hph->versionInfo, 0, sizeof(hph->versionInfo));
+ int32_t can_status = 0;
+
// Start closed-loop compressor control by starting solenoid state updates
- HAL_SendREVPHSolenoidsState(hph.get(), status);
+ HAL_SendREVPHSolenoidsState(hph.get(), &can_status);
return handle;
}
void HAL_FreeREVPH(HAL_REVPHHandle handle) {
auto hph = REVPHHandles->Get(handle);
- if (hph == nullptr)
- return;
-
- HAL_CleanCAN(hph->hcan);
+ if (hph) {
+ HAL_CleanCAN(hph->hcan);
+ }
REVPHHandles->Free(handle);
}
diff --git a/hal/src/main/native/athena/SPI.cpp b/hal/src/main/native/athena/SPI.cpp
index 0df6fdb..9d3335e 100644
--- a/hal/src/main/native/athena/SPI.cpp
+++ b/hal/src/main/native/athena/SPI.cpp
@@ -125,8 +125,8 @@
// CS0 is not a DIO port, so nothing to allocate
handle = open("/dev/spidev0.0", O_RDWR);
if (handle < 0) {
- fmt::print("Failed to open SPI port {}: {}\n", port,
- std::strerror(errno));
+ fmt::print("Failed to open SPI port {}: {}\n",
+ static_cast<int32_t>(port), std::strerror(errno));
CommonSPIPortFree();
return;
}
@@ -147,8 +147,8 @@
}
handle = open("/dev/spidev0.1", O_RDWR);
if (handle < 0) {
- fmt::print("Failed to open SPI port {}: {}\n", port,
- std::strerror(errno));
+ fmt::print("Failed to open SPI port {}: {}\n",
+ static_cast<int32_t>(port), std::strerror(errno));
CommonSPIPortFree();
HAL_FreeDIOPort(digitalHandles[0]);
return;
@@ -170,8 +170,8 @@
}
handle = open("/dev/spidev0.2", O_RDWR);
if (handle < 0) {
- fmt::print("Failed to open SPI port {}: {}\n", port,
- std::strerror(errno));
+ fmt::print("Failed to open SPI port {}: {}\n",
+ static_cast<int32_t>(port), std::strerror(errno));
CommonSPIPortFree();
HAL_FreeDIOPort(digitalHandles[1]);
return;
@@ -193,8 +193,8 @@
}
handle = open("/dev/spidev0.3", O_RDWR);
if (handle < 0) {
- fmt::print("Failed to open SPI port {}: {}\n", port,
- std::strerror(errno));
+ fmt::print("Failed to open SPI port {}: {}\n",
+ static_cast<int32_t>(port), std::strerror(errno));
CommonSPIPortFree();
HAL_FreeDIOPort(digitalHandles[2]);
return;
@@ -240,8 +240,8 @@
digitalSystem->readEnableMXPSpecialFunction(status) | 0x00F0, status);
handle = open("/dev/spidev1.0", O_RDWR);
if (handle < 0) {
- fmt::print("Failed to open SPI port {}: {}\n", port,
- std::strerror(errno));
+ fmt::print("Failed to open SPI port {}: {}\n",
+ static_cast<int32_t>(port), std::strerror(errno));
HAL_FreeDIOPort(digitalHandles[5]); // free the first port allocated
HAL_FreeDIOPort(digitalHandles[6]); // free the second port allocated
HAL_FreeDIOPort(digitalHandles[7]); // free the third port allocated
@@ -364,19 +364,27 @@
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
}
-void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
- HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {
+void HAL_SetSPIMode(HAL_SPIPort port, HAL_SPIMode mode) {
if (port < 0 || port >= kSpiMaxHandles) {
return;
}
- uint8_t mode = 0;
- mode |= (!msbFirst ? 8 : 0);
- mode |= (clkIdleHigh ? 2 : 0);
- mode |= (sampleOnTrailing ? 1 : 0);
+ uint8_t mode8 = mode & SPI_MODE_3;
std::scoped_lock lock(spiApiMutexes[port]);
- ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
+ ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode8);
+}
+
+HAL_SPIMode HAL_GetSPIMode(HAL_SPIPort port) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return HAL_SPI_kMode0;
+ }
+
+ uint8_t mode8 = 0;
+
+ std::scoped_lock lock(spiApiMutexes[port]);
+ ioctl(HAL_GetSPIHandle(port), SPI_IOC_RD_MODE, &mode8);
+ return static_cast<HAL_SPIMode>(mode8 & SPI_MODE_3);
}
void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
diff --git a/hal/src/main/native/athena/cpp/SerialHelper.cpp b/hal/src/main/native/athena/cpp/SerialHelper.cpp
index 3831769..fef92d4 100644
--- a/hal/src/main/native/athena/cpp/SerialHelper.cpp
+++ b/hal/src/main/native/athena/cpp/SerialHelper.cpp
@@ -193,7 +193,7 @@
ViSession vSession;
*status = viOpen(m_resourceHandle, desc, VI_NULL, VI_NULL, &vSession);
if (*status < 0)
- goto done;
+ continue;
*status = 0;
*status = viGetAttribute(vSession, VI_ATTR_INTF_INST_NAME, &osName);
@@ -201,9 +201,9 @@
// Use a separate close variable so we can check
ViStatus closeStatus = viClose(vSession);
if (*status < 0)
- goto done;
+ continue;
if (closeStatus < 0)
- goto done;
+ continue;
*status = 0;
// split until (/dev/
diff --git a/hal/src/main/native/athena/mockdata/DriverStationData.cpp b/hal/src/main/native/athena/mockdata/DriverStationData.cpp
index ba519fc..76a8e8b 100644
--- a/hal/src/main/native/athena/mockdata/DriverStationData.cpp
+++ b/hal/src/main/native/athena/mockdata/DriverStationData.cpp
@@ -103,13 +103,13 @@
void HALSIM_SetJoystickType(int32_t stick, int32_t type) {}
-void HALSIM_SetJoystickName(int32_t stick, const char* name) {}
+void HALSIM_SetJoystickName(int32_t stick, const char* name, size_t size) {}
void HALSIM_SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type) {}
-void HALSIM_SetGameSpecificMessage(const char* message) {}
+void HALSIM_SetGameSpecificMessage(const char* message, size_t size) {}
-void HALSIM_SetEventName(const char* name) {}
+void HALSIM_SetEventName(const char* name, size_t size) {}
void HALSIM_SetMatchType(HAL_MatchType type) {}
diff --git a/hal/src/main/native/athena/mockdata/MockHooks.cpp b/hal/src/main/native/athena/mockdata/MockHooks.cpp
index 0ea05d0..a6a6804 100644
--- a/hal/src/main/native/athena/mockdata/MockHooks.cpp
+++ b/hal/src/main/native/athena/mockdata/MockHooks.cpp
@@ -48,4 +48,6 @@
void HALSIM_CancelSimPeriodicAfterCallback(int32_t uid) {}
+void HALSIM_CancelAllSimPeriodicCallbacks(void) {}
+
} // extern "C"
diff --git a/hal/src/main/native/athena/mockdata/Reset.cpp b/hal/src/main/native/athena/mockdata/Reset.cpp
new file mode 100644
index 0000000..7cbeea3
--- /dev/null
+++ b/hal/src/main/native/athena/mockdata/Reset.cpp
@@ -0,0 +1,5 @@
+// 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.
+
+extern "C" void HALSIM_ResetAllSimData(void) {}
diff --git a/hal/src/main/native/athena/mockdata/RoboRioData.cpp b/hal/src/main/native/athena/mockdata/RoboRioData.cpp
index 9f6683a..9392fcb 100644
--- a/hal/src/main/native/athena/mockdata/RoboRioData.cpp
+++ b/hal/src/main/native/athena/mockdata/RoboRioData.cpp
@@ -29,6 +29,32 @@
DEFINE_CAPI(int32_t, UserFaults3V3, 0)
DEFINE_CAPI(double, BrownoutVoltage, 6.75)
+int32_t HALSIM_RegisterRoboRioSerialNumberCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
+ return 0;
+}
+void HALSIM_CancelRoboRioSerialNumberCallback(int32_t uid) {}
+size_t HALSIM_GetRoboRioSerialNumber(char* buffer, size_t size) {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ return 0;
+}
+void HALSIM_SetRoboRioSerialNumber(const char* buffer, size_t size) {}
+
+int32_t HALSIM_RegisterRoboRioCommentsCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
+ return 0;
+}
+void HALSIM_CancelRoboRioCommentsCallback(int32_t uid) {}
+size_t HALSIM_GetRoboRioComments(char* buffer, size_t size) {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ return 0;
+}
+void HALSIM_SetRoboRioComments(const char* buffer, size_t size) {}
+
void HALSIM_RegisterRoboRioAllCallbacks(HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify) {}
} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CANJNI.cpp b/hal/src/main/native/cpp/jni/CANJNI.cpp
index 968f656..4ad2a74 100644
--- a/hal/src/main/native/cpp/jni/CANJNI.cpp
+++ b/hal/src/main/native/cpp/jni/CANJNI.cpp
@@ -62,9 +62,7 @@
if (!CheckCANStatus(env, status, *messageIDPtr)) {
return nullptr;
}
- return MakeJByteArray(env,
- std::string_view{reinterpret_cast<const char*>(buffer),
- static_cast<size_t>(dataSize)});
+ return MakeJByteArray(env, {buffer, static_cast<size_t>(dataSize)});
}
/*
@@ -93,4 +91,90 @@
txFullCount, receiveErrorCount, transmitErrorCount);
}
+/*
+ * Class: edu_wpi_first_hal_can_CANJNI
+ * Method: openCANStreamSession
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_can_CANJNI_openCANStreamSession
+ (JNIEnv* env, jclass, jint messageID, jint messageIDMask, jint maxMessages)
+{
+ uint32_t handle = 0;
+ int32_t status = 0;
+ HAL_CAN_OpenStreamSession(&handle, static_cast<uint32_t>(messageID),
+ static_cast<uint32_t>(messageIDMask),
+ static_cast<uint32_t>(maxMessages), &status);
+
+ if (!CheckStatus(env, status)) {
+ return static_cast<jint>(0);
+ }
+
+ return static_cast<jint>(handle);
+}
+
+/*
+ * Class: edu_wpi_first_hal_can_CANJNI
+ * Method: closeCANStreamSession
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_can_CANJNI_closeCANStreamSession
+ (JNIEnv* env, jclass, jint sessionHandle)
+{
+ HAL_CAN_CloseStreamSession(static_cast<uint32_t>(sessionHandle));
+}
+
+/*
+ * Class: edu_wpi_first_hal_can_CANJNI
+ * Method: readCANStreamSession
+ * Signature: (I[Ljava/lang/Object;I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_can_CANJNI_readCANStreamSession
+ (JNIEnv* env, jclass, jint sessionHandle, jobjectArray messages,
+ jint messagesToRead)
+{
+ uint32_t handle = static_cast<uint32_t>(sessionHandle);
+ uint32_t messagesRead = 0;
+
+ wpi::SmallVector<HAL_CANStreamMessage, 16> messageBuffer;
+ messageBuffer.resize_for_overwrite(messagesToRead);
+
+ int32_t status = 0;
+
+ HAL_CAN_ReadStreamSession(handle, messageBuffer.begin(),
+ static_cast<uint32_t>(messagesToRead),
+ &messagesRead, &status);
+
+ if (status == HAL_ERR_CANSessionMux_MessageNotFound || messagesRead == 0) {
+ return 0;
+ }
+
+ if (!CheckStatus(env, status)) {
+ return 0;
+ }
+
+ for (int i = 0; i < static_cast<int>(messagesRead); i++) {
+ struct HAL_CANStreamMessage* msg = &messageBuffer[i];
+ JLocal<jobject> elem{
+ env, static_cast<jstring>(env->GetObjectArrayElement(messages, i))};
+ if (!elem) {
+ // TODO decide if should throw
+ continue;
+ }
+ JLocal<jbyteArray> toSetArray{
+ env, SetCANStreamObject(env, elem, msg->dataSize, msg->messageID,
+ msg->timeStamp)};
+ auto javaLen = env->GetArrayLength(toSetArray);
+ if (javaLen < msg->dataSize) {
+ msg->dataSize = javaLen;
+ }
+ env->SetByteArrayRegion(toSetArray, 0, msg->dataSize,
+ reinterpret_cast<jbyte*>(msg->data));
+ }
+
+ return static_cast<jint>(messagesRead);
+}
+
} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/DIOJNI.cpp b/hal/src/main/native/cpp/jni/DIOJNI.cpp
index 5cd6c2e..dee34c7 100644
--- a/hal/src/main/native/cpp/jni/DIOJNI.cpp
+++ b/hal/src/main/native/cpp/jni/DIOJNI.cpp
@@ -146,6 +146,20 @@
/*
* Class: edu_wpi_first_hal_DIOJNI
+ * Method: pulseMultiple
+ * Signature: (JD)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_pulseMultiple
+ (JNIEnv* env, jclass, jlong channelMask, jdouble value)
+{
+ int32_t status = 0;
+ HAL_PulseMultiple(static_cast<uint32_t>(channelMask), value, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
* Method: isPulsing
* Signature: (I)Z
*/
@@ -248,6 +262,20 @@
/*
* Class: edu_wpi_first_hal_DIOJNI
+ * Method: setDigitalPWMPPS
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMPPS
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ int32_t status = 0;
+ HAL_SetDigitalPWMPPS((HAL_DigitalPWMHandle)id, value, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
* Method: setDigitalPWMOutputChannel
* Signature: (II)V
*/
diff --git a/hal/src/main/native/cpp/jni/DriverStationJNI.cpp b/hal/src/main/native/cpp/jni/DriverStationJNI.cpp
new file mode 100644
index 0000000..f050f02
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/DriverStationJNI.cpp
@@ -0,0 +1,450 @@
+// 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 <jni.h>
+
+#include <cassert>
+
+#include <fmt/format.h>
+#include <wpi/jni_util.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_DriverStationJNI.h"
+#include "hal/DriverStation.h"
+#include "hal/FRCUsageReporting.h"
+#include "hal/HALBase.h"
+
+// TODO Static asserts
+
+using namespace hal;
+using namespace wpi::java;
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: observeUserProgramStarting
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_observeUserProgramStarting
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramStarting();
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: observeUserProgramDisabled
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_observeUserProgramDisabled
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramDisabled();
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: observeUserProgramAutonomous
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_observeUserProgramAutonomous
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramAutonomous();
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: observeUserProgramTeleop
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_observeUserProgramTeleop
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramTeleop();
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: observeUserProgramTest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_observeUserProgramTest
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramTest();
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: report
+ * Signature: (IIILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_report
+ (JNIEnv* paramEnv, jclass, jint paramResource, jint paramInstanceNumber,
+ jint paramContext, jstring paramFeature)
+{
+ JStringRef featureStr{paramEnv, paramFeature};
+ jint returnValue = HAL_Report(paramResource, paramInstanceNumber,
+ paramContext, featureStr.c_str());
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: nativeGetControlWord
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_nativeGetControlWord
+ (JNIEnv*, jclass)
+{
+ static_assert(sizeof(HAL_ControlWord) == sizeof(jint),
+ "Java int must match the size of control word");
+ HAL_ControlWord controlWord;
+ HAL_GetControlWord(&controlWord);
+ jint retVal = 0;
+ std::memcpy(&retVal, &controlWord, sizeof(HAL_ControlWord));
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: nativeGetAllianceStation
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_nativeGetAllianceStation
+ (JNIEnv*, jclass)
+{
+ int32_t status = 0;
+ auto allianceStation = HAL_GetAllianceStation(&status);
+ return static_cast<jint>(allianceStation);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickAxesRaw
+ * Signature: (B[I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickAxesRaw
+ (JNIEnv* env, jclass, jbyte joystickNum, jintArray axesRawArray)
+{
+ HAL_JoystickAxes axes;
+ HAL_GetJoystickAxes(joystickNum, &axes);
+
+ jsize javaSize = env->GetArrayLength(axesRawArray);
+ if (axes.count > javaSize) {
+ ThrowIllegalArgumentException(
+ env,
+ fmt::format("Native array size larger then passed in java array "
+ "size\nNative Size: {} Java Size: {}",
+ static_cast<int>(axes.count), static_cast<int>(javaSize)));
+ return 0;
+ }
+
+ jint raw[HAL_kMaxJoystickAxes];
+ for (int16_t i = 0; i < axes.count; i++) {
+ raw[i] = axes.raw[i];
+ }
+ env->SetIntArrayRegion(axesRawArray, 0, axes.count, raw);
+
+ return axes.count;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickAxes
+ * Signature: (B[F)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickAxes
+ (JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
+{
+ HAL_JoystickAxes axes;
+ HAL_GetJoystickAxes(joystickNum, &axes);
+
+ jsize javaSize = env->GetArrayLength(axesArray);
+ if (axes.count > javaSize) {
+ ThrowIllegalArgumentException(
+ env,
+ fmt::format("Native array size larger then passed in java array "
+ "size\nNative Size: {} Java Size: {}",
+ static_cast<int>(axes.count), static_cast<int>(javaSize)));
+ return 0;
+ }
+
+ env->SetFloatArrayRegion(axesArray, 0, axes.count, axes.axes);
+
+ return axes.count;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickPOVs
+ * Signature: (B[S)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickPOVs
+ (JNIEnv* env, jclass, jbyte joystickNum, jshortArray povsArray)
+{
+ HAL_JoystickPOVs povs;
+ HAL_GetJoystickPOVs(joystickNum, &povs);
+
+ jsize javaSize = env->GetArrayLength(povsArray);
+ if (povs.count > javaSize) {
+ ThrowIllegalArgumentException(
+ env,
+ fmt::format("Native array size larger then passed in java array "
+ "size\nNative Size: {} Java Size: {}",
+ static_cast<int>(povs.count), static_cast<int>(javaSize)));
+ return 0;
+ }
+
+ env->SetShortArrayRegion(povsArray, 0, povs.count, povs.povs);
+
+ return povs.count;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getAllJoystickData
+ * Signature: ([F[B[S[J)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getAllJoystickData
+ (JNIEnv* env, jclass cls, jfloatArray axesArray, jbyteArray rawAxesArray,
+ jshortArray povsArray, jlongArray buttonsAndMetadataArray)
+{
+ HAL_JoystickAxes axes[HAL_kMaxJoysticks];
+ HAL_JoystickPOVs povs[HAL_kMaxJoysticks];
+ HAL_JoystickButtons buttons[HAL_kMaxJoysticks];
+
+ HAL_GetAllJoystickData(axes, povs, buttons);
+
+ CriticalJFloatArrayRef jAxes(env, axesArray);
+ CriticalJByteArrayRef jRawAxes(env, rawAxesArray);
+ CriticalJShortArrayRef jPovs(env, povsArray);
+ CriticalJLongArrayRef jButtons(env, buttonsAndMetadataArray);
+
+ static_assert(sizeof(jAxes[0]) == sizeof(axes[0].axes[0]));
+ static_assert(sizeof(jRawAxes[0]) == sizeof(axes[0].raw[0]));
+ static_assert(sizeof(jPovs[0]) == sizeof(povs[0].povs[0]));
+
+ for (size_t i = 0; i < HAL_kMaxJoysticks; i++) {
+ std::memcpy(&jAxes[i * HAL_kMaxJoystickAxes], axes[i].axes,
+ sizeof(axes[i].axes));
+ std::memcpy(&jRawAxes[i * HAL_kMaxJoystickAxes], axes[i].raw,
+ sizeof(axes[i].raw));
+ std::memcpy(&jPovs[i * HAL_kMaxJoystickPOVs], povs[i].povs,
+ sizeof(povs[i].povs));
+ jButtons[i * 4] = axes[i].count;
+ jButtons[(i * 4) + 1] = povs[i].count;
+ jButtons[(i * 4) + 2] = buttons[i].count;
+ jButtons[(i * 4) + 3] = buttons[i].buttons;
+ }
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickButtons
+ * Signature: (BLjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickButtons
+ (JNIEnv* env, jclass, jbyte joystickNum, jobject count)
+{
+ HAL_JoystickButtons joystickButtons;
+ HAL_GetJoystickButtons(joystickNum, &joystickButtons);
+ jbyte* countPtr =
+ reinterpret_cast<jbyte*>(env->GetDirectBufferAddress(count));
+ *countPtr = joystickButtons.count;
+ return joystickButtons.buttons;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: setJoystickOutputs
+ * Signature: (BISS)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_setJoystickOutputs
+ (JNIEnv*, jclass, jbyte port, jint outputs, jshort leftRumble,
+ jshort rightRumble)
+{
+ return HAL_SetJoystickOutputs(port, outputs, leftRumble, rightRumble);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickIsXbox
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickIsXbox
+ (JNIEnv*, jclass, jbyte port)
+{
+ return HAL_GetJoystickIsXbox(port);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickType
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickType
+ (JNIEnv*, jclass, jbyte port)
+{
+ return HAL_GetJoystickType(port);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickName
+ * Signature: (B)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickName
+ (JNIEnv* env, jclass, jbyte port)
+{
+ char* joystickName = HAL_GetJoystickName(port);
+ jstring str = MakeJString(env, joystickName);
+ HAL_FreeJoystickName(joystickName);
+ return str;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getJoystickAxisType
+ * Signature: (BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getJoystickAxisType
+ (JNIEnv*, jclass, jbyte joystickNum, jbyte axis)
+{
+ return HAL_GetJoystickAxisType(joystickNum, axis);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getMatchTime
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getMatchTime
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ return HAL_GetMatchTime(&status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getMatchInfo
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getMatchInfo
+ (JNIEnv* env, jclass, jobject info)
+{
+ HAL_MatchInfo matchInfo;
+ auto status = HAL_GetMatchInfo(&matchInfo);
+ if (status == 0) {
+ SetMatchInfoObject(env, info, matchInfo);
+ }
+ return status;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: sendError
+ * Signature: (ZIZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_sendError
+ (JNIEnv* env, jclass, jboolean isError, jint errorCode, jboolean isLVCode,
+ jstring details, jstring location, jstring callStack, jboolean printMsg)
+{
+ JStringRef detailsStr{env, details};
+ JStringRef locationStr{env, location};
+ JStringRef callStackStr{env, callStack};
+
+ jint returnValue =
+ HAL_SendError(isError, errorCode, isLVCode, detailsStr.c_str(),
+ locationStr.c_str(), callStackStr.c_str(), printMsg);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: sendConsoleLine
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_sendConsoleLine
+ (JNIEnv* env, jclass, jstring line)
+{
+ JStringRef lineStr{env, line};
+
+ jint returnValue = HAL_SendConsoleLine(lineStr.c_str());
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: refreshDSData
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_refreshDSData
+ (JNIEnv*, jclass)
+{
+ HAL_RefreshDSData();
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: provideNewDataEventHandle
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_provideNewDataEventHandle
+ (JNIEnv*, jclass, jint handle)
+{
+ HAL_ProvideNewDataEventHandle(handle);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: removeNewDataEventHandle
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_removeNewDataEventHandle
+ (JNIEnv*, jclass, jint handle)
+{
+ HAL_RemoveNewDataEventHandle(handle);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DriverStationJNI
+ * Method: getOutputsActive
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_DriverStationJNI_getOutputsActive
+ (JNIEnv*, jclass)
+{
+ return HAL_GetOutputsEnabled();
+}
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/DutyCycleJNI.cpp b/hal/src/main/native/cpp/jni/DutyCycleJNI.cpp
index 96cc27b..f83e13c 100644
--- a/hal/src/main/native/cpp/jni/DutyCycleJNI.cpp
+++ b/hal/src/main/native/cpp/jni/DutyCycleJNI.cpp
@@ -74,15 +74,15 @@
/*
* Class: edu_wpi_first_hal_DutyCycleJNI
- * Method: getOutputRaw
+ * Method: getHighTime
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_DutyCycleJNI_getOutputRaw
+Java_edu_wpi_first_hal_DutyCycleJNI_getHighTime
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
- auto retVal = HAL_GetDutyCycleOutputRaw(
+ auto retVal = HAL_GetDutyCycleHighTime(
static_cast<HAL_DutyCycleHandle>(handle), &status);
CheckStatus(env, status);
return retVal;
diff --git a/hal/src/main/native/cpp/jni/HAL.cpp b/hal/src/main/native/cpp/jni/HAL.cpp
index 4e26032..b603a76 100644
--- a/hal/src/main/native/cpp/jni/HAL.cpp
+++ b/hal/src/main/native/cpp/jni/HAL.cpp
@@ -108,310 +108,6 @@
/*
* Class: edu_wpi_first_hal_HAL
- * Method: observeUserProgramStarting
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_observeUserProgramStarting
- (JNIEnv*, jclass)
-{
- HAL_ObserveUserProgramStarting();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: observeUserProgramDisabled
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_observeUserProgramDisabled
- (JNIEnv*, jclass)
-{
- HAL_ObserveUserProgramDisabled();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: observeUserProgramAutonomous
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_observeUserProgramAutonomous
- (JNIEnv*, jclass)
-{
- HAL_ObserveUserProgramAutonomous();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: observeUserProgramTeleop
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_observeUserProgramTeleop
- (JNIEnv*, jclass)
-{
- HAL_ObserveUserProgramTeleop();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: observeUserProgramTest
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_observeUserProgramTest
- (JNIEnv*, jclass)
-{
- HAL_ObserveUserProgramTest();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: report
- * Signature: (IIILjava/lang/String;)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_report
- (JNIEnv* paramEnv, jclass, jint paramResource, jint paramInstanceNumber,
- jint paramContext, jstring paramFeature)
-{
- JStringRef featureStr{paramEnv, paramFeature};
- jint returnValue = HAL_Report(paramResource, paramInstanceNumber,
- paramContext, featureStr.c_str());
- return returnValue;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: nativeGetControlWord
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_nativeGetControlWord
- (JNIEnv*, jclass)
-{
- static_assert(sizeof(HAL_ControlWord) == sizeof(jint),
- "Java int must match the size of control word");
- HAL_ControlWord controlWord;
- HAL_GetControlWord(&controlWord);
- jint retVal = 0;
- std::memcpy(&retVal, &controlWord, sizeof(HAL_ControlWord));
- return retVal;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: nativeGetAllianceStation
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_nativeGetAllianceStation
- (JNIEnv*, jclass)
-{
- int32_t status = 0;
- auto allianceStation = HAL_GetAllianceStation(&status);
- return static_cast<jint>(allianceStation);
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickAxes
- * Signature: (B[F)S
- */
-JNIEXPORT jshort JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickAxes
- (JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
-{
- HAL_JoystickAxes axes;
- HAL_GetJoystickAxes(joystickNum, &axes);
-
- jsize javaSize = env->GetArrayLength(axesArray);
- if (axes.count > javaSize) {
- ThrowIllegalArgumentException(
- env,
- fmt::format("Native array size larger then passed in java array "
- "size\nNative Size: {} Java Size: {}",
- static_cast<int>(axes.count), static_cast<int>(javaSize)));
- return 0;
- }
-
- env->SetFloatArrayRegion(axesArray, 0, axes.count, axes.axes);
-
- return axes.count;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickPOVs
- * Signature: (B[S)S
- */
-JNIEXPORT jshort JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickPOVs
- (JNIEnv* env, jclass, jbyte joystickNum, jshortArray povsArray)
-{
- HAL_JoystickPOVs povs;
- HAL_GetJoystickPOVs(joystickNum, &povs);
-
- jsize javaSize = env->GetArrayLength(povsArray);
- if (povs.count > javaSize) {
- ThrowIllegalArgumentException(
- env,
- fmt::format("Native array size larger then passed in java array "
- "size\nNative Size: {} Java Size: {}",
- static_cast<int>(povs.count), static_cast<int>(javaSize)));
- return 0;
- }
-
- env->SetShortArrayRegion(povsArray, 0, povs.count, povs.povs);
-
- return povs.count;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickButtons
- * Signature: (BLjava/lang/Object;)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickButtons
- (JNIEnv* env, jclass, jbyte joystickNum, jobject count)
-{
- HAL_JoystickButtons joystickButtons;
- HAL_GetJoystickButtons(joystickNum, &joystickButtons);
- jbyte* countPtr =
- reinterpret_cast<jbyte*>(env->GetDirectBufferAddress(count));
- *countPtr = joystickButtons.count;
- return joystickButtons.buttons;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: setJoystickOutputs
- * Signature: (BISS)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_setJoystickOutputs
- (JNIEnv*, jclass, jbyte port, jint outputs, jshort leftRumble,
- jshort rightRumble)
-{
- return HAL_SetJoystickOutputs(port, outputs, leftRumble, rightRumble);
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickIsXbox
- * Signature: (B)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickIsXbox
- (JNIEnv*, jclass, jbyte port)
-{
- return HAL_GetJoystickIsXbox(port);
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickType
- * Signature: (B)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickType
- (JNIEnv*, jclass, jbyte port)
-{
- return HAL_GetJoystickType(port);
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickName
- * Signature: (B)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickName
- (JNIEnv* env, jclass, jbyte port)
-{
- char* joystickName = HAL_GetJoystickName(port);
- jstring str = MakeJString(env, joystickName);
- HAL_FreeJoystickName(joystickName);
- return str;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getJoystickAxisType
- * Signature: (BB)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_getJoystickAxisType
- (JNIEnv*, jclass, jbyte joystickNum, jbyte axis)
-{
- return HAL_GetJoystickAxisType(joystickNum, axis);
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: isNewControlData
- * Signature: ()Z
- */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_hal_HAL_isNewControlData
- (JNIEnv*, jclass)
-{
- return static_cast<jboolean>(HAL_IsNewControlData());
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: waitForDSData
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_waitForDSData
- (JNIEnv* env, jclass)
-{
- HAL_WaitForDSData();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: releaseDSMutex
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_HAL_releaseDSMutex
- (JNIEnv* env, jclass)
-{
- HAL_ReleaseDSMutex();
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: waitForDSDataTimeout
- * Signature: (D)Z
- */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_hal_HAL_waitForDSDataTimeout
- (JNIEnv*, jclass, jdouble timeout)
-{
- return static_cast<jboolean>(HAL_WaitForDSDataTimeout(timeout));
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: getMatchTime
- * Signature: ()D
- */
-JNIEXPORT jdouble JNICALL
-Java_edu_wpi_first_hal_HAL_getMatchTime
- (JNIEnv* env, jclass)
-{
- int32_t status = 0;
- return HAL_GetMatchTime(&status);
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
* Method: getSystemActive
* Signature: ()Z
*/
@@ -442,58 +138,6 @@
/*
* Class: edu_wpi_first_hal_HAL
- * Method: getMatchInfo
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_getMatchInfo
- (JNIEnv* env, jclass, jobject info)
-{
- HAL_MatchInfo matchInfo;
- auto status = HAL_GetMatchInfo(&matchInfo);
- if (status == 0) {
- SetMatchInfoObject(env, info, matchInfo);
- }
- return status;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: sendError
- * Signature: (ZIZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_sendError
- (JNIEnv* env, jclass, jboolean isError, jint errorCode, jboolean isLVCode,
- jstring details, jstring location, jstring callStack, jboolean printMsg)
-{
- JStringRef detailsStr{env, details};
- JStringRef locationStr{env, location};
- JStringRef callStackStr{env, callStack};
-
- jint returnValue =
- HAL_SendError(isError, errorCode, isLVCode, detailsStr.c_str(),
- locationStr.c_str(), callStackStr.c_str(), printMsg);
- return returnValue;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
- * Method: sendConsoleLine
- * Signature: (Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL
-Java_edu_wpi_first_hal_HAL_sendConsoleLine
- (JNIEnv* env, jclass, jstring line)
-{
- JStringRef lineStr{env, line};
-
- jint returnValue = HAL_SendConsoleLine(lineStr.c_str());
- return returnValue;
-}
-
-/*
- * Class: edu_wpi_first_hal_HAL
* Method: getPortWithModule
* Signature: (BB)I
*/
diff --git a/hal/src/main/native/cpp/jni/HALUtil.cpp b/hal/src/main/native/cpp/jni/HALUtil.cpp
index 5d5a958..76c05f8 100644
--- a/hal/src/main/native/cpp/jni/HALUtil.cpp
+++ b/hal/src/main/native/cpp/jni/HALUtil.cpp
@@ -52,6 +52,7 @@
static JClass matchInfoDataCls;
static JClass accumulatorResultCls;
static JClass canDataCls;
+static JClass canStreamMessageCls;
static JClass halValueCls;
static JClass baseStoreCls;
static JClass revPHVersionCls;
@@ -64,6 +65,7 @@
{"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
{"edu/wpi/first/hal/AccumulatorResult", &accumulatorResultCls},
{"edu/wpi/first/hal/CANData", &canDataCls},
+ {"edu/wpi/first/hal/CANStreamMessage", &canStreamMessageCls},
{"edu/wpi/first/hal/HALValue", &halValueCls},
{"edu/wpi/first/hal/DMAJNISample$BaseStore", &baseStoreCls},
{"edu/wpi/first/hal/REVPHVersion", &revPHVersionCls}};
@@ -303,6 +305,18 @@
return retVal;
}
+jbyteArray SetCANStreamObject(JNIEnv* env, jobject canStreamData,
+ int32_t length, uint32_t messageID,
+ uint64_t timestamp) {
+ static jmethodID func =
+ env->GetMethodID(canStreamMessageCls, "setStreamData", "(IIJ)[B");
+
+ jbyteArray retVal = static_cast<jbyteArray>(env->CallObjectMethod(
+ canStreamData, func, static_cast<jint>(length),
+ static_cast<jint>(messageID), static_cast<jlong>(timestamp)));
+ return retVal;
+}
+
jobject CreateHALValue(JNIEnv* env, const HAL_Value& value) {
static jmethodID fromNative = env->GetStaticMethodID(
halValueCls, "fromNative", "(IJD)Ledu/wpi/first/hal/HALValue;");
@@ -444,6 +458,34 @@
/*
* Class: edu_wpi_first_hal_HALUtil
+ * Method: getSerialNumber
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_HALUtil_getSerialNumber
+ (JNIEnv* env, jclass)
+{
+ char serialNum[9];
+ size_t len = HAL_GetSerialNumber(serialNum, sizeof(serialNum));
+ return MakeJString(env, std::string_view(serialNum, len));
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getComments
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_HALUtil_getComments
+ (JNIEnv* env, jclass)
+{
+ char comments[65];
+ size_t len = HAL_GetComments(comments, sizeof(comments));
+ return MakeJString(env, std::string_view(comments, len));
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
* Method: getFPGATime
* Signature: ()J
*/
diff --git a/hal/src/main/native/cpp/jni/HALUtil.h b/hal/src/main/native/cpp/jni/HALUtil.h
index cf3956c..9c9487c 100644
--- a/hal/src/main/native/cpp/jni/HALUtil.h
+++ b/hal/src/main/native/cpp/jni/HALUtil.h
@@ -78,6 +78,10 @@
jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
uint64_t timestamp);
+jbyteArray SetCANStreamObject(JNIEnv* env, jobject canStreamData,
+ int32_t length, uint32_t messageID,
+ uint64_t timestamp);
+
jobject CreateHALValue(JNIEnv* env, const HAL_Value& value);
jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index);
diff --git a/hal/src/main/native/cpp/jni/I2CJNI.cpp b/hal/src/main/native/cpp/jni/I2CJNI.cpp
index b605b95..68b8442 100644
--- a/hal/src/main/native/cpp/jni/I2CJNI.cpp
+++ b/hal/src/main/native/cpp/jni/I2CJNI.cpp
@@ -64,6 +64,16 @@
(JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataToSend,
jbyte sendSize, jbyteArray dataReceived, jbyte receiveSize)
{
+ if (sendSize < 0) {
+ ThrowIllegalArgumentException(env, "I2CJNI.i2cTransactionB() sendSize < 0");
+ return 0;
+ }
+ if (receiveSize < 0) {
+ ThrowIllegalArgumentException(env,
+ "I2CJNI.i2cTransactionB() receiveSize < 0");
+ return 0;
+ }
+
wpi::SmallVector<uint8_t, 128> recvBuf;
recvBuf.resize(receiveSize);
jint returnValue =
@@ -142,6 +152,11 @@
(JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataReceived,
jbyte receiveSize)
{
+ if (receiveSize < 0) {
+ ThrowIllegalArgumentException(env, "I2CJNI.i2cReadB() receiveSize < 0");
+ return 0;
+ }
+
wpi::SmallVector<uint8_t, 128> recvBuf;
recvBuf.resize(receiveSize);
jint returnValue = HAL_ReadI2C(static_cast<HAL_I2CPort>(port), address,
diff --git a/hal/src/main/native/cpp/jni/InterruptJNI.cpp b/hal/src/main/native/cpp/jni/InterruptJNI.cpp
index ed56ce5..e220125 100644
--- a/hal/src/main/native/cpp/jni/InterruptJNI.cpp
+++ b/hal/src/main/native/cpp/jni/InterruptJNI.cpp
@@ -50,15 +50,15 @@
/*
* Class: edu_wpi_first_hal_InterruptJNI
* Method: waitForInterrupt
- * Signature: (IDZ)I
+ * Signature: (IDZ)J
*/
-JNIEXPORT jint JNICALL
+JNIEXPORT jlong JNICALL
Java_edu_wpi_first_hal_InterruptJNI_waitForInterrupt
(JNIEnv* env, jclass, jint interruptHandle, jdouble timeout,
jboolean ignorePrevious)
{
int32_t status = 0;
- int32_t result = HAL_WaitForInterrupt((HAL_InterruptHandle)interruptHandle,
+ int64_t result = HAL_WaitForInterrupt((HAL_InterruptHandle)interruptHandle,
timeout, ignorePrevious, &status);
CheckStatus(env, status);
@@ -67,6 +67,25 @@
/*
* Class: edu_wpi_first_hal_InterruptJNI
+ * Method: waitForMultipleInterrupts
+ * Signature: (IJDZ)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_waitForMultipleInterrupts
+ (JNIEnv* env, jclass, jint interruptHandle, jlong mask, jdouble timeout,
+ jboolean ignorePrevious)
+{
+ int32_t status = 0;
+ int64_t result =
+ HAL_WaitForMultipleInterrupts((HAL_InterruptHandle)interruptHandle, mask,
+ timeout, ignorePrevious, &status);
+
+ CheckStatus(env, status);
+ return result;
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
* Method: readInterruptRisingTimestamp
* Signature: (I)J
*/
diff --git a/hal/src/main/native/cpp/jni/SPIJNI.cpp b/hal/src/main/native/cpp/jni/SPIJNI.cpp
index 67ef56d..4f1e556 100644
--- a/hal/src/main/native/cpp/jni/SPIJNI.cpp
+++ b/hal/src/main/native/cpp/jni/SPIJNI.cpp
@@ -15,6 +15,27 @@
using namespace hal;
using namespace wpi::java;
+static_assert(HAL_SPIPort::HAL_SPI_kInvalid ==
+ edu_wpi_first_hal_SPIJNI_INVALID_PORT);
+static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS0 ==
+ edu_wpi_first_hal_SPIJNI_ONBOARD_CS0_PORT);
+static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS1 ==
+ edu_wpi_first_hal_SPIJNI_ONBOARD_CS1_PORT);
+static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS2 ==
+ edu_wpi_first_hal_SPIJNI_ONBOARD_CS2_PORT);
+static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS3 ==
+ edu_wpi_first_hal_SPIJNI_ONBOARD_CS3_PORT);
+static_assert(HAL_SPIPort::HAL_SPI_kMXP == edu_wpi_first_hal_SPIJNI_MXP_PORT);
+
+static_assert(HAL_SPIMode::HAL_SPI_kMode0 ==
+ edu_wpi_first_hal_SPIJNI_SPI_MODE0);
+static_assert(HAL_SPIMode::HAL_SPI_kMode1 ==
+ edu_wpi_first_hal_SPIJNI_SPI_MODE1);
+static_assert(HAL_SPIMode::HAL_SPI_kMode2 ==
+ edu_wpi_first_hal_SPIJNI_SPI_MODE2);
+static_assert(HAL_SPIMode::HAL_SPI_kMode3 ==
+ edu_wpi_first_hal_SPIJNI_SPI_MODE3);
+
extern "C" {
/*
@@ -63,6 +84,11 @@
(JNIEnv* env, jclass, jint port, jbyteArray dataToSend,
jbyteArray dataReceived, jbyte size)
{
+ if (size < 0) {
+ ThrowIllegalArgumentException(env, "SPIJNI.spiTransactionB() size < 0");
+ return 0;
+ }
+
wpi::SmallVector<uint8_t, 128> recvBuf;
recvBuf.resize(size);
jint retVal =
@@ -120,6 +146,11 @@
(JNIEnv* env, jclass, jint port, jboolean initiate, jobject dataReceived,
jbyte size)
{
+ if (size < 0) {
+ ThrowIllegalArgumentException(env, "SPIJNI.spiRead() size < 0");
+ return 0;
+ }
+
uint8_t* dataReceivedPtr =
reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
jint retVal;
@@ -145,6 +176,11 @@
(JNIEnv* env, jclass, jint port, jboolean initiate, jbyteArray dataReceived,
jbyte size)
{
+ if (size < 0) {
+ ThrowIllegalArgumentException(env, "SPIJNI.spiReadB() size < 0");
+ return 0;
+ }
+
jint retVal;
wpi::SmallVector<uint8_t, 128> recvBuf;
recvBuf.resize(size);
@@ -187,16 +223,27 @@
/*
* Class: edu_wpi_first_hal_SPIJNI
- * Method: spiSetOpts
- * Signature: (IIII)V
+ * Method: spiSetMode
+ * Signature: (II)V
*/
JNIEXPORT void JNICALL
-Java_edu_wpi_first_hal_SPIJNI_spiSetOpts
- (JNIEnv*, jclass, jint port, jint msb_first, jint sample_on_trailing,
- jint clk_idle_high)
+Java_edu_wpi_first_hal_SPIJNI_spiSetMode
+ (JNIEnv*, jclass, jint port, jint mode)
{
- HAL_SetSPIOpts(static_cast<HAL_SPIPort>(port), msb_first, sample_on_trailing,
- clk_idle_high);
+ HAL_SetSPIMode(static_cast<HAL_SPIPort>(port),
+ static_cast<HAL_SPIMode>(mode));
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiGetMode
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiGetMode
+ (JNIEnv*, jclass, jint port)
+{
+ return static_cast<jint>(HAL_GetSPIMode(static_cast<HAL_SPIPort>(port)));
}
/*
@@ -361,6 +408,12 @@
(JNIEnv* env, jclass, jint port, jintArray buffer, jint numToRead,
jdouble timeout)
{
+ if (numToRead < 0) {
+ ThrowIllegalArgumentException(
+ env, "SPIJNI.spiReadAutoReceivedData() numToRead < 0");
+ return 0;
+ }
+
wpi::SmallVector<uint32_t, 128> recvBuf;
recvBuf.resize(numToRead);
int32_t status = 0;
diff --git a/hal/src/main/native/cpp/jni/simulation/AddressableLEDDataJNI.cpp b/hal/src/main/native/cpp/jni/simulation/AddressableLEDDataJNI.cpp
index e888bd3..70b31ab 100644
--- a/hal/src/main/native/cpp/jni/simulation/AddressableLEDDataJNI.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/AddressableLEDDataJNI.cpp
@@ -257,7 +257,7 @@
std::make_unique<HAL_AddressableLEDData[]>(HAL_kAddressableLEDMaxLength);
int32_t length = HALSIM_GetAddressableLEDData(index, data.get());
return MakeJByteArray(
- env, wpi::span(reinterpret_cast<jbyte*>(data.get()), length * 4));
+ env, std::span(reinterpret_cast<jbyte*>(data.get()), length * 4));
}
/*
diff --git a/hal/src/main/native/cpp/jni/simulation/BufferCallbackStore.cpp b/hal/src/main/native/cpp/jni/simulation/BufferCallbackStore.cpp
index 265b363..f83ab62 100644
--- a/hal/src/main/native/cpp/jni/simulation/BufferCallbackStore.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/BufferCallbackStore.cpp
@@ -57,9 +57,8 @@
std::fflush(stdout);
}
- auto toCallbackArr = MakeJByteArray(
- env, std::string_view{reinterpret_cast<const char*>(buffer),
- static_cast<size_t>(length)});
+ auto toCallbackArr =
+ MakeJByteArray(env, {buffer, static_cast<size_t>(length)});
env->CallVoidMethod(m_call, sim::GetBufferCallback(), MakeJString(env, name),
toCallbackArr, static_cast<jint>(length));
@@ -124,6 +123,9 @@
void sim::FreeBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
FreeBufferCallbackFunc freeCallback) {
auto callback = callbackHandles->Free(handle);
+ if (callback == nullptr) {
+ return;
+ }
freeCallback(index, callback->getCallbackId());
callback->free(env);
}
diff --git a/hal/src/main/native/cpp/jni/simulation/ConstBufferCallbackStore.cpp b/hal/src/main/native/cpp/jni/simulation/ConstBufferCallbackStore.cpp
index cba0a5b..af57803 100644
--- a/hal/src/main/native/cpp/jni/simulation/ConstBufferCallbackStore.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/ConstBufferCallbackStore.cpp
@@ -58,9 +58,8 @@
std::fflush(stdout);
}
- auto toCallbackArr = MakeJByteArray(
- env, std::string_view{reinterpret_cast<const char*>(buffer),
- static_cast<size_t>(length)});
+ auto toCallbackArr =
+ MakeJByteArray(env, {buffer, static_cast<size_t>(length)});
env->CallVoidMethod(m_call, sim::GetConstBufferCallback(),
MakeJString(env, name), toCallbackArr,
@@ -117,6 +116,9 @@
void sim::FreeConstBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
FreeConstBufferCallbackFunc freeCallback) {
auto callback = callbackHandles->Free(handle);
+ if (callback == nullptr) {
+ return;
+ }
freeCallback(index, callback->getCallbackId());
callback->free(env);
}
diff --git a/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp b/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp
index acecacb..c50b8e3 100644
--- a/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp
@@ -732,7 +732,8 @@
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickName
(JNIEnv* env, jclass, jint stick, jstring name)
{
- HALSIM_SetJoystickName(stick, JStringRef{env, name}.c_str());
+ JStringRef nameJString{env, name};
+ HALSIM_SetJoystickName(stick, nameJString.c_str(), nameJString.size());
}
/*
@@ -756,7 +757,8 @@
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setGameSpecificMessage
(JNIEnv* env, jclass, jstring message)
{
- HALSIM_SetGameSpecificMessage(JStringRef{env, message}.c_str());
+ JStringRef messageJString{env, message};
+ HALSIM_SetGameSpecificMessage(messageJString.c_str(), messageJString.size());
}
/*
@@ -768,7 +770,8 @@
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setEventName
(JNIEnv* env, jclass, jstring name)
{
- HALSIM_SetEventName(JStringRef{env, name}.c_str());
+ JStringRef nameJString{env, name};
+ HALSIM_SetEventName(nameJString.c_str(), nameJString.size());
}
/*
diff --git a/hal/src/main/native/cpp/jni/simulation/RoboRioDataJNI.cpp b/hal/src/main/native/cpp/jni/simulation/RoboRioDataJNI.cpp
index 03bb0c5..5bcd114 100644
--- a/hal/src/main/native/cpp/jni/simulation/RoboRioDataJNI.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/RoboRioDataJNI.cpp
@@ -4,11 +4,14 @@
#include <jni.h>
+#include <wpi/jni_util.h>
+
#include "CallbackStore.h"
#include "edu_wpi_first_hal_simulation_RoboRioDataJNI.h"
#include "hal/simulation/RoboRioData.h"
using namespace hal;
+using namespace wpi::java;
extern "C" {
@@ -827,6 +830,61 @@
/*
* Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
+ * Method: getSerialNumber
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_getSerialNumber
+ (JNIEnv* env, jclass)
+{
+ char serialNum[9];
+ size_t len = HALSIM_GetRoboRioSerialNumber(serialNum, sizeof(serialNum));
+ return MakeJString(env, std::string_view(serialNum, len));
+}
+
+/*
+ * Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
+ * Method: setSerialNumber
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_setSerialNumber
+ (JNIEnv* env, jclass, jstring serialNumber)
+{
+ JStringRef serialNumberJString{env, serialNumber};
+ HALSIM_SetRoboRioSerialNumber(serialNumberJString.c_str(),
+ serialNumberJString.size());
+}
+
+/*
+ * Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
+ * Method: getComments
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_getComments
+ (JNIEnv* env, jclass)
+{
+ char comments[65];
+ size_t len = HALSIM_GetRoboRioComments(comments, sizeof(comments));
+ return MakeJString(env, std::string_view(comments, len));
+}
+
+/*
+ * Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
+ * Method: setComments
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_setComments
+ (JNIEnv* env, jclass, jstring comments)
+{
+ JStringRef commentsJString{env, comments};
+ HALSIM_SetRoboRioComments(commentsJString.c_str(), commentsJString.size());
+}
+
+/*
+ * Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
* Method: resetData
* Signature: ()V
*/
diff --git a/hal/src/main/native/cpp/jni/simulation/SimDeviceDataJNI.cpp b/hal/src/main/native/cpp/jni/simulation/SimDeviceDataJNI.cpp
index 60ce0f7..c7c2a19 100644
--- a/hal/src/main/native/cpp/jni/simulation/SimDeviceDataJNI.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/SimDeviceDataJNI.cpp
@@ -242,6 +242,9 @@
static void FreeDeviceCallback(JNIEnv* env, SIM_JniHandle handle,
FreeDeviceCallbackFunc freeCallback) {
auto callback = deviceCallbackHandles->Free(handle);
+ if (callback == nullptr) {
+ return;
+ }
freeCallback(callback->getCallbackId());
callback->free(env);
}
@@ -296,6 +299,9 @@
static void FreeValueCallback(JNIEnv* env, SIM_JniHandle handle,
FreeValueCallbackFunc freeCallback) {
auto callback = valueCallbackHandles->Free(handle);
+ if (callback == nullptr) {
+ return;
+ }
freeCallback(callback->getCallbackId());
callback->free(env);
}
@@ -668,7 +674,7 @@
{
int32_t numElems = 0;
const double* elems = HALSIM_GetSimValueEnumDoubleValues(handle, &numElems);
- return MakeJDoubleArray(env, wpi::span(elems, numElems));
+ return MakeJDoubleArray(env, std::span(elems, numElems));
}
/*
diff --git a/hal/src/main/native/cpp/jni/simulation/SpiReadAutoReceiveBufferCallbackStore.cpp b/hal/src/main/native/cpp/jni/simulation/SpiReadAutoReceiveBufferCallbackStore.cpp
index c20f607..5b2ff2b 100644
--- a/hal/src/main/native/cpp/jni/simulation/SpiReadAutoReceiveBufferCallbackStore.cpp
+++ b/hal/src/main/native/cpp/jni/simulation/SpiReadAutoReceiveBufferCallbackStore.cpp
@@ -59,7 +59,7 @@
}
auto toCallbackArr = MakeJIntArray(
- env, wpi::span<const uint32_t>{buffer, static_cast<size_t>(numToRead)});
+ env, std::span<const uint32_t>{buffer, static_cast<size_t>(numToRead)});
jint ret = env->CallIntMethod(m_call, sim::GetBufferCallback(),
MakeJString(env, name), toCallbackArr,
@@ -127,6 +127,9 @@
void sim::FreeSpiBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
FreeSpiBufferCallbackFunc freeCallback) {
auto callback = callbackHandles->Free(handle);
+ if (callback == nullptr) {
+ return;
+ }
freeCallback(index, callback->getCallbackId());
callback->free(env);
}
diff --git a/hal/src/main/native/include/hal/AnalogGyro.h b/hal/src/main/native/include/hal/AnalogGyro.h
index 6e5a9c2..ed7c308 100644
--- a/hal/src/main/native/include/hal/AnalogGyro.h
+++ b/hal/src/main/native/include/hal/AnalogGyro.h
@@ -22,7 +22,7 @@
* Initializes an analog gyro.
*
* @param[in] handle handle to the analog port
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status the error code, or 0 for success
* @return the initialized gyro handle
diff --git a/hal/src/main/native/include/hal/AnalogInput.h b/hal/src/main/native/include/hal/AnalogInput.h
index 956cd21..0a1a3c5 100644
--- a/hal/src/main/native/include/hal/AnalogInput.h
+++ b/hal/src/main/native/include/hal/AnalogInput.h
@@ -22,7 +22,7 @@
* Initializes the analog input port using the given port object.
*
* @param[in] portHandle Handle to the port to initialize.
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status the error code, or 0 for success
* @return the created analog input handle
@@ -46,7 +46,7 @@
HAL_Bool HAL_CheckAnalogModule(int32_t module);
/**
- * Checks that the analog output channel number is value.
+ * Checks that the analog output channel number is valid.
* Verifies that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
diff --git a/hal/src/main/native/include/hal/AnalogOutput.h b/hal/src/main/native/include/hal/AnalogOutput.h
index 26e5231..f9a1f36 100644
--- a/hal/src/main/native/include/hal/AnalogOutput.h
+++ b/hal/src/main/native/include/hal/AnalogOutput.h
@@ -22,7 +22,7 @@
* Initializes the analog output port using the given port object.
*
* @param[in] portHandle handle to the port
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status Error status variable. 0 on success.
* @return the created analog output handle
@@ -58,7 +58,7 @@
int32_t* status);
/**
- * Checks that the analog output channel number is value.
+ * Checks that the analog output channel number is valid.
*
* Verifies that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
diff --git a/hal/src/main/native/include/hal/CANAPI.h b/hal/src/main/native/include/hal/CANAPI.h
index 29859cf..d5244b5 100644
--- a/hal/src/main/native/include/hal/CANAPI.h
+++ b/hal/src/main/native/include/hal/CANAPI.h
@@ -22,7 +22,8 @@
/**
* Initializes a CAN device.
*
- * These follow the FIRST standard CAN layout. Link TBD
+ * These follow the FIRST standard CAN layout.
+ * https://docs.wpilib.org/en/stable/docs/software/can-devices/can-addressing.html
*
* @param[in] manufacturer the can manufacturer
* @param[in] deviceId the device ID (0-63)
diff --git a/hal/src/main/native/include/hal/CANAPITypes.h b/hal/src/main/native/include/hal/CANAPITypes.h
index 1be672e..404eecf 100644
--- a/hal/src/main/native/include/hal/CANAPITypes.h
+++ b/hal/src/main/native/include/hal/CANAPITypes.h
@@ -54,7 +54,8 @@
HAL_CAN_Man_kKauaiLabs = 9,
HAL_CAN_Man_kCopperforge = 10,
HAL_CAN_Man_kPWF = 11,
- HAL_CAN_Man_kStudica = 12
+ HAL_CAN_Man_kStudica = 12,
+ HAL_CAN_Man_kTheThriftyBot = 13
};
// clang-format on
/** @} */
diff --git a/hal/src/main/native/include/hal/ChipObject.h b/hal/src/main/native/include/hal/ChipObject.h
index 4526a1a..23dcb38 100644
--- a/hal/src/main/native/include/hal/ChipObject.h
+++ b/hal/src/main/native/include/hal/ChipObject.h
@@ -34,7 +34,6 @@
#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSysWatchdog.h>
#include <FRC_FPGA_ChipObject/tDMAChannelDescriptor.h>
#include <FRC_FPGA_ChipObject/tDMAManager.h>
-#include <FRC_FPGA_ChipObject/tInterruptManager.h>
#include <FRC_FPGA_ChipObject/tSystem.h>
#include <FRC_FPGA_ChipObject/tSystemInterface.h>
diff --git a/hal/src/main/native/include/hal/DIO.h b/hal/src/main/native/include/hal/DIO.h
index e094a0d..6b922b5 100644
--- a/hal/src/main/native/include/hal/DIO.h
+++ b/hal/src/main/native/include/hal/DIO.h
@@ -23,7 +23,7 @@
*
* @param[in] portHandle the port handle to create from
* @param[in] input true for input, false for output
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status Error status variable. 0 on success.
* @return the created digital handle
@@ -95,6 +95,16 @@
double dutyCycle, int32_t* status);
/**
+ * Configures the digital PWM to be a PPS signal with specified duty cycle.
+ *
+ * @param[in] pwmGenerator the digital PWM handle
+ * @param[in] dutyCycle the percent duty cycle to output [0..1]
+ * @param[out] status Error status variable. 0 on success.
+ */
+void HAL_SetDigitalPWMPPS(HAL_DigitalPWMHandle pwmGenerator, double dutyCycle,
+ int32_t* status);
+
+/**
* Configures which DO channel the PWM signal is output on.
*
* @param[in] pwmGenerator the digital PWM handle
@@ -150,13 +160,26 @@
* single pulse going at any time.
*
* @param[in] dioPortHandle the digital port handle
- * @param[in] pulseLength the active length of the pulse (in seconds)
+ * @param[in] pulseLengthSeconds the active length of the pulse (in seconds)
* @param[out] status Error status variable. 0 on success.
*/
-void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
+void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLengthSeconds,
int32_t* status);
/**
+ * Generates a single digital pulse on multiple channels.
+ *
+ * Write a pulse to the channels enabled by the mask. There can only be a
+ * single pulse going at any time.
+ *
+ * @param[in] channelMask the channel mask
+ * @param[in] pulseLengthSeconds the active length of the pulse (in seconds)
+ * @param[out] status Error status variable. 0 on success.
+ */
+void HAL_PulseMultiple(uint32_t channelMask, double pulseLengthSeconds,
+ int32_t* status);
+
+/**
* Checks a DIO line to see if it is currently generating a pulse.
*
* @param[in] dioPortHandle the digital port handle
diff --git a/hal/src/main/native/include/hal/DriverStation.h b/hal/src/main/native/include/hal/DriverStation.h
index 1839cfc..ae68b65 100644
--- a/hal/src/main/native/include/hal/DriverStation.h
+++ b/hal/src/main/native/include/hal/DriverStation.h
@@ -6,6 +6,8 @@
#include <stdint.h>
+#include <wpi/Synchronization.h>
+
#include "hal/DriverStationTypes.h"
#include "hal/Types.h"
@@ -34,6 +36,14 @@
int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
const char* details, const char* location,
const char* callStack, HAL_Bool printMsg);
+
+/**
+ * Set the print function used by HAL_SendError
+ *
+ * @param func Function called by HAL_SendError when stderr is printed
+ */
+void HAL_SetPrintErrorImpl(void (*func)(const char* line, size_t size));
+
/**
* Sends a line to the driver station console.
*
@@ -87,6 +97,9 @@
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
HAL_JoystickButtons* buttons);
+void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs,
+ HAL_JoystickButtons* buttons);
+
/**
* Retrieves the Joystick Descriptor for particular slot.
*
@@ -184,6 +197,11 @@
double HAL_GetMatchTime(int32_t* status);
/**
+ * Gets if outputs are enabled by the control system.
+ */
+HAL_Bool HAL_GetOutputsEnabled(void);
+
+/**
* Gets info about a specific match.
*
* @param[in] info the match info (output)
@@ -191,44 +209,10 @@
*/
int32_t HAL_GetMatchInfo(HAL_MatchInfo* info);
-/**
- * Releases the DS Mutex to allow proper shutdown of any threads that are
- * waiting on it.
- */
-void HAL_ReleaseDSMutex(void);
+void HAL_RefreshDSData(void);
-/**
- * Has a new control packet from the driver station arrived since the last
- * time this function was called?
- *
- * @return true if the control data has been updated since the last call
- */
-HAL_Bool HAL_IsNewControlData(void);
-
-/**
- * Waits for the newest DS packet to arrive. Note that this is a blocking call.
- * Checks if new control data has arrived since the last HAL_WaitForDSData or
- * HAL_IsNewControlData call. If new data has not arrived, waits for new data
- * to arrive. Otherwise, returns immediately.
- */
-void HAL_WaitForDSData(void);
-
-/**
- * Waits for the newest DS packet to arrive. If timeout is <= 0, this will wait
- * forever. Otherwise, it will wait until either a new packet, or the timeout
- * time has passed.
- *
- * @param[in] timeout timeout in seconds
- * @return true for new data, false for timeout
- */
-HAL_Bool HAL_WaitForDSDataTimeout(double timeout);
-
-/**
- * Initializes the driver station communication. This will properly
- * handle multiple calls. However note that this CANNOT be called from a library
- * that interfaces with LabVIEW.
- */
-void HAL_InitializeDriverStation(void);
+void HAL_ProvideNewDataEventHandle(WPI_EventHandle handle);
+void HAL_RemoveNewDataEventHandle(WPI_EventHandle handle);
/**
* Sets the program starting flag in the DS.
diff --git a/hal/src/main/native/include/hal/DriverStationTypes.h b/hal/src/main/native/include/hal/DriverStationTypes.h
index 21f9088..277c286 100644
--- a/hal/src/main/native/include/hal/DriverStationTypes.h
+++ b/hal/src/main/native/include/hal/DriverStationTypes.h
@@ -69,6 +69,7 @@
struct HAL_JoystickAxes {
int16_t count;
float axes[HAL_kMaxJoystickAxes];
+ uint8_t raw[HAL_kMaxJoystickAxes];
};
typedef struct HAL_JoystickAxes HAL_JoystickAxes;
diff --git a/hal/src/main/native/include/hal/DutyCycle.h b/hal/src/main/native/include/hal/DutyCycle.h
index 05b654b..90266fd 100644
--- a/hal/src/main/native/include/hal/DutyCycle.h
+++ b/hal/src/main/native/include/hal/DutyCycle.h
@@ -71,24 +71,21 @@
int32_t* status);
/**
- * Get the raw output ratio of the duty cycle signal.
- *
- * <p> 0 means always low, an output equal to
- * GetOutputScaleFactor() means always high.
+ * Get the raw high time of the duty cycle signal.
*
* @param[in] dutyCycleHandle the duty cycle handle
* @param[out] status Error status variable. 0 on success.
- * @return output ratio in raw units
+ * @return high time of last pulse in nanoseconds
*/
-int32_t HAL_GetDutyCycleOutputRaw(HAL_DutyCycleHandle dutyCycleHandle,
- int32_t* status);
+int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status);
/**
* Get the scale factor of the output.
*
* <p> An output equal to this value is always high, and then linearly scales
- * down to 0. Divide the result of getOutputRaw by this in order to get the
- * percentage between 0 and 1.
+ * down to 0. Divide a raw result by this in order to get the
+ * percentage between 0 and 1. Used by DMA.
*
* @param[in] dutyCycleHandle the duty cycle handle
* @param[out] status Error status variable. 0 on success.
diff --git a/hal/src/main/native/include/hal/Extensions.h b/hal/src/main/native/include/hal/Extensions.h
index ad3f733..6f64fdb 100644
--- a/hal/src/main/native/include/hal/Extensions.h
+++ b/hal/src/main/native/include/hal/Extensions.h
@@ -10,8 +10,7 @@
* @defgroup hal_extensions Simulator Extensions
* @ingroup hal_capi
* HAL Simulator Extensions. These are libraries that provide additional
- * simulator functionality, such as a Gazebo interface, or a more light weight
- * simulation.
+ * simulator functionality.
*
* An extension must expose the HALSIM_InitExtension entry point which is
* invoked after the library is loaded.
diff --git a/hal/src/main/native/include/hal/HALBase.h b/hal/src/main/native/include/hal/HALBase.h
index b31ec75..1fe6b3a 100644
--- a/hal/src/main/native/include/hal/HALBase.h
+++ b/hal/src/main/native/include/hal/HALBase.h
@@ -6,6 +6,14 @@
#include <stdint.h>
+#ifdef __cplusplus
+#include <cstddef>
+#else
+
+#include <stddef.h> // NOLINT(build/include_order)
+
+#endif
+
#include "hal/Types.h"
/**
@@ -67,6 +75,24 @@
int64_t HAL_GetFPGARevision(int32_t* status);
/**
+ * Returns the serial number.
+ *
+ * @param[out] buffer The serial number.
+ * @param size The maximum characters to copy into buffer.
+ * @return Number of characters copied into buffer.
+ */
+size_t HAL_GetSerialNumber(char* buffer, size_t size);
+
+/**
+ * Returns the comments from the roboRIO web interface.
+ *
+ * @param[out] buffer The comments string.
+ * @param size The maximum characters to copy into buffer.
+ * @return Number of characters copied into buffer.
+ */
+size_t HAL_GetComments(char* buffer, size_t size);
+
+/**
* Returns the runtime type of the HAL.
*
* @return HAL Runtime Type
diff --git a/hal/src/main/native/include/hal/Interrupts.h b/hal/src/main/native/include/hal/Interrupts.h
index def800c..2bccbe9 100644
--- a/hal/src/main/native/include/hal/Interrupts.h
+++ b/hal/src/main/native/include/hal/Interrupts.h
@@ -35,7 +35,7 @@
void HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle);
/**
- * In synchronous mode, waits for the defined interrupt to occur.
+ * Waits for the defined interrupt to occur.
*
* @param[in] interruptHandle the interrupt handle
* @param[in] timeout timeout in seconds
@@ -49,6 +49,21 @@
int32_t* status);
/**
+ * Waits for any interrupt covered by the mask to occur.
+ *
+ * @param[in] interruptHandle the interrupt handle to use for the context
+ * @param[in] mask the mask of interrupts to wait for
+ * @param[in] timeout timeout in seconds
+ * @param[in] ignorePrevious if true, ignore interrupts that happened before
+ * waitForInterrupt was called
+ * @param[out] status Error status variable. 0 on success.
+ * @return the mask of interrupts that fired
+ */
+int64_t HAL_WaitForMultipleInterrupts(HAL_InterruptHandle interruptHandle,
+ int64_t mask, double timeout,
+ HAL_Bool ignorePrevious, int32_t* status);
+
+/**
* Returns the timestamp for the rising interrupt that occurred most recently.
*
* This is in the same time domain as HAL_GetFPGATime(). It only contains the
diff --git a/hal/src/main/native/include/hal/PWM.h b/hal/src/main/native/include/hal/PWM.h
index 7fd125e..df9020b 100644
--- a/hal/src/main/native/include/hal/PWM.h
+++ b/hal/src/main/native/include/hal/PWM.h
@@ -22,7 +22,7 @@
* Initializes a PWM port.
*
* @param[in] portHandle the port to initialize
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status Error status variable. 0 on success.
* @return the created pwm handle
diff --git a/hal/src/main/native/include/hal/PowerDistribution.h b/hal/src/main/native/include/hal/PowerDistribution.h
index 47cc9b2..7c2b582 100644
--- a/hal/src/main/native/include/hal/PowerDistribution.h
+++ b/hal/src/main/native/include/hal/PowerDistribution.h
@@ -37,7 +37,7 @@
*
* @param[in] moduleNumber the module number to initialize
* @param[in] type the type of module to intialize
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* @param[out] status Error status variable. 0 on success.
* @return the created PowerDistribution
*/
diff --git a/hal/src/main/native/include/hal/Relay.h b/hal/src/main/native/include/hal/Relay.h
index 7d711b2..9ee104b 100644
--- a/hal/src/main/native/include/hal/Relay.h
+++ b/hal/src/main/native/include/hal/Relay.h
@@ -27,7 +27,7 @@
* @param[in] portHandle the port handle to initialize
* @param[in] fwd true for the forward port, false for the
* reverse port
- * @param[in] allocationLocation the location where the allocation is occuring
+ * @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status Error status variable. 0 on success.
* @return the created relay handle
diff --git a/hal/src/main/native/include/hal/SPI.h b/hal/src/main/native/include/hal/SPI.h
index 84cec5d..f3c7fdc 100644
--- a/hal/src/main/native/include/hal/SPI.h
+++ b/hal/src/main/native/include/hal/SPI.h
@@ -90,23 +90,27 @@
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
* MXP
- * @param speed The speed in Hz (0-1MHz)
+ * @param speed The speed in Hz (500KHz-10MHz)
*/
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed);
/**
- * Sets the SPI options.
+ * Sets the SPI Mode.
*
- * @param port The number of the port to use. 0-3 for Onboard
- * CS0-CS2, 4 for MXP
- * @param msbFirst True to write the MSB first, False for LSB first
- * @param sampleOnTrailing True to sample on the trailing edge, False to sample
- * on the leading edge
- * @param clkIdleHigh True to set the clock to active low, False to set the
- * clock active high
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP
+ * @param mode The SPI mode to use
*/
-void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
- HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh);
+void HAL_SetSPIMode(HAL_SPIPort port, HAL_SPIMode mode);
+
+/**
+ * Gets the SPI Mode.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP
+ * @returns The SPI mode currently set
+ */
+HAL_SPIMode HAL_GetSPIMode(HAL_SPIPort port);
/**
* Sets the CS Active high for a SPI port.
diff --git a/hal/src/main/native/include/hal/SPITypes.h b/hal/src/main/native/include/hal/SPITypes.h
index de66226..34b5d61 100644
--- a/hal/src/main/native/include/hal/SPITypes.h
+++ b/hal/src/main/native/include/hal/SPITypes.h
@@ -25,6 +25,15 @@
};
// clang-format on
+// clang-format off
+HAL_ENUM(HAL_SPIMode) {
+ HAL_SPI_kMode0 = 0,
+ HAL_SPI_kMode1 = 1,
+ HAL_SPI_kMode2 = 2,
+ HAL_SPI_kMode3 = 3,
+};
+// clang-format on
+
#ifdef __cplusplus
namespace hal {
diff --git a/hal/src/main/native/include/hal/SimDevice.h b/hal/src/main/native/include/hal/SimDevice.h
index 7c0cf2d..f90cb9b 100644
--- a/hal/src/main/native/include/hal/SimDevice.h
+++ b/hal/src/main/native/include/hal/SimDevice.h
@@ -8,8 +8,7 @@
#ifdef __cplusplus
#include <initializer_list>
-
-#include <wpi/span.h>
+#include <span>
#endif
#include "hal/Types.h"
@@ -832,7 +831,7 @@
* @return simulated enum value object
*/
SimEnum CreateEnum(const char* name, int32_t direction,
- wpi::span<const char* const> options,
+ std::span<const char* const> options,
int32_t initialValue) {
return HAL_CreateSimValueEnum(m_handle, name, direction, options.size(),
const_cast<const char**>(options.data()),
@@ -885,8 +884,8 @@
* @return simulated enum value object
*/
SimEnum CreateEnumDouble(const char* name, int32_t direction,
- wpi::span<const char* const> options,
- wpi::span<const double> optionValues,
+ std::span<const char* const> options,
+ std::span<const double> optionValues,
int32_t initialValue) {
if (options.size() != optionValues.size()) {
return {};
diff --git a/hal/src/main/native/include/hal/cpp/UnsafeDIO.h b/hal/src/main/native/include/hal/cpp/UnsafeDIO.h
index eb7f231..c849fd0 100644
--- a/hal/src/main/native/include/hal/cpp/UnsafeDIO.h
+++ b/hal/src/main/native/include/hal/cpp/UnsafeDIO.h
@@ -18,6 +18,16 @@
* outside of the UnsafeManipulateDIO callback.
*/
struct DIOSetProxy {
+ DIOSetProxy(tDIO::tOutputEnable setOutputDirReg,
+ tDIO::tOutputEnable unsetOutputDirReg,
+ tDIO::tDO setOutputStateReg, tDIO::tDO unsetOutputStateReg,
+ tDIO* dio)
+ : m_setOutputDirReg{setOutputDirReg},
+ m_unsetOutputDirReg{unsetOutputDirReg},
+ m_setOutputStateReg{setOutputStateReg},
+ m_unsetOutputStateReg{unsetOutputStateReg},
+ m_dio{dio} {}
+
DIOSetProxy(const DIOSetProxy&) = delete;
DIOSetProxy(DIOSetProxy&&) = delete;
DIOSetProxy& operator=(const DIOSetProxy&) = delete;
diff --git a/hal/src/main/native/include/hal/roborio/InterruptManager.h b/hal/src/main/native/include/hal/roborio/InterruptManager.h
new file mode 100644
index 0000000..36d904b
--- /dev/null
+++ b/hal/src/main/native/include/hal/roborio/InterruptManager.h
@@ -0,0 +1,33 @@
+// 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 <FRC_FPGA_ChipObject/fpgainterfacecapi/NiFpga.h>
+#include <wpi/mutex.h>
+
+#include "hal/ChipObject.h"
+#include "hal/Types.h"
+
+namespace hal {
+class InterruptManager {
+ public:
+ static InterruptManager& GetInstance();
+ static void Initialize(tSystemInterface* baseSystem);
+
+ NiFpga_IrqContext GetContext() noexcept;
+ void ReleaseContext(NiFpga_IrqContext context) noexcept;
+
+ uint32_t WaitForInterrupt(NiFpga_IrqContext context, uint32_t mask,
+ bool ignorePrevious, uint32_t timeoutInMs,
+ int32_t* status);
+
+ private:
+ InterruptManager() = default;
+
+ wpi::priority_mutex currentMaskMutex;
+ uint32_t currentMask;
+ NiFpga_Session fpgaSession;
+};
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/simulation/DriverStationData.h b/hal/src/main/native/include/hal/simulation/DriverStationData.h
index 87223ec..b10cf03 100644
--- a/hal/src/main/native/include/hal/simulation/DriverStationData.h
+++ b/hal/src/main/native/include/hal/simulation/DriverStationData.h
@@ -4,6 +4,8 @@
#pragma once
+#include <cstddef>
+
#include "hal/DriverStationTypes.h"
#include "hal/Types.h"
#include "hal/simulation/NotifyListener.h"
@@ -145,11 +147,11 @@
void HALSIM_SetJoystickIsXbox(int32_t stick, HAL_Bool isXbox);
void HALSIM_SetJoystickType(int32_t stick, int32_t type);
-void HALSIM_SetJoystickName(int32_t stick, const char* name);
+void HALSIM_SetJoystickName(int32_t stick, const char* name, size_t size);
void HALSIM_SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type);
-void HALSIM_SetGameSpecificMessage(const char* message);
-void HALSIM_SetEventName(const char* name);
+void HALSIM_SetGameSpecificMessage(const char* message, size_t size);
+void HALSIM_SetEventName(const char* name, size_t size);
void HALSIM_SetMatchType(HAL_MatchType type);
void HALSIM_SetMatchNumber(int32_t matchNumber);
void HALSIM_SetReplayNumber(int32_t replayNumber);
diff --git a/hal/src/main/native/include/hal/simulation/MockHooks.h b/hal/src/main/native/include/hal/simulation/MockHooks.h
index 330f72e..fe50656 100644
--- a/hal/src/main/native/include/hal/simulation/MockHooks.h
+++ b/hal/src/main/native/include/hal/simulation/MockHooks.h
@@ -36,4 +36,6 @@
HALSIM_SimPeriodicCallback callback, void* param);
void HALSIM_CancelSimPeriodicAfterCallback(int32_t uid);
+void HALSIM_CancelAllSimPeriodicCallbacks(void);
+
} // extern "C"
diff --git a/hal/src/main/native/include/hal/simulation/Reset.h b/hal/src/main/native/include/hal/simulation/Reset.h
new file mode 100644
index 0000000..447321c
--- /dev/null
+++ b/hal/src/main/native/include/hal/simulation/Reset.h
@@ -0,0 +1,7 @@
+// 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
+
+extern "C" void HALSIM_ResetAllSimData(void);
diff --git a/hal/src/main/native/include/hal/simulation/RoboRioData.h b/hal/src/main/native/include/hal/simulation/RoboRioData.h
index 8f33bc5..864be5c 100644
--- a/hal/src/main/native/include/hal/simulation/RoboRioData.h
+++ b/hal/src/main/native/include/hal/simulation/RoboRioData.h
@@ -4,9 +4,14 @@
#pragma once
+#include <cstddef>
+
#include "hal/Types.h"
#include "hal/simulation/NotifyListener.h"
+typedef void (*HAL_RoboRioStringCallback)(const char* name, void* param,
+ const char* str, size_t size);
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -121,6 +126,18 @@
double HALSIM_GetRoboRioBrownoutVoltage(void);
void HALSIM_SetRoboRioBrownoutVoltage(double brownoutVoltage);
+int32_t HALSIM_RegisterRoboRioSerialNumberCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioSerialNumberCallback(int32_t uid);
+size_t HALSIM_GetRoboRioSerialNumber(char* buffer, size_t size);
+void HALSIM_SetRoboRioSerialNumber(const char* serialNumber, size_t size);
+
+int32_t HALSIM_RegisterRoboRioCommentsCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioCommentsCallback(int32_t uid);
+size_t HALSIM_GetRoboRioComments(char* buffer, size_t size);
+void HALSIM_SetRoboRioComments(const char* comments, size_t size);
+
void HALSIM_RegisterRoboRioAllCallbacks(HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
diff --git a/hal/src/main/native/include/hal/simulation/SimDataValue.h b/hal/src/main/native/include/hal/simulation/SimDataValue.h
index 4368a10..0f0cde5 100644
--- a/hal/src/main/native/include/hal/simulation/SimDataValue.h
+++ b/hal/src/main/native/include/hal/simulation/SimDataValue.h
@@ -87,9 +87,21 @@
T (*GetDefault)() = nullptr>
class SimDataValue final : public impl::SimDataValueBase<T, MakeValue> {
public:
+// FIXME: GCC 12.1 gives the false positive "the address of <GetDefault> will
+// never be NULL" because it doesn't realize the default template parameter can
+// make GetDefault nullptr. In C++20, replace "T (*GetDefault)() = nullptr" with
+// "T (*GetDefault)() = [] { return T(); }" and unconditionally call
+// GetDefault() to fix the warning.
+#if __GNUC__ >= 12
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waddress"
+#endif // __GNUC__ >= 12
SimDataValue()
: impl::SimDataValueBase<T, MakeValue>(
GetDefault != nullptr ? GetDefault() : T()) {}
+#if __GNUC__ >= 12
+#pragma GCC diagnostic pop
+#endif // __GNUC__ >= 12
explicit SimDataValue(T value)
: impl::SimDataValueBase<T, MakeValue>(value) {}
@@ -136,22 +148,24 @@
* @param DATA the backing data array
* @param LOWERNAME the lowercase name of the backing data variable
*/
-#define HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, NS, CAPINAME, DATA, LOWERNAME) \
- int32_t NS##_Register##CAPINAME##Callback( \
- int32_t index, HAL_NotifyCallback callback, void* param, \
- HAL_Bool initialNotify) { \
- return DATA[index].LOWERNAME.RegisterCallback(callback, param, \
- initialNotify); \
- } \
- \
- void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) { \
- DATA[index].LOWERNAME.CancelCallback(uid); \
- } \
- \
- TYPE NS##_Get##CAPINAME(int32_t index) { return DATA[index].LOWERNAME; } \
- \
- void NS##_Set##CAPINAME(int32_t index, TYPE LOWERNAME) { \
- DATA[index].LOWERNAME = LOWERNAME; \
+#define HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, NS, CAPINAME, DATA, LOWERNAME) \
+ int32_t NS##_Register##CAPINAME##Callback( \
+ int32_t index, HAL_NotifyCallback callback, void* param, \
+ HAL_Bool initialNotify) { \
+ return DATA[index].LOWERNAME.RegisterCallback(callback, param, \
+ initialNotify); \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) { \
+ DATA[index].LOWERNAME.CancelCallback(uid); \
+ } \
+ \
+ TYPE NS##_Get##CAPINAME(int32_t index) { \
+ return DATA[index].LOWERNAME; \
+ } \
+ \
+ void NS##_Set##CAPINAME(int32_t index, TYPE LOWERNAME) { \
+ DATA[index].LOWERNAME = LOWERNAME; \
}
/**
@@ -220,9 +234,13 @@
DATA->LOWERNAME.CancelCallback(uid); \
} \
\
- TYPE NS##_Get##CAPINAME(void) { return DATA->LOWERNAME; } \
+ TYPE NS##_Get##CAPINAME(void) { \
+ return DATA->LOWERNAME; \
+ } \
\
- void NS##_Set##CAPINAME(TYPE LOWERNAME) { DATA->LOWERNAME = LOWERNAME; }
+ void NS##_Set##CAPINAME(TYPE LOWERNAME) { \
+ DATA->LOWERNAME = LOWERNAME; \
+ }
/**
* Define a stub standard C API for simulation data.
@@ -249,7 +267,9 @@
\
void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) {} \
\
- TYPE NS##_Get##CAPINAME(int32_t index) { return RETURN; } \
+ TYPE NS##_Get##CAPINAME(int32_t index) { \
+ return RETURN; \
+ } \
\
void NS##_Set##CAPINAME(int32_t index, TYPE) {}
@@ -269,18 +289,20 @@
* @param CAPINAME the C API name (usually first letter capitalized)
* @param RETURN what to return from the Get function
*/
-#define HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(TYPE, NS, CAPINAME, RETURN) \
- int32_t NS##_Register##CAPINAME##Callback( \
- int32_t index, int32_t channel, HAL_NotifyCallback callback, \
- void* param, HAL_Bool initialNotify) { \
- return 0; \
- } \
- \
- void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t channel, \
- int32_t uid) {} \
- \
- TYPE NS##_Get##CAPINAME(int32_t index, int32_t channel) { return RETURN; } \
- \
+#define HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(TYPE, NS, CAPINAME, RETURN) \
+ int32_t NS##_Register##CAPINAME##Callback( \
+ int32_t index, int32_t channel, HAL_NotifyCallback callback, \
+ void* param, HAL_Bool initialNotify) { \
+ return 0; \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t channel, \
+ int32_t uid) {} \
+ \
+ TYPE NS##_Get##CAPINAME(int32_t index, int32_t channel) { \
+ return RETURN; \
+ } \
+ \
void NS##_Set##CAPINAME(int32_t index, int32_t channel, TYPE) {}
/**
@@ -306,7 +328,9 @@
\
void NS##_Cancel##CAPINAME##Callback(int32_t uid) {} \
\
- TYPE NS##_Get##CAPINAME(void) { return RETURN; } \
+ TYPE NS##_Get##CAPINAME(void) { \
+ return RETURN; \
+ } \
\
void NS##_Set##CAPINAME(TYPE) {}
diff --git a/hal/src/main/native/sim/CANAPI.cpp b/hal/src/main/native/sim/CANAPI.cpp
index 4d733bb..38014bd 100644
--- a/hal/src/main/native/sim/CANAPI.cpp
+++ b/hal/src/main/native/sim/CANAPI.cpp
@@ -93,6 +93,9 @@
void HAL_CleanCAN(HAL_CANHandle handle) {
auto data = canHandles->Free(handle);
+ if (data == nullptr) {
+ return;
+ }
std::scoped_lock lock(data->mapMutex);
diff --git a/hal/src/main/native/sim/DIO.cpp b/hal/src/main/native/sim/DIO.cpp
index 1b744a1..b611b35 100644
--- a/hal/src/main/native/sim/DIO.cpp
+++ b/hal/src/main/native/sim/DIO.cpp
@@ -151,6 +151,23 @@
SimDigitalPWMData[id].dutyCycle = dutyCycle;
}
+void HAL_SetDigitalPWMPPS(HAL_DigitalPWMHandle pwmGenerator, double dutyCycle,
+ int32_t* status) {
+ auto port = digitalPWMHandles->Get(pwmGenerator);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ int32_t id = *port;
+ if (dutyCycle > 1.0) {
+ dutyCycle = 1.0;
+ }
+ if (dutyCycle < 0.0) {
+ dutyCycle = 0.0;
+ }
+ SimDigitalPWMData[id].dutyCycle = dutyCycle;
+}
+
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
@@ -225,7 +242,7 @@
return value;
}
-void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
+void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLengthSeconds,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -235,6 +252,11 @@
// TODO (Thad) Add this
}
+void HAL_PulseMultiple(uint32_t channelMask, double pulseLengthSeconds,
+ int32_t* status) {
+ // TODO (Thad) Add this
+}
+
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
diff --git a/hal/src/main/native/sim/DigitalInternal.h b/hal/src/main/native/sim/DigitalInternal.h
index cd1ac5f..e7f531e 100644
--- a/hal/src/main/native/sim/DigitalInternal.h
+++ b/hal/src/main/native/sim/DigitalInternal.h
@@ -30,7 +30,7 @@
* reliably down to 10.0 ms; starting at about 8.5ms, the servo sometimes hums
* and get hot; by 5.0ms the hum is nearly continuous
* - 10ms periods work well for Victor 884
- * - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
+ * - 5ms periods allows higher update rates for Luminary Micro Jaguar motor
* controllers. Due to the shipping firmware on the Jaguar, we can't run the
* update period less than 5.05 ms.
*
diff --git a/hal/src/main/native/sim/DriverStation.cpp b/hal/src/main/native/sim/DriverStation.cpp
index 723cdac..c99493d 100644
--- a/hal/src/main/native/sim/DriverStation.cpp
+++ b/hal/src/main/native/sim/DriverStation.cpp
@@ -8,37 +8,94 @@
#include <pthread.h>
#endif
+#include <atomic>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <fmt/format.h>
+#include <wpi/EventVector.h>
#include <wpi/condition_variable.h>
#include <wpi/mutex.h>
#include "HALInitializer.h"
+#include "hal/Errors.h"
#include "hal/cpp/fpga_clock.h"
#include "hal/simulation/MockHooks.h"
#include "mockdata/DriverStationDataInternal.h"
static wpi::mutex msgMutex;
-static wpi::condition_variable* newDSDataAvailableCond;
-static wpi::mutex newDSDataAvailableMutex;
-static int newDSDataAvailableCounter{0};
-static std::atomic_bool isFinalized{false};
static std::atomic<HALSIM_SendErrorHandler> sendErrorHandler{nullptr};
static std::atomic<HALSIM_SendConsoleLineHandler> sendConsoleLineHandler{
nullptr};
+using namespace hal;
+
+static constexpr int kJoystickPorts = 6;
+
+namespace {
+struct JoystickDataCache {
+ JoystickDataCache() { std::memset(this, 0, sizeof(*this)); }
+ void Update();
+
+ HAL_JoystickAxes axes[kJoystickPorts];
+ HAL_JoystickPOVs povs[kJoystickPorts];
+ HAL_JoystickButtons buttons[kJoystickPorts];
+ HAL_AllianceStationID allianceStation;
+ double matchTime;
+};
+static_assert(std::is_standard_layout_v<JoystickDataCache>);
+// static_assert(std::is_trivial_v<JoystickDataCache>);
+
+static std::atomic_bool gShutdown{false};
+
+struct FRCDriverStation {
+ ~FRCDriverStation() { gShutdown = true; }
+ wpi::EventVector newDataEvents;
+ wpi::mutex cacheMutex;
+};
+} // namespace
+
+void JoystickDataCache::Update() {
+ for (int i = 0; i < kJoystickPorts; i++) {
+ SimDriverStationData->GetJoystickAxes(i, &axes[i]);
+ SimDriverStationData->GetJoystickPOVs(i, &povs[i]);
+ SimDriverStationData->GetJoystickButtons(i, &buttons[i]);
+ }
+ allianceStation = SimDriverStationData->allianceStationId;
+ matchTime = SimDriverStationData->matchTime;
+}
+
+#define CHECK_JOYSTICK_NUMBER(stickNum) \
+ if ((stickNum) < 0 || (stickNum) >= HAL_kMaxJoysticks) \
+ return PARAMETER_OUT_OF_RANGE
+
+static HAL_ControlWord newestControlWord;
+static JoystickDataCache caches[3];
+static JoystickDataCache* currentRead = &caches[0];
+static JoystickDataCache* currentReadLocal = &caches[0];
+static std::atomic<JoystickDataCache*> currentCache{&caches[1]};
+static JoystickDataCache* lastGiven = &caches[1];
+static JoystickDataCache* cacheToUpdate = &caches[2];
+
+static ::FRCDriverStation* driverStation;
+
namespace hal::init {
void InitializeDriverStation() {
- static wpi::condition_variable nddaC;
- newDSDataAvailableCond = &nddaC;
+ static FRCDriverStation ds;
+ driverStation = &ds;
}
} // namespace hal::init
-using namespace hal;
+namespace hal {
+static void DefaultPrintErrorImpl(const char* line, size_t size) {
+ std::fwrite(line, size, 1, stderr);
+}
+} // namespace hal
+
+static std::atomic<void (*)(const char* line, size_t size)> gPrintErrorImpl{
+ hal::DefaultPrintErrorImpl};
extern "C" {
@@ -92,7 +149,8 @@
if (callStack && callStack[0] != '\0') {
fmt::format_to(fmt::appender{buf}, "{}\n", callStack);
}
- std::fwrite(buf.data(), buf.size(), 1, stderr);
+ auto printError = gPrintErrorImpl.load();
+ printError(buf.data(), buf.size());
}
if (i == KEEP_MSGS) {
// replace the oldest one
@@ -111,6 +169,10 @@
return retval;
}
+void HAL_SetPrintErrorImpl(void (*func)(const char* line, size_t size)) {
+ gPrintErrorImpl.store(func ? func : hal::DefaultPrintErrorImpl);
+}
+
int32_t HAL_SendConsoleLine(const char* line) {
auto handler = sendConsoleLineHandler.load();
if (handler) {
@@ -122,39 +184,67 @@
}
int32_t HAL_GetControlWord(HAL_ControlWord* controlWord) {
- std::memset(controlWord, 0, sizeof(HAL_ControlWord));
- controlWord->enabled = SimDriverStationData->enabled;
- controlWord->autonomous = SimDriverStationData->autonomous;
- controlWord->test = SimDriverStationData->test;
- controlWord->eStop = SimDriverStationData->eStop;
- controlWord->fmsAttached = SimDriverStationData->fmsAttached;
- controlWord->dsAttached = SimDriverStationData->dsAttached;
+ if (gShutdown) {
+ return INCOMPATIBLE_STATE;
+ }
+ std::scoped_lock lock{driverStation->cacheMutex};
+ *controlWord = newestControlWord;
return 0;
}
HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
- *status = 0;
- return SimDriverStationData->allianceStationId;
+ if (gShutdown) {
+ return HAL_AllianceStationID_kRed1;
+ }
+ std::scoped_lock lock{driverStation->cacheMutex};
+ return currentRead->allianceStation;
}
int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes) {
- SimDriverStationData->GetJoystickAxes(joystickNum, axes);
+ if (gShutdown) {
+ return INCOMPATIBLE_STATE;
+ }
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{driverStation->cacheMutex};
+ *axes = currentRead->axes[joystickNum];
return 0;
}
int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
- SimDriverStationData->GetJoystickPOVs(joystickNum, povs);
+ if (gShutdown) {
+ return INCOMPATIBLE_STATE;
+ }
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{driverStation->cacheMutex};
+ *povs = currentRead->povs[joystickNum];
return 0;
}
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
HAL_JoystickButtons* buttons) {
- SimDriverStationData->GetJoystickButtons(joystickNum, buttons);
+ if (gShutdown) {
+ return INCOMPATIBLE_STATE;
+ }
+ CHECK_JOYSTICK_NUMBER(joystickNum);
+ std::scoped_lock lock{driverStation->cacheMutex};
+ *buttons = currentRead->buttons[joystickNum];
return 0;
}
+void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs,
+ HAL_JoystickButtons* buttons) {
+ if (gShutdown) {
+ return;
+ }
+ std::scoped_lock lock{driverStation->cacheMutex};
+ std::memcpy(axes, currentRead->axes, sizeof(currentRead->axes));
+ std::memcpy(povs, currentRead->povs, sizeof(currentRead->povs));
+ std::memcpy(buttons, currentRead->buttons, sizeof(currentRead->buttons));
+}
+
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
HAL_JoystickDescriptor* desc) {
+ CHECK_JOYSTICK_NUMBER(joystickNum);
SimDriverStationData->GetJoystickDescriptor(joystickNum, desc);
return 0;
}
@@ -196,7 +286,11 @@
}
double HAL_GetMatchTime(int32_t* status) {
- return SimDriverStationData->matchTime;
+ if (gShutdown) {
+ return 0;
+ }
+ std::scoped_lock lock{driverStation->cacheMutex};
+ return currentRead->matchTime;
}
int32_t HAL_GetMatchInfo(HAL_MatchInfo* info) {
@@ -224,103 +318,74 @@
// TODO
}
-static int& GetThreadLocalLastCount() {
- // There is a rollover error condition here. At Packet# = n * (uintmax), this
- // will return false when instead it should return true. However, this at a
- // 20ms rate occurs once every 2.7 years of DS connected runtime, so not
- // worth the cycles to check.
- thread_local int lastCount{0};
- return lastCount;
+void HAL_RefreshDSData(void) {
+ if (gShutdown) {
+ return;
+ }
+ HAL_ControlWord controlWord;
+ std::memset(&controlWord, 0, sizeof(controlWord));
+ controlWord.enabled = SimDriverStationData->enabled;
+ controlWord.autonomous = SimDriverStationData->autonomous;
+ controlWord.test = SimDriverStationData->test;
+ controlWord.eStop = SimDriverStationData->eStop;
+ controlWord.fmsAttached = SimDriverStationData->fmsAttached;
+ controlWord.dsAttached = SimDriverStationData->dsAttached;
+ std::scoped_lock lock{driverStation->cacheMutex};
+ JoystickDataCache* prev = currentCache.exchange(nullptr);
+ if (prev != nullptr) {
+ currentRead = prev;
+ }
+ newestControlWord = controlWord;
}
-HAL_Bool HAL_IsNewControlData(void) {
- std::scoped_lock lock(newDSDataAvailableMutex);
- int& lastCount = GetThreadLocalLastCount();
- int currentCount = newDSDataAvailableCounter;
- if (lastCount == currentCount) {
- return false;
+void HAL_ProvideNewDataEventHandle(WPI_EventHandle handle) {
+ if (gShutdown) {
+ return;
}
- lastCount = currentCount;
- return true;
-}
-
-void HAL_WaitForDSData(void) {
- HAL_WaitForDSDataTimeout(0);
-}
-
-HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
- std::unique_lock lock(newDSDataAvailableMutex);
- int& lastCount = GetThreadLocalLastCount();
- int currentCount = newDSDataAvailableCounter;
- if (lastCount != currentCount) {
- lastCount = currentCount;
- return true;
- }
-
- if (isFinalized.load()) {
- return false;
- }
- auto timeoutTime =
- std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
-
- while (newDSDataAvailableCounter == currentCount) {
- if (timeout > 0) {
- auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
- if (timedOut == std::cv_status::timeout) {
- return false;
- }
- } else {
- newDSDataAvailableCond->wait(lock);
- }
- }
- lastCount = newDSDataAvailableCounter;
- return true;
-}
-
-// Constant number to be used for our occur handle
-constexpr int32_t refNumber = 42;
-
-static int32_t newDataOccur(uint32_t refNum) {
- // Since we could get other values, require our specific handle
- // to signal our threads
- if (refNum != refNumber) {
- return 0;
- }
- SimDriverStationData->CallNewDataCallbacks();
- std::scoped_lock lock(newDSDataAvailableMutex);
- // Nofify all threads
- newDSDataAvailableCounter++;
- newDSDataAvailableCond->notify_all();
- return 0;
-}
-
-void HAL_InitializeDriverStation(void) {
hal::init::CheckInit();
- static std::atomic_bool initialized{false};
- static wpi::mutex initializeMutex;
- // Initial check, as if it's true initialization has finished
- if (initialized) {
- return;
- }
-
- std::scoped_lock lock(initializeMutex);
- // Second check in case another thread was waiting
- if (initialized) {
- return;
- }
-
- SimDriverStationData->ResetData();
-
- std::atexit([]() {
- isFinalized.store(true);
- HAL_ReleaseDSMutex();
- });
-
- initialized = true;
+ driverStation->newDataEvents.Add(handle);
}
-void HAL_ReleaseDSMutex(void) {
- newDataOccur(refNumber);
+void HAL_RemoveNewDataEventHandle(WPI_EventHandle handle) {
+ if (gShutdown) {
+ return;
+ }
+ driverStation->newDataEvents.Remove(handle);
+}
+
+HAL_Bool HAL_GetOutputsEnabled(void) {
+ if (gShutdown) {
+ return false;
+ }
+ std::scoped_lock lock{driverStation->cacheMutex};
+ return newestControlWord.enabled && newestControlWord.dsAttached;
}
} // extern "C"
+
+namespace hal {
+void NewDriverStationData() {
+ if (gShutdown) {
+ return;
+ }
+ cacheToUpdate->Update();
+
+ JoystickDataCache* given = cacheToUpdate;
+ JoystickDataCache* prev = currentCache.exchange(cacheToUpdate);
+ if (prev == nullptr) {
+ cacheToUpdate = currentReadLocal;
+ currentReadLocal = lastGiven;
+ } else {
+ // Current read local does not update
+ cacheToUpdate = prev;
+ }
+ lastGiven = given;
+
+ driverStation->newDataEvents.Wakeup();
+ SimDriverStationData->CallNewDataCallbacks();
+}
+
+void InitializeDriverStation() {
+ SimDriverStationData->ResetData();
+}
+} // namespace hal
diff --git a/hal/src/main/native/sim/DutyCycle.cpp b/hal/src/main/native/sim/DutyCycle.cpp
index 51c6506..f46d2da 100644
--- a/hal/src/main/native/sim/DutyCycle.cpp
+++ b/hal/src/main/native/sim/DutyCycle.cpp
@@ -84,6 +84,7 @@
}
return SimDutyCycleData[dutyCycle->index].frequency;
}
+
double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
int32_t* status) {
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
@@ -93,20 +94,29 @@
}
return SimDutyCycleData[dutyCycle->index].output;
}
-int32_t HAL_GetDutyCycleOutputRaw(HAL_DutyCycleHandle dutyCycleHandle,
- int32_t* status) {
+
+int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
if (dutyCycle == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
- return SimDutyCycleData[dutyCycle->index].output *
- HAL_GetDutyCycleOutputScaleFactor(dutyCycleHandle, status);
+
+ if (SimDutyCycleData[dutyCycle->index].frequency == 0) {
+ return 0;
+ }
+
+ double periodSeconds = 1.0 / SimDutyCycleData[dutyCycle->index].frequency;
+ double periodNanoSeconds = periodSeconds * 1e9;
+ return periodNanoSeconds * SimDutyCycleData[dutyCycle->index].output;
}
+
int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,
int32_t* status) {
return 4e7 - 1;
}
+
int32_t HAL_GetDutyCycleFPGAIndex(HAL_DutyCycleHandle dutyCycleHandle,
int32_t* status) {
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
diff --git a/hal/src/main/native/sim/Encoder.cpp b/hal/src/main/native/sim/Encoder.cpp
index 78aa281..137ee78 100644
--- a/hal/src/main/native/sim/Encoder.cpp
+++ b/hal/src/main/native/sim/Encoder.cpp
@@ -53,7 +53,7 @@
HAL_FPGAEncoderHandle* fpgaHandle,
HAL_CounterHandle* counterHandle) {
auto encoder = encoderHandles->Get(handle);
- if (!handle) {
+ if (!encoder) {
return false;
}
diff --git a/hal/src/main/native/sim/HAL.cpp b/hal/src/main/native/sim/HAL.cpp
index 8d911df..82dd8c4 100644
--- a/hal/src/main/native/sim/HAL.cpp
+++ b/hal/src/main/native/sim/HAL.cpp
@@ -57,6 +57,10 @@
static SimPeriodicCallbackRegistry gSimPeriodicBefore;
static SimPeriodicCallbackRegistry gSimPeriodicAfter;
+namespace hal {
+void InitializeDriverStation();
+} // namespace hal
+
namespace hal::init {
void InitializeHAL() {
InitializeAccelerometerData();
@@ -276,6 +280,14 @@
return 0; // TODO: Find a better number to return;
}
+size_t HAL_GetSerialNumber(char* buffer, size_t size) {
+ return HALSIM_GetRoboRioSerialNumber(buffer, size);
+}
+
+size_t HAL_GetComments(char* buffer, size_t size) {
+ return HALSIM_GetRoboRioComments(buffer, size);
+}
+
uint64_t HAL_GetFPGATime(int32_t* status) {
return hal::GetFPGATime();
}
@@ -335,7 +347,7 @@
hal::init::HAL_IsInitialized.store(true);
hal::RestartTiming();
- HAL_InitializeDriverStation();
+ hal::InitializeDriverStation();
initialized = true;
@@ -409,6 +421,11 @@
gSimPeriodicAfter.Cancel(uid);
}
+void HALSIM_CancelAllSimPeriodicCallbacks(void) {
+ gSimPeriodicBefore.Reset();
+ gSimPeriodicAfter.Reset();
+}
+
int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
const char* feature) {
return 0; // Do nothing for now
diff --git a/hal/src/main/native/sim/Interrupts.cpp b/hal/src/main/native/sim/Interrupts.cpp
index e55316d..ac9f7f8 100644
--- a/hal/src/main/native/sim/Interrupts.cpp
+++ b/hal/src/main/native/sim/Interrupts.cpp
@@ -351,6 +351,26 @@
}
}
+int64_t HAL_WaitForMultipleInterrupts(HAL_InterruptHandle interruptHandle,
+ int64_t mask, double timeout,
+ HAL_Bool ignorePrevious,
+ int32_t* status) {
+ // TODO make this properly work, will require a decent rewrite
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return WaitResult::Timeout;
+ }
+
+ if (interrupt->isAnalog) {
+ return WaitForInterruptAnalog(interruptHandle, interrupt.get(), timeout,
+ ignorePrevious);
+ } else {
+ return WaitForInterruptDigital(interruptHandle, interrupt.get(), timeout,
+ ignorePrevious);
+ }
+}
+
int64_t HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto interrupt = interruptHandles->Get(interruptHandle);
diff --git a/hal/src/main/native/sim/MockHooks.cpp b/hal/src/main/native/sim/MockHooks.cpp
index 4e20c6a..93c385e 100644
--- a/hal/src/main/native/sim/MockHooks.cpp
+++ b/hal/src/main/native/sim/MockHooks.cpp
@@ -122,7 +122,7 @@
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
uint64_t nextTimeout = HALSIM_GetNextNotifierTimeout();
- uint64_t step = std::min(delta, nextTimeout - curTime);
+ uint64_t step = (std::min)(delta, nextTimeout - curTime);
StepTiming(step);
delta -= step;
diff --git a/hal/src/main/native/sim/PowerDistribution.cpp b/hal/src/main/native/sim/PowerDistribution.cpp
index ddda420..22e4bba 100644
--- a/hal/src/main/native/sim/PowerDistribution.cpp
+++ b/hal/src/main/native/sim/PowerDistribution.cpp
@@ -147,11 +147,23 @@
}
double HAL_GetPowerDistributionTotalCurrent(HAL_PowerDistributionHandle handle,
int32_t* status) {
- return 0.0;
+ auto module = hal::can::GetCANModuleFromHandle(handle, status);
+ if (*status != 0) {
+ return 0.0;
+ }
+
+ double total = 0.0;
+ auto& data = SimPowerDistributionData[module];
+ for (int i = 0; i < kNumPDSimChannels; i++) {
+ total += data.current[i];
+ }
+ return total;
}
double HAL_GetPowerDistributionTotalPower(HAL_PowerDistributionHandle handle,
int32_t* status) {
- return 0.0;
+ double voltage = HAL_GetPowerDistributionVoltage(handle, status);
+ double current = HAL_GetPowerDistributionTotalCurrent(handle, status);
+ return voltage * current;
}
double HAL_GetPowerDistributionTotalEnergy(HAL_PowerDistributionHandle handle,
int32_t* status) {
diff --git a/hal/src/main/native/sim/SPI.cpp b/hal/src/main/native/sim/SPI.cpp
index bf362a8..70e2bde 100644
--- a/hal/src/main/native/sim/SPI.cpp
+++ b/hal/src/main/native/sim/SPI.cpp
@@ -34,8 +34,10 @@
SimSPIData[port].initialized = false;
}
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {}
-void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
- HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {}
+void HAL_SetSPIMode(HAL_SPIPort port, HAL_SPIMode mode) {}
+HAL_SPIMode HAL_GetSPIMode(HAL_SPIPort port) {
+ return HAL_SPI_kMode0;
+}
void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {}
void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {}
int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
diff --git a/hal/src/main/native/sim/mockdata/DriverStationData.cpp b/hal/src/main/native/sim/mockdata/DriverStationData.cpp
index 1c76a7a..a0cae1c 100644
--- a/hal/src/main/native/sim/mockdata/DriverStationData.cpp
+++ b/hal/src/main/native/sim/mockdata/DriverStationData.cpp
@@ -216,8 +216,12 @@
m_newDataCallbacks(&empty);
}
+namespace hal {
+void NewDriverStationData();
+} // namespace hal
+
void DriverStationData::NotifyNewData() {
- HAL_ReleaseDSMutex();
+ hal::NewDriverStationData();
}
void DriverStationData::SetJoystickButton(int32_t stick, int32_t button,
@@ -335,14 +339,17 @@
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
-void DriverStationData::SetJoystickName(int32_t stick, const char* name) {
+void DriverStationData::SetJoystickName(int32_t stick, const char* name,
+ size_t size) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
- std::strncpy(m_joystickData[stick].descriptor.name, name,
- sizeof(m_joystickData[stick].descriptor.name) - 1);
- *(std::end(m_joystickData[stick].descriptor.name) - 1) = '\0';
+ if (size > sizeof(m_joystickData[stick].descriptor.name) - 1) {
+ size = sizeof(m_joystickData[stick].descriptor.name) - 1;
+ }
+ std::strncpy(m_joystickData[stick].descriptor.name, name, size);
+ m_joystickData[stick].descriptor.name[size] = '\0';
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
@@ -359,19 +366,27 @@
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
-void DriverStationData::SetGameSpecificMessage(const char* message) {
+void DriverStationData::SetGameSpecificMessage(const char* message,
+ size_t size) {
std::scoped_lock lock(m_matchInfoMutex);
+ if (size > sizeof(m_matchInfo.gameSpecificMessage) - 1) {
+ size = sizeof(m_matchInfo.gameSpecificMessage) - 1;
+ }
std::strncpy(reinterpret_cast<char*>(m_matchInfo.gameSpecificMessage),
- message, sizeof(m_matchInfo.gameSpecificMessage) - 1);
- *(std::end(m_matchInfo.gameSpecificMessage) - 1) = '\0';
- m_matchInfo.gameSpecificMessageSize = std::strlen(message);
+ message, size);
+ m_matchInfo.gameSpecificMessage[size] = '\0';
+ m_matchInfo.gameSpecificMessageSize =
+ std::strlen(reinterpret_cast<char*>(m_matchInfo.gameSpecificMessage));
m_matchInfoCallbacks(&m_matchInfo);
}
-void DriverStationData::SetEventName(const char* name) {
+void DriverStationData::SetEventName(const char* name, size_t size) {
std::scoped_lock lock(m_matchInfoMutex);
- std::strncpy(m_matchInfo.eventName, name, sizeof(m_matchInfo.eventName) - 1);
- *(std::end(m_matchInfo.eventName) - 1) = '\0';
+ if (size > sizeof(m_matchInfo.eventName) - 1) {
+ size = sizeof(m_matchInfo.eventName) - 1;
+ }
+ std::strncpy(m_matchInfo.eventName, name, size);
+ m_matchInfo.eventName[size] = '\0';
m_matchInfoCallbacks(&m_matchInfo);
}
@@ -536,20 +551,20 @@
SimDriverStationData->SetJoystickType(stick, type);
}
-void HALSIM_SetJoystickName(int32_t stick, const char* name) {
- SimDriverStationData->SetJoystickName(stick, name);
+void HALSIM_SetJoystickName(int32_t stick, const char* name, size_t size) {
+ SimDriverStationData->SetJoystickName(stick, name, size);
}
void HALSIM_SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type) {
SimDriverStationData->SetJoystickAxisType(stick, axis, type);
}
-void HALSIM_SetGameSpecificMessage(const char* message) {
- SimDriverStationData->SetGameSpecificMessage(message);
+void HALSIM_SetGameSpecificMessage(const char* message, size_t size) {
+ SimDriverStationData->SetGameSpecificMessage(message, size);
}
-void HALSIM_SetEventName(const char* name) {
- SimDriverStationData->SetEventName(name);
+void HALSIM_SetEventName(const char* name, size_t size) {
+ SimDriverStationData->SetEventName(name, size);
}
void HALSIM_SetMatchType(HAL_MatchType type) {
diff --git a/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h
index 2470b04..763b465 100644
--- a/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h
+++ b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h
@@ -107,11 +107,11 @@
void SetJoystickIsXbox(int32_t stick, HAL_Bool isXbox);
void SetJoystickType(int32_t stick, int32_t type);
- void SetJoystickName(int32_t stick, const char* name);
+ void SetJoystickName(int32_t stick, const char* name, size_t size);
void SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type);
- void SetGameSpecificMessage(const char* message);
- void SetEventName(const char* name);
+ void SetGameSpecificMessage(const char* message, size_t size);
+ void SetEventName(const char* name, size_t size);
void SetMatchType(HAL_MatchType type);
void SetMatchNumber(int32_t matchNumber);
void SetReplayNumber(int32_t replayNumber);
diff --git a/hal/src/main/native/sim/mockdata/Reset.cpp b/hal/src/main/native/sim/mockdata/Reset.cpp
new file mode 100644
index 0000000..bb83973
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/Reset.cpp
@@ -0,0 +1,109 @@
+// 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 <hal/simulation/AccelerometerData.h>
+#include <hal/simulation/AddressableLEDData.h>
+#include <hal/simulation/AnalogGyroData.h>
+#include <hal/simulation/AnalogInData.h>
+#include <hal/simulation/AnalogOutData.h>
+#include <hal/simulation/AnalogTriggerData.h>
+#include <hal/simulation/CTREPCMData.h>
+#include <hal/simulation/CanData.h>
+#include <hal/simulation/DIOData.h>
+#include <hal/simulation/DigitalPWMData.h>
+#include <hal/simulation/DriverStationData.h>
+#include <hal/simulation/DutyCycleData.h>
+#include <hal/simulation/EncoderData.h>
+#include <hal/simulation/I2CData.h>
+#include <hal/simulation/PWMData.h>
+#include <hal/simulation/PowerDistributionData.h>
+#include <hal/simulation/REVPHData.h>
+#include <hal/simulation/RelayData.h>
+#include <hal/simulation/RoboRioData.h>
+#include <hal/simulation/SPIAccelerometerData.h>
+#include <hal/simulation/SPIData.h>
+#include <hal/simulation/SimDeviceData.h>
+
+#include "../PortsInternal.h"
+
+extern "C" void HALSIM_ResetAllSimData(void) {
+ for (int32_t i = 0; i < hal::kAccelerometers; i++) {
+ HALSIM_ResetAccelerometerData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumAddressableLEDs; i++) {
+ HALSIM_ResetAddressableLEDData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumAccumulators; i++) {
+ HALSIM_ResetAnalogGyroData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumAnalogInputs; i++) {
+ HALSIM_ResetAnalogInData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumAnalogOutputs; i++) {
+ HALSIM_ResetAnalogOutData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumAnalogTriggers; i++) {
+ HALSIM_ResetAnalogTriggerData(i);
+ }
+
+ HALSIM_ResetCanData();
+
+ for (int32_t i = 0; i < hal::kNumCTREPCMModules; i++) {
+ HALSIM_ResetCTREPCMData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumDigitalPWMOutputs; i++) {
+ HALSIM_ResetDigitalPWMData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumDigitalChannels; i++) {
+ HALSIM_ResetDIOData(i);
+ }
+
+ HALSIM_ResetDriverStationData();
+
+ for (int32_t i = 0; i < hal::kNumDutyCycles; i++) {
+ HALSIM_ResetDutyCycleData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumEncoders; i++) {
+ HALSIM_ResetEncoderData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kI2CPorts; i++) {
+ HALSIM_ResetI2CData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumPDSimModules; i++) {
+ HALSIM_ResetPowerDistributionData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumPWMChannels; i++) {
+ HALSIM_ResetPWMData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumRelayHeaders; i++) {
+ HALSIM_ResetRelayData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kNumREVPHModules; i++) {
+ HALSIM_ResetREVPHData(i);
+ }
+
+ HALSIM_ResetRoboRioData();
+ HALSIM_ResetSimDeviceData();
+
+ for (int32_t i = 0; i < hal::kSPIAccelerometers; i++) {
+ HALSIM_ResetSPIAccelerometerData(i);
+ }
+
+ for (int32_t i = 0; i < hal::kSPIPorts; i++) {
+ HALSIM_ResetSPIData(i);
+ }
+}
diff --git a/hal/src/main/native/sim/mockdata/RoboRioData.cpp b/hal/src/main/native/sim/mockdata/RoboRioData.cpp
index 6932620..b73b0d9 100644
--- a/hal/src/main/native/sim/mockdata/RoboRioData.cpp
+++ b/hal/src/main/native/sim/mockdata/RoboRioData.cpp
@@ -32,6 +32,79 @@
userFaults5V.Reset(0);
userFaults3V3.Reset(0);
brownoutVoltage.Reset(6.75);
+ m_serialNumber = "";
+ m_comments = "";
+}
+
+int32_t RoboRioData::RegisterSerialNumberCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
+ std::scoped_lock lock(m_serialNumberMutex);
+ int32_t uid = m_serialNumberCallbacks.Register(callback, param);
+ if (initialNotify) {
+ callback(GetSerialNumberName(), param, m_serialNumber.c_str(),
+ m_serialNumber.size());
+ }
+ return uid;
+}
+
+void RoboRioData::CancelSerialNumberCallback(int32_t uid) {
+ m_serialNumberCallbacks.Cancel(uid);
+}
+
+size_t RoboRioData::GetSerialNumber(char* buffer, size_t size) {
+ std::scoped_lock lock(m_serialNumberMutex);
+ size_t copied = m_serialNumber.copy(buffer, size);
+ // Null terminate
+ if (copied == size) {
+ copied -= 1;
+ }
+ buffer[copied] = '\0';
+ return copied;
+}
+
+void RoboRioData::SetSerialNumber(const char* serialNumber, size_t size) {
+ // Limit serial number to 8 characters internally- serialnum environment
+ // variable is always 8 characters
+ if (size > 8) {
+ size = 8;
+ }
+ std::scoped_lock lock(m_serialNumberMutex);
+ m_serialNumber = std::string(serialNumber, size);
+ m_serialNumberCallbacks(m_serialNumber.c_str(), m_serialNumber.size());
+}
+
+int32_t RoboRioData::RegisterCommentsCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
+ std::scoped_lock lock(m_commentsMutex);
+ int32_t uid = m_commentsCallbacks.Register(callback, param);
+ if (initialNotify) {
+ callback(GetCommentsName(), param, m_comments.c_str(),
+ m_serialNumber.size());
+ }
+ return uid;
+}
+
+void RoboRioData::CancelCommentsCallback(int32_t uid) {
+ m_commentsCallbacks.Cancel(uid);
+}
+
+size_t RoboRioData::GetComments(char* buffer, size_t size) {
+ std::scoped_lock lock(m_commentsMutex);
+ size_t copied = m_comments.copy(buffer, size);
+ // Null terminate if there is room
+ if (copied < size) {
+ buffer[copied] = '\0';
+ }
+ return copied;
+}
+
+void RoboRioData::SetComments(const char* comments, size_t size) {
+ if (size > 64) {
+ size = 64;
+ }
+ std::scoped_lock lock(m_commentsMutex);
+ m_comments = std::string(comments, size);
+ m_commentsCallbacks(m_comments.c_str(), m_comments.size());
}
extern "C" {
@@ -60,6 +133,39 @@
DEFINE_CAPI(int32_t, UserFaults3V3, userFaults3V3)
DEFINE_CAPI(double, BrownoutVoltage, brownoutVoltage)
+int32_t HALSIM_RegisterRoboRioSerialNumberCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
+ return SimRoboRioData->RegisterSerialNumberCallback(callback, param,
+ initialNotify);
+}
+void HALSIM_CancelRoboRioSerialNumberCallback(int32_t uid) {
+ return SimRoboRioData->CancelSerialNumberCallback(uid);
+}
+size_t HALSIM_GetRoboRioSerialNumber(char* buffer, size_t size) {
+ return SimRoboRioData->GetSerialNumber(buffer, size);
+}
+void HALSIM_SetRoboRioSerialNumber(const char* serialNumber, size_t size) {
+ SimRoboRioData->SetSerialNumber(serialNumber, size);
+}
+
+int32_t HALSIM_RegisterRoboRioCommentsCallback(
+ HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
+ return SimRoboRioData->RegisterCommentsCallback(callback, param,
+ initialNotify);
+}
+void HALSIM_CancelRoboRioCommentsCallback(int32_t uid) {
+ SimRoboRioData->CancelCommentsCallback(uid);
+}
+size_t HALSIM_GetRoboRioComments(char* buffer, size_t size) {
+ return SimRoboRioData->GetComments(buffer, size);
+}
+void HALSIM_SetRoboRioComments(const char* comments, size_t size) {
+ SimRoboRioData->SetComments(comments, size);
+}
+
+void HALSIM_RegisterRoboRioAllCallbacks(HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
#define REGISTER(NAME) \
SimRoboRioData->NAME.RegisterCallback(callback, param, initialNotify)
diff --git a/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h b/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h
index 99e61ea..c3ff17a 100644
--- a/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h
+++ b/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h
@@ -4,6 +4,11 @@
#pragma once
+#include <cstddef>
+#include <string>
+
+#include <wpi/spinlock.h>
+
#include "hal/simulation/RoboRioData.h"
#include "hal/simulation/SimDataValue.h"
@@ -26,6 +31,9 @@
HAL_SIMDATAVALUE_DEFINE_NAME(UserFaults3V3)
HAL_SIMDATAVALUE_DEFINE_NAME(BrownoutVoltage)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(SerialNumber)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(Comments);
+
public:
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetFPGAButtonName> fpgaButton{false};
SimDataValue<double, HAL_MakeDouble, GetVInVoltageName> vInVoltage{12.0};
@@ -50,7 +58,32 @@
SimDataValue<double, HAL_MakeDouble, GetBrownoutVoltageName> brownoutVoltage{
6.75};
+ int32_t RegisterSerialNumberCallback(HAL_RoboRioStringCallback callback,
+ void* param, HAL_Bool initialNotify);
+ void CancelSerialNumberCallback(int32_t uid);
+ size_t GetSerialNumber(char* buffer, size_t size);
+ void SetSerialNumber(const char* serialNumber, size_t size);
+
+ int32_t RegisterCommentsCallback(HAL_RoboRioStringCallback callback,
+ void* param, HAL_Bool initialNotify);
+ void CancelCommentsCallback(int32_t uid);
+ size_t GetComments(char* buffer, size_t size);
+ void SetComments(const char* comments, size_t size);
+
virtual void ResetData();
+
+ private:
+ wpi::spinlock m_serialNumberMutex;
+ std::string m_serialNumber;
+
+ wpi::spinlock m_commentsMutex;
+ std::string m_comments;
+
+ SimCallbackRegistry<HAL_RoboRioStringCallback, GetSerialNumberName>
+ m_serialNumberCallbacks;
+
+ SimCallbackRegistry<HAL_RoboRioStringCallback, GetCommentsName>
+ m_commentsCallbacks;
};
extern RoboRioData* SimRoboRioData;
} // namespace hal
diff --git a/hal/src/test/java/edu/wpi/first/hal/JNITest.java b/hal/src/test/java/edu/wpi/first/hal/JNITest.java
new file mode 100644
index 0000000..49e201d
--- /dev/null
+++ b/hal/src/test/java/edu/wpi/first/hal/JNITest.java
@@ -0,0 +1,15 @@
+// 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 edu.wpi.first.hal;
+
+import org.junit.jupiter.api.Test;
+
+public class JNITest {
+ @Test
+ void jniLinkTest() {
+ // Test to verify that the JNI test link works correctly.
+ HAL.initialize(500, 0);
+ }
+}
diff --git a/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp b/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp
index 4925e16..59658cb 100644
--- a/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp
+++ b/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp
@@ -61,6 +61,9 @@
HALSIM_SetJoystickPOVs(joystickUnderTest, &set_povs);
HALSIM_SetJoystickButtons(joystickUnderTest, &set_buttons);
+ HALSIM_NotifyDriverStationNewData();
+ HAL_RefreshDSData();
+
// Check the set values
HAL_GetJoystickAxes(joystickUnderTest, &axes);
HAL_GetJoystickPOVs(joystickUnderTest, &povs);
@@ -89,6 +92,9 @@
// Reset
HALSIM_ResetDriverStationData();
+ HALSIM_NotifyDriverStationNewData();
+ HAL_RefreshDSData();
+
for (int joystickNum = 0; joystickNum < 6; ++joystickNum) {
HAL_GetJoystickAxes(joystickNum, &axes);
HAL_GetJoystickPOVs(joystickNum, &povs);