Compare commits

...

110 Commits

Author SHA1 Message Date
Thad House
02336fc478 Makes FMS data never be a null string. (#900)
Fixes #895
2018-01-19 23:49:34 -08:00
Thad House
c00848c060 Fixes indexed classed handle resource (#899)
Nothing in WPILib uses it, so it was not tested
2018-01-19 22:31:59 -08:00
Dustin Spicuzza
738a1c015c PIDController: setContinuous should only check input range if continuous is true (#896) 2018-01-19 22:31:08 -08:00
Thad House
48ae6c954a Publishes match specific data and other FMS info to NT (#874)
This is so products like SB can present the current setup.
2018-01-18 23:17:28 -08:00
Thad House
07f70cf784 Fixes control data packet delay (#875)
Because of an expected change in 2018 that didn't happen, we had a race
condition causing a 1 packet delay on all DS values. This fixes that.
2018-01-18 21:54:33 -08:00
sciencewhiz
e4e1eab413 Fix cancel of inner commands in ConditionalCommands (#858) 2018-01-18 20:04:33 -08:00
Nic Hodlofski
0e8ff4663d SpeedControllerGroup: Call set() from pidWrite()
This means pidWrite() now takes m_isInverted into account.
Fixes #887.
2018-01-18 20:03:13 -08:00
HeroCC
54a0a7654a Link to replacements for RobotDrive in JavaDocs (#879)
In smart IDEs, this will allow users to easily view source for these two classes by linking to it
2018-01-11 22:17:33 -08:00
Rohit Vighne
59f938b584 Invert when getting motor speed in SpeedControllerGroup (#886) 2018-01-11 22:16:42 -08:00
sciencewhiz
5513888457 Fix PIDController with Continous and no Input Range set. (#883) 2018-01-11 21:06:25 -08:00
Peter Johnson
02b6615042 RobotController: Make getBatteryVoltage() static. (#869) 2018-01-04 23:12:13 -06:00
Tyler Veness
1f4822f332 Replaced Talon motor controller in DifferentialDrive class docs with Spark (#868) 2018-01-03 20:27:34 -06:00
Peter Johnson
bb38ef5642 DifferentialDrive: Invert right motor in LiveWindow. (#867) 2018-01-02 21:15:15 -06:00
PJ Reiniger
ca36d1dce6 Adding callbacks for notifying when the distance per pulse changes (#861) 2018-01-02 16:53:39 -06:00
Sam Carlberg
ee33296e1f SmartDashboard override .name entry in putData(String, Sendable) (#866)
Fixes #865
2018-01-02 16:39:16 -06:00
Tyler Veness
0ef9803363 Update copyright year to 2018 (#864)
Also fix a few files with incorrect line endings.
2018-01-02 11:20:21 -06:00
Tyler Veness
eedb8910c3 Removed extra newlines from beginning of Java classes (#859)
The content of this PR was generated by styleguide#111.
2018-01-02 11:17:46 -06:00
Sam Carlberg
8346caed9c Move subsystem command metadata to metadata key format (#863) 2018-01-01 17:05:03 -05:00
PJ Reiniger
55b6764d50 Fix bugs in simulation libraries (#853)
Some thing got broken in the past couple of weeks with updates to the
HAL.
2017-12-31 14:37:14 -06:00
Thad House
2c4faee667 Fixes -Og compile and strip binaries (#838) 2017-12-29 22:18:35 -06:00
Jaci R
8d1dee16be Add DriverStation NetworkTables HAL Extension (#829) 2017-12-29 21:55:31 -06:00
Jaci R
76b182600a Add Low Fidelity NetworkTables simulation extension (#823) 2017-12-29 21:54:18 -06:00
sciencewhiz
c647a801ad Add Encoder Index as a child (#857) 2017-12-29 21:48:39 -06:00
sciencewhiz
02131639bc Add Digilent DMC 60 Speed Controller (#855) 2017-12-28 21:42:19 -06:00
Noah Gleason
566e283694 Make setDefaultCommand public (#854) 2017-12-28 12:48:15 -06:00
Peter Johnson
40eb6dfc9b Fix SmartDashboard PutData to hook setters. (#851)
* Fix SmartDashboard PutData to hook setters.

Also update all PutData values in main periodic loop (same as LiveWindow).

* Improve SmartDashboard.putData() repeat call handling.
2017-12-26 18:18:02 -05:00
Dustin Spicuzza
a3e5378d14 SPI: Check for null (#850) 2017-12-25 22:03:22 -06:00
Thad House
691741cfcb Fixes non public static methods in RobotController. (#852) 2017-12-25 20:26:05 -06:00
Thad House
166d9e01bf Add PWMVictorSPX (#842) 2017-12-17 19:59:30 -08:00
Thad House
7eab4371f4 Adds TriState DIO functionality to the HAL (#835)
Adds a function to raw set the DIO direction. Also adds a C++ unsafe
function to enable fast setting of DIO direction.
2017-12-14 00:17:29 -08:00
Peter Johnson
de134a5c60 Add deprecated shims for LiveWindowSendable and NamedSendable. (#834)
This will help prevent old code from breaking (not all cases, but should help).
2017-12-13 23:45:12 -08:00
Peter Johnson
7f074563d0 Add support for automatic SPI transfer engine. (#836)
The SPI Accumulator functions have been moved from HAL to wpilib and rewritten
to use the automatic transfer engine.
2017-12-13 23:41:37 -08:00
Thad House
d3dd586362 Revert "Fixes SPI bad chip select (#818)" (#822)
This is no longer required for image 2018v16.

This reverts commit b42285fddd.
2017-12-12 11:31:20 -08:00
Thad House
9c85105591 Update to image 2018v16 (#833) 2017-12-12 11:03:53 -08:00
Peter Johnson
86ac70a125 Fix wpilibcIntegrationTests RobotController warnings. (#832) 2017-12-11 22:15:29 -08:00
Austin Shalit
3c3a448d47 Deprecate SampleRobot (#472)
Suggest TimedRobot as an alternative.

Remove -Werror from examples to avoid breaking build.
2017-12-11 22:06:01 -08:00
Thad House
8744511f1d Fixes some methods in RobotController not being static. (#831) 2017-12-11 11:48:54 -08:00
Thad House
7729dd972f Fixes JNI symbol check (#830)
setErrorData symbol was missing. However, its been deprecated at the
netcomm level for years, and wasn't exposed in wpilibj. And it would
have been crashing since forever, so safe to remove.
2017-12-11 11:48:39 -08:00
Thad House
8b7aa61091 Adds RobotController class (#828)
Unifies random functionality from other classes
Deprecates all old functions.
2017-12-10 21:52:49 -08:00
Peter Johnson
88a6b4ac38 PIDController::InitSendable(): Use double, not bool for double values. (#827) 2017-12-10 20:58:29 -08:00
Peter Johnson
217b1a2259 VisionRunner: Add stop() function to stop a runForever() loop. (#826)
This was previously possible in Java with Thread.interrupt(), but provide
the same function in both C++ and Java.

Fixes #444.
2017-12-10 20:58:14 -08:00
Thad House
d2e7a90f41 Removes statics from hal sim (#825)
Based off of #824, the equivelent in sim.
2017-12-10 19:38:53 -08:00
Thad House
8bd48d6c34 Switches HAL to manual instead of static initialization (#824)
Only athena.

Will fix a whole lot of init issues.
2017-12-10 18:02:07 -08:00
Thad House
1fa0adb091 Removes MSVC and GCC old version workarounds (#821) 2017-12-08 23:40:35 -08:00
Thad House
f615e68a43 Require GCC 5 for wpilib build (#820)
Will help in season with teams not upgrading their GCC. Will have a
better error message.
2017-12-08 22:48:01 -08:00
Thad House
aa4f0ef4f8 Start using the new FRC compiler define (#797)
Remove all definitions from the MockData headers when in simulation mode.
Add a constexpr IsReal and IsSimulation in RobotBase.
2017-12-08 22:47:21 -08:00
Thad House
b42285fddd Fixes SPI bad chip select (#818)
Temporary workaround for 2018v13 image.
2017-12-08 21:42:30 -08:00
Thad House
8106fbdbea Removes custom CONFIG_ATHENA compiler directive (#796)
In roborio GCC 5.5, __FRC_ROBORIO__ has been added directly to the
compiler. So we can instead use that to detect if we are build for the
roborio, and in a much more reliable way.
2017-12-08 21:40:11 -08:00
Tyler Veness
942ba51765 Reclassified NetworkTables headers as "other library" (#775) 2017-12-07 23:34:29 -08:00
PJ Reiniger
33a08d5b34 Add halsim unit tests (#783)
Also adds function that can register all the callbacks at once.
Since all of the callbacks issue a string identifier, it makes it
possible and easy to have one function callback, and differentiate the
path to take based on the string.  Hooking up all the callbacks at once
makes it easier for the simulator developer to know when something was
added to wpilib rather than looking at the commits.
2017-12-07 22:42:20 -08:00
Thad House
4e3af0756d Removes workarounds for issues in image 10 (#816) 2017-12-06 21:20:03 -08:00
Thad House
5078f6c92a Update to image 2018v13 (#815) 2017-12-06 21:02:36 -08:00
Peter Johnson
899892c119 Change Utility to use Twine. 2017-12-05 00:17:56 -08:00
Peter Johnson
54326311ad Use Twine in error checks. 2017-12-05 00:17:56 -08:00
Peter Johnson
fe53dd2f28 Use Twine for error message inputs. 2017-12-05 00:17:56 -08:00
Peter Johnson
ab137abab5 Use llvm::Twine across C++ Command structure. 2017-12-05 00:17:56 -08:00
Peter Johnson
001dedf3b2 SmartDashboard: Use magic static for static initialization. (#812)
It's possible for SmartDashboard functions to be called from static
initializers in user code, so use a magic static to force initialization
order.
2017-12-04 23:50:27 -08:00
Peter Johnson
f9bece2ffb Update LiveWindow to provide continuous telemetry. (#771)
LiveWindow.updateValues() is now called from IterativeRobotBase on every
loop iteration.  Telemetry for all WPILib classes is enabled by default;
it can be disabled for specific classes using LiveWindow.disableTelemetry(),
or all telemetry can be disabled using LiveWindow.disableAllTelemetry().

This necessitated changing the hook methodology into other classes to
be more property-based rather than each class providing multiple functions.
This had the benefit of reducing boilerplate and increasing consistency.

- Remove NamedSendable, add name to Sendable.

- Provide SendableBase abstract class.

- Deprecate LiveWindow addSensor/addActuator interfaces.

- Add LiveWindow support to drive classes.

- Add addChild() helper functions to Subsystem.

- Fix inheritance hierarchy.  Now only sensors inherit from SensorBase.
  Other devices inherit from some combination of SendableBase, ErrorBase, or
  nothing.
2017-12-04 23:28:33 -08:00
Tyler Veness
3befc7015b Make MotorEncoderTest use LinearDigitalFilter's reference overload (#811) 2017-12-04 22:37:06 -08:00
Tyler Veness
de63e1c8a1 Fixed race condition between PIDController enable/disable and PIDWrite() call
To make this work in PIDController.java, the use of synchronized had to be
replaced with ReentrantLock and try-catch blocks. The locking in
PIDController.java was made equivalent to PIDController.cpp and some existing
race conditions in PIDController.java were fixed in the process.

Fixes #30.
2017-12-04 20:42:33 -08:00
Tyler Veness
a76b1aa800 Reduced scope of PIDController's critical sections
m_pidInput and m_pidOutput are considered constant after their construction.
Setting the input range, output range, tolerance, or continuous mode locks the
controller. m_error and m_result are held in temp variables and set at the end
of the calculation.

Getters of P, I, D, F, m_error, m_setpoint, m_result, and m_enabled lock the
critical section. P, I, D, F, and m_setpoint are retrieved at the beginning of
Calculate().

Fixes #40.
2017-12-04 20:42:33 -08:00
Tyler Veness
350b741adc Cleaned up SampleRobot template and added warning about disabling motor safety (#766) 2017-12-04 20:28:31 -08:00
Thad House
64bfdc1a69 Bail out of the integration tests if enable fails (#792)
A failure is much better then an infinite loop.
2017-12-04 20:24:26 -08:00
Tyler Veness
65cc85f68d Add reference constructors/factory methods to LinearDigitalFilter (#810)
Composition is less verbose with references than with smart pointers.
2017-12-04 20:12:06 -08:00
sciencewhiz
6a00dc7976 Re-Add PacGoat java example (#802) 2017-12-04 20:09:02 -08:00
Tyler Veness
e9e407a87d Replace C identifier lists with (void) (#809)
These changes were generated by wpilibsuite/styleguide#106.
2017-12-04 20:05:51 -08:00
Tyler Veness
59c4984ed6 Deprecated internal filter of PID controller (#746)
This was replaced with an external LinearDigitalFilter.
2017-12-04 20:05:02 -08:00
Peter Johnson
b428d1e4b3 Remove CANSpeedController interface. (#806)
CANJaguar is no longer supported, and CANTalon no longer uses this interface.
2017-12-04 20:03:07 -08:00
Thad House
0994364591 Fixes cross module base class statics (#779) 2017-12-03 00:05:05 -08:00
sciencewhiz
0b8d3f0260 Update SampleRobot template to match comments (#768) 2017-12-02 23:28:52 -08:00
sciencewhiz
52eba45c51 Add missing documentation for squaredInputs for RobotDrive (#805) 2017-12-02 22:31:51 -08:00
Thad House
9090a82ef5 Fixes halsim sources and headers zips (#804) 2017-12-02 22:30:54 -08:00
Peter Johnson
2a69a4c7dc Revert #780 (don't kill FRC_NetCommDaemon). (#795)
This commit reverts commit 0f3f5218ad.
2017-12-01 23:47:01 -08:00
Thad House
9d2393f97e Waits 10 seconds between running the C++ and Java test (#798)
Potentially will fix java tests not enabling.
2017-12-01 23:45:49 -08:00
Peter Johnson
dae619b006 Add error reporting to AbstractComsSetup test initialization. (#800) 2017-12-01 23:44:11 -08:00
Thad House
9c06d2878b Update to latest native plugin (#799)
This is what prints warnings to console.
2017-12-01 16:23:30 -08:00
Peter Johnson
e3a2abdf97 HAL_SetDigitalPWMRate(): Use same logic as LabView. (#794) 2017-12-01 10:26:40 -08:00
Peter Johnson
7867e906e9 NidecBrushless: Have disable() call PWM.setDisabled(). (#763)
This provides a way to stop motor operation even if the DIO is disconnected.

Also change Set() to enable the PWM instead of having the constructor do it.

Provide an explicit Enable() call to re-enable after Disable() is called.
This is different from the other motor controllers (which automatically
re-enable when Set() is called) due to the dual-wiring of this motor
controller.

Motor safety results in disabling the motor only until the next Set() call.
2017-12-01 00:43:11 -08:00
Peter Johnson
65a044f633 Fix HAL_CleanNotifier race. (#793)
This race was caused by holding a lock while calling into FRC_ChipObject,
which was waiting for the callback to exit before returning, and our
callback wanted to grab the same lock.
2017-11-30 20:45:40 -08:00
sciencewhiz
cbd08a1e11 Add tests for equivilance of RobotDrive and DifferentialDrive/MecanumDrive (#732)
Add documentation for how to get same results as RobotDrive and improve
RobotDrive documentation
2017-11-29 21:41:00 -08:00
sciencewhiz
e308dd28f3 Fix javadoc link in Solenoid.java (#789) 2017-11-29 21:33:29 -08:00
Thad House
fa0b4428e9 Runs DS enabled loop in process (#785)
Solves mutex issues, and other issues with the existing teststand
software. And simplifies the unit test structure.
2017-11-28 19:12:05 -08:00
Tyler Veness
26a36779a6 Performed cleanup of Timer's free functions (#776)
* GetClock() is now officially deprecated since its comment already informally
  did so and the function just forwards to Timer::GetFPGATimestamp().
* The declaration of GetPPCTimestamp() is missing a definition and has been
  removed.
* std::this_thread::sleep_for() returns immediately when given a negative
  duration, so the check for that was removed from Wait().
2017-11-27 21:59:00 -08:00
Tyler Veness
dfc0656e5c Fix wpilibj FilterOutputTest null pointer exception (#778) 2017-11-27 12:28:25 -08:00
Peter Johnson
0f3f5218ad Kill FRC_NetCommDaemon as well as robot programs. (#780)
Also use flock on Jenkins side to prevent multiple simultaneous runs, instead of using teststand mutex.
2017-11-27 12:24:46 -08:00
Tyler Veness
34c44b7ae9 Improved Drive docs and fix implementation bugs (#774)
I also found some inconsistencies in MecanumDrive and KilloughDrive and fixed
them.

Drive now uses the NED axes convention. Therefore, the positive X axis points
ahead, the positive Y axis points to the right, and the positive Z axis points
down.

Translation in X assumes forward is positive. Translation in Y assumes right is
positive. Rotation rate assumes clockwise is positive. Angles are measured
clockwise from the positive X axis.

Based on the angle origin convention, DrivePolar() for both Mecanum and Killough
needed the normalization removed, sine used to compute the Y component, and
cosine used to compute the X component.

The vector rotation done in DriveCartesian() needs to rotate by a negative angle
instead of positive to undo the robot's rotation. RobotDrive assumed a clockwise
angle and sensors returned counter-clockwise angles, which is why it used a
positive angle for rotation.
2017-11-26 18:36:51 -08:00
sciencewhiz
7a250a1b93 Implement PCM One Shot feature. Fixes artf4731 (#539) 2017-11-26 12:55:21 -08:00
Caleb Smith
a338ee8be0 Add PIDController Wrapping (#601) 2017-11-25 21:15:33 -08:00
sciencewhiz
c9d440f338 Fix Java Compressor test. Make limits same as C++. (#772) 2017-11-24 20:14:36 -08:00
Tyler Veness
a00b2449db Removed unused includes and replaced Ultrasonic's std::set with std::vector (#767) 2017-11-23 20:46:24 -08:00
Tyler Veness
5c659fdcdf Deprecated PIDController::SetTolerance() (#764)
PIDController::SetPercentTolerance() behaves identically to it, so removing
SetTolerance() leaves one obvious way to do absolute or percent tolerance.
2017-11-23 01:21:36 -08:00
Thad House
d36d72bd4f Fixes MotorSafetyHelper locking and race conditions (#762)
Closes #760
2017-11-23 00:36:57 -08:00
sciencewhiz
614093c0c4 Fix documentation for getMatchTime in Timer class to match DriverStation (#761) 2017-11-23 00:19:05 -08:00
PJ Reiniger
12c4418bda Added callbacks for CAN (#757)
Added callback scheme for a pass through to something higher
level.  Since the ID is embedded into the arbitration ID, and some
devices can use different schemes whether it is plugged in through a
device or put into the daisy chain (pigeonImu), I made one "internal
data object" for max reusability.
2017-11-22 19:48:32 -08:00
Caleb Smith
0431cf97ff Cleanup PIDController (#597) 2017-11-22 18:56:35 -08:00
Tyler Veness
ba879f4663 Cleaned up variable names for std::lock_guard and their associated mutexes (#759) 2017-11-22 17:10:21 -08:00
Tyler Veness
96de0b5b11 Variable name fixes (#758) 2017-11-22 17:06:57 -08:00
Tyler Veness
85157a56c3 CircularBuffer now uses an idiomatic interface in C++ and Java (#421) 2017-11-22 17:04:57 -08:00
Tyler Veness
029246ed28 Replaced extra constructors in LinearDigitalFilter with llvm::ArrayRef<> (#755)
llvm::ArrayRef<> replaces both the std::initializer_list<> and std::vector<>
constructor overloads.
2017-11-20 21:23:00 -08:00
sciencewhiz
6377ab774d Allow deprecated warnings for tests (#756) 2017-11-20 21:21:50 -08:00
Tyler Veness
05e581f409 Fixed crash in wpilibj SampleRobot (#753)
robotInit() and HAL.observeUserProgramStarting() should be called in
startCompetition() rather than the constructor.

Fixes #752.
2017-11-19 22:47:39 -08:00
Peter Johnson
c73dd807e1 ErrorBase: Remove last use of sstream and iostream. (#750) 2017-11-19 20:16:42 -08:00
Tyler Veness
7a0dd9baa9 Add return-to-zero test for LinearDigitalFilter moving average (#751)
Ensures LinearDigitalFilter moving average returns to zero after non-zero
values are inserted.

Tests for issue #642
2017-11-19 20:16:09 -08:00
Tyler Veness
11f37683c3 Added constructor to PIDController that takes references instead of pointers (#745) 2017-11-19 19:06:00 -08:00
Tyler Veness
5af0c9c101 Replaced const variables with constexpr (#731) 2017-11-19 19:04:28 -08:00
Tyler Veness
259461aee9 Added PIDController::GetAvgError() back in (#749)
It got removed during the LinearDigitalFilter change (#38) instead of deprecated
by mistake.
2017-11-19 18:23:48 -08:00
Peter Johnson
d214b36786 Change HAL notifier to polling. (#627)
This moves the thread code to the WPILib layer, fixing various potential
races and significantly simplifying the HAL implementation.
2017-11-19 17:58:40 -08:00
Tyler Veness
4a07f0380f PIDController class now uses LinearDigitalFilter for filtering velocity instead of internal queue (#38) 2017-11-19 15:58:30 -08:00
Peter Johnson
7f46b50b21 Unify WPI_Now and HAL_GetFPGATime. (#743)
Depends on wpilibsuite/wpiutil#56.
2017-11-19 12:33:36 -08:00
PJ Reiniger
303c259b89 Simulate ADX* family of accelerometers and gyros (#688) 2017-11-18 12:31:51 -08:00
1004 changed files with 17935 additions and 8485 deletions

View File

@@ -31,6 +31,7 @@ modifiableFileExclude {
includeOtherLibs {
^HAL/
^llvm/
^networktables/
^opencv2/
^support/
}

View File

@@ -35,6 +35,6 @@ cache:
- $HOME/.gradle/wrapper/
script:
- python3.5 -m wpiformat -y 2017 -clang 5.0
- python3.5 -m wpiformat -y 2018 -clang 5.0
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
- ./gradlew --no-daemon --console=plain -PskipAthena :hal:halSimSharedLibrary :wpilibc:wpilibcSharedLibrary :wpilibj:wpilibJNISharedSharedLibrary :wpilibj:jar

View File

@@ -9,7 +9,7 @@ buildscript {
}
}
dependencies {
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.3.0'
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.5.1'
}
}

View File

@@ -1,21 +1,21 @@
import edu.wpi.first.nativeutils.*
import org.gradle.internal.os.OperatingSystem
def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS',
'/Zi', '/FS', '/Zc:inline', '/MT']
def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/Zi', '/FS', '/Zc:inline', '/MT']
def windowsReleaseCompilerArgs = ['/O2']
def windowsLinkerArgs = [ '/DEBUG:FULL' ]
def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ]
def linuxCompilerArgs = ['-std=c++1y', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g',
'-Wno-unused-parameter', '-fPIC', '-rdynamic', '-pthread']
def linuxCompilerArgs = ['-std=c++11', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g',
'-Wno-unused-parameter', '-fPIC', '-rdynamic', '-Wno-error=deprecated-declarations', '-pthread']
def linuxLinkerArgs = ['-rdynamic', '-pthread']
def linuxReleaseCompilerArgs = ['-O2']
def linuxReleaseCompilerArgs = ['-Og']
def linuxDebugCompilerArgs = ['-O0']
def linux32BitArg = '-m32'
def macCompilerArgs = ['-std=c++11', '-Wall', '-Wextra', '-Werror', '-pedantic-errors', '-fPIC', '-g',
'-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field', '-Wno-unused-const-variable', '-pthread']
'-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field',
'-Wno-unused-const-variable', '-pthread']
def macReleaseCompilerArgs = ['-O2']
def macDebugCompilerArgs = ['-O0']
def mac32BitArg = '-m32'
@@ -147,6 +147,7 @@ if (!project.hasProperty('onlyAthena')) {
linkerArgs << linux32BitArg
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
detectPlatform = linux32IntelPlatformDetect
exclude << 'halAthena'
@@ -159,6 +160,7 @@ if (!project.hasProperty('onlyAthena')) {
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
detectPlatform = linux64IntelPlatformDetect
exclude << 'halAthena'
@@ -173,6 +175,7 @@ if (!project.hasProperty('onlyAthena')) {
linkerArgs << mac32BitArg
debugCompilerArgs = macDebugCompilerArgs
releaseCompilerArgs = macReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Clang'
detectPlatform = mac32PlatformDetect
exclude << 'halAthena'
@@ -184,56 +187,45 @@ if (!project.hasProperty('onlyAthena')) {
compilerArgs = macCompilerArgs
debugCompilerArgs = macDebugCompilerArgs
releaseCompilerArgs = macReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Clang'
detectPlatform = mac64PlatformDetect
exclude << 'halAthena'
}
raspbian(CrossBuildConfig) {
architecture = 'raspbian'
}
}
}
if (project.hasProperty('linuxCross')) {
model {
buildConfigs {
linuxArm(CrossBuildConfig) {
architecture = 'nativearm'
operatingSystem = 'linux'
toolChainPrefix = 'arm-linux-gnueabihf-'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
skipByDefault = true
compilerFamily = 'Gcc'
exclude << 'gmock'
exclude << 'halAthena'
}
armhf(CrossBuildConfig) {
architecture = 'armhf'
operatingSystem = 'linux'
toolChainPrefix = 'arm-linux-gnueabihf-'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
skipByDefault = true
compilerFamily = 'Gcc'
exclude << 'gmock'
exclude << 'halAthena'
}
aarch(CrossBuildConfig) {
architecture = 'aarch'
operatingSystem = 'linux'
toolChainPrefix = 'aarch-linux-gnu-'
toolChainPrefix = 'PLEASE_PROVIDE_A_COMPILER_NAME'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
skipByDefault = true
compilerFamily = 'Gcc'
exclude << 'gmock'
exclude << 'halAthena'
}
}
}
} else {
model {
buildConfigs {
linuxArm(BuildConfig) {
architecture = 'arm'
architecture = 'nativearm'
operatingSystem = 'linux'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
detectPlatform = linuxArmPlatformDetect
exclude << 'halAthena'

View File

@@ -5,17 +5,6 @@ apply plugin: 'edu.wpi.first.NativeUtils'
apply from: '../config.gradle'
ext.addHalCompilerArguments = { binary->
if (binary.targetPlatform.architecture.name == 'athena') {
tasks.withType(CppCompile) {
binary.cppCompiler.args "-DCONFIG_ATHENA"
}
}
tasks.withType(CppCompile) {
binary.cppCompiler.args "-DNAMESPACED_PRIORITY"
}
}
ext.addHalToLinker = { binary->
if (binary.targetPlatform.architecture.name == 'athena') {
binary.lib project: ':hal', library: 'halAthena', linkage: 'shared'
@@ -172,7 +161,6 @@ model {
}
binaries {
all {
project.addHalCompilerArguments(it)
project(':ni-libraries').addNiLibrariesToLinker(it)
}
withType(GoogleTestTestSuiteBinarySpec) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -19,14 +19,14 @@
using namespace hal;
// The 7-bit I2C address with a 0 "send" bit
static const uint8_t kSendAddress = (0x1c << 1) | 0;
static constexpr uint8_t kSendAddress = (0x1c << 1) | 0;
// The 7-bit I2C address with a 1 "receive" bit
static const uint8_t kReceiveAddress = (0x1c << 1) | 1;
static constexpr uint8_t kReceiveAddress = (0x1c << 1) | 1;
static const uint8_t kControlTxRx = 1;
static const uint8_t kControlStart = 2;
static const uint8_t kControlStop = 4;
static constexpr uint8_t kControlTxRx = 1;
static constexpr uint8_t kControlStart = 2;
static constexpr uint8_t kControlStop = 4;
static std::unique_ptr<tAccel> accel;
static HAL_AccelerometerRange accelerometerRange;
@@ -77,6 +77,12 @@ enum Register {
kReg_OffZ = 0x31
};
namespace hal {
namespace init {
void InitializeAccelerometer() {}
} // namespace init
} // namespace hal
namespace hal {
static void writeRegister(Register reg, uint8_t data);
@@ -91,6 +97,8 @@ static void initializeAccelerometer() {
if (!accel) {
accel.reset(tAccel::create(&status));
accelerometerRange = HAL_AccelerometerRange::HAL_AccelerometerRange_k2G;
// Enable I2C
accel->writeCNFG(1, &status);
@@ -219,7 +227,7 @@ void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerX() {
double HAL_GetAccelerometerX(void) {
initializeAccelerometer();
int32_t raw =
@@ -232,7 +240,7 @@ double HAL_GetAccelerometerX() {
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerY() {
double HAL_GetAccelerometerY(void) {
initializeAccelerometer();
int32_t raw =
@@ -245,7 +253,7 @@ double HAL_GetAccelerometerY() {
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerZ() {
double HAL_GetAccelerometerZ(void) {
initializeAccelerometer();
int32_t raw =

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -12,6 +12,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeAnalogAccumulator() {}
} // namespace init
} // namespace hal
extern "C" {
/**
@@ -22,7 +28,7 @@ extern "C" {
*/
HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -55,7 +61,7 @@ void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
*/
void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -84,7 +90,7 @@ void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
*/
void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
int32_t center, int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -104,7 +110,7 @@ void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
*/
void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
int32_t deadband, int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -127,7 +133,7 @@ void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
*/
int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -151,7 +157,7 @@ int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
*/
int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -175,7 +181,7 @@ int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
*/
void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
int64_t* value, int64_t* count, int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -34,8 +34,18 @@ static constexpr double kDefaultVoltsPerDegreePerSecond = 0.007;
using namespace hal;
static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
HAL_HandleEnum::AnalogGyro>
analogGyroHandles;
HAL_HandleEnum::AnalogGyro>* analogGyroHandles;
namespace hal {
namespace init {
void InitializeAnalogGyro() {
static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
HAL_HandleEnum::AnalogGyro>
agHandles;
analogGyroHandles = &agHandles;
}
} // namespace init
} // namespace hal
static void Wait(double seconds) {
if (seconds < 0.0) return;
@@ -56,13 +66,13 @@ HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
// handle known to be correct, so no need to type check
int16_t channel = getHandleIndex(analogHandle);
auto handle = analogGyroHandles.Allocate(channel, status);
auto handle = analogGyroHandles->Allocate(channel, status);
if (*status != 0)
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
// Initialize port structure
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) { // would only error on thread issue
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -77,7 +87,7 @@ HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
}
void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -100,13 +110,13 @@ void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
}
void HAL_FreeAnalogGyro(HAL_GyroHandle handle) {
analogGyroHandles.Free(handle);
analogGyroHandles->Free(handle);
}
void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
double voltsPerDegreePerSecond, double offset,
int32_t center, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -121,7 +131,7 @@ void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
double voltsPerDegreePerSecond,
int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -131,7 +141,7 @@ void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
}
void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -149,7 +159,7 @@ void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
}
void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -176,7 +186,7 @@ void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -189,7 +199,7 @@ void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
}
double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -211,7 +221,7 @@ double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
}
double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -225,7 +235,7 @@ double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
}
double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -234,7 +244,7 @@ double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
}
int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status) {
auto gyro = analogGyroHandles.Get(handle);
auto gyro = analogGyroHandles->Get(handle);
if (gyro == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -16,6 +16,12 @@
#include "HAL/handles/HandlesInternal.h"
#include "PortsInternal.h"
namespace hal {
namespace init {
void InitializeAnalogInput() {}
} // namespace init
} // namespace hal
using namespace hal;
extern "C" {
@@ -37,13 +43,13 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
return HAL_kInvalidHandle;
}
HAL_AnalogInputHandle handle = analogInputHandles.Allocate(channel, status);
HAL_AnalogInputHandle handle = analogInputHandles->Allocate(channel, status);
if (*status != 0)
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
// Initialize port structure
auto analog_port = analogInputHandles.Get(handle);
auto analog_port = analogInputHandles->Get(handle);
if (analog_port == nullptr) { // would only error on thread issue
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -67,7 +73,7 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
*/
void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
// no status, so no need to check for a proper free.
analogInputHandles.Free(analogPortHandle);
analogInputHandles->Free(analogPortHandle);
}
/**
@@ -135,7 +141,7 @@ double HAL_GetAnalogSampleRate(int32_t* status) {
*/
void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
int32_t bits, int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -155,7 +161,7 @@ void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
*/
int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return kDefaultAverageBits;
@@ -177,7 +183,7 @@ int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
*/
void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
int32_t bits, int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -198,7 +204,7 @@ void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
*/
int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return kDefaultOversampleBits;
@@ -219,7 +225,7 @@ int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
*/
int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -229,7 +235,7 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
readSelect.Channel = port->channel;
readSelect.Averaged = false;
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
return static_cast<int16_t>(analogInputSystem->readOutput(status));
@@ -251,7 +257,7 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
*/
int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -260,7 +266,7 @@ int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
readSelect.Channel = port->channel;
readSelect.Averaged = true;
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
return static_cast<int32_t>(analogInputSystem->readOutput(status));
@@ -351,7 +357,7 @@ int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
*/
int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -373,7 +379,7 @@ int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
*/
int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -21,8 +21,8 @@ wpi::mutex analogRegisterWindowMutex;
std::unique_ptr<tAI> analogInputSystem;
std::unique_ptr<tAO> analogOutputSystem;
IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort, kNumAnalogInputs,
HAL_HandleEnum::AnalogInput>
IndexedHandleResource<HAL_AnalogInputHandle, ::hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
analogInputHandles;
static int32_t analogNumChannelsToActivate = 0;
@@ -31,12 +31,21 @@ static std::atomic<bool> analogSystemInitialized{false};
bool analogSampleRateSet = false;
namespace init {
void InitializeAnalogInternal() {
static IndexedHandleResource<HAL_AnalogInputHandle, ::hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
alH;
analogInputHandles = &alH;
}
} // namespace init
/**
* Initialize the analog System.
*/
void initializeAnalog(int32_t* status) {
if (analogSystemInitialized) return;
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
if (analogSystemInitialized) return;
analogInputSystem.reset(tAI::create(status));
analogOutputSystem.reset(tAO::create(status));

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -24,7 +24,7 @@ constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock
constexpr int32_t kDefaultOversampleBits = 0;
constexpr int32_t kDefaultAverageBits = 7;
constexpr double kDefaultSampleRate = 50000.0;
static const uint32_t kAccumulatorChannels[] = {0, 1};
static constexpr uint32_t kAccumulatorChannels[] = {0, 1};
extern std::unique_ptr<tAI> analogInputSystem;
extern std::unique_ptr<tAO> analogOutputSystem;
@@ -37,7 +37,7 @@ struct AnalogPort {
};
extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
analogInputHandles;
int32_t getAnalogNumActiveChannels(int32_t* status);

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -24,9 +24,20 @@ struct AnalogOutput {
} // namespace
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>*
analogOutputHandles;
namespace hal {
namespace init {
void InitializeAnalogOutput() {
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
aoH;
analogOutputHandles = &aoH;
}
} // namespace init
} // namespace hal
extern "C" {
/**
@@ -44,12 +55,13 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
return HAL_kInvalidHandle;
}
HAL_AnalogOutputHandle handle = analogOutputHandles.Allocate(channel, status);
HAL_AnalogOutputHandle handle =
analogOutputHandles->Allocate(channel, status);
if (*status != 0)
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
auto port = analogOutputHandles.Get(handle);
auto port = analogOutputHandles->Get(handle);
if (port == nullptr) { // would only error on thread issue
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -61,7 +73,7 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
// no status, so no need to check for a proper free.
analogOutputHandles.Free(analogOutputHandle);
analogOutputHandles->Free(analogOutputHandle);
}
/**
@@ -77,7 +89,7 @@ HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
double voltage, int32_t* status) {
auto port = analogOutputHandles.Get(analogOutputHandle);
auto port = analogOutputHandles->Get(analogOutputHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -95,7 +107,7 @@ void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
int32_t* status) {
auto port = analogOutputHandles.Get(analogOutputHandle);
auto port = analogOutputHandles->Get(analogOutputHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0.0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -27,25 +27,37 @@ struct AnalogTrigger {
} // namespace
static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>
kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>*
analogTriggerHandles;
namespace hal {
namespace init {
void InitializeAnalogTrigger() {
static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
kNumAnalogTriggers,
HAL_HandleEnum::AnalogTrigger>
atH;
analogTriggerHandles = &atH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
HAL_AnalogInputHandle portHandle, int32_t* index, int32_t* status) {
// ensure we are given a valid and active AnalogInput handle
auto analog_port = analogInputHandles.Get(portHandle);
auto analog_port = analogInputHandles->Get(portHandle);
if (analog_port == nullptr) {
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
}
HAL_AnalogTriggerHandle handle = analogTriggerHandles.Allocate();
HAL_AnalogTriggerHandle handle = analogTriggerHandles->Allocate();
if (handle == HAL_kInvalidHandle) {
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto trigger = analogTriggerHandles.Get(handle);
auto trigger = analogTriggerHandles->Get(handle);
if (trigger == nullptr) { // would only occur on thread issue
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -61,14 +73,14 @@ HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
int32_t* status) {
analogTriggerHandles.Free(analogTriggerHandle);
analogTriggerHandles->Free(analogTriggerHandle);
// caller owns the analog input handle.
}
void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
int32_t lower, int32_t upper,
int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -87,7 +99,7 @@ void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
void HAL_SetAnalogTriggerLimitsVoltage(
HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -111,7 +123,7 @@ void HAL_SetAnalogTriggerLimitsVoltage(
*/
void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_Bool useAveragedValue, int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -132,7 +144,7 @@ void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
*/
void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_Bool useFilteredValue, int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -152,7 +164,7 @@ void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
*/
HAL_Bool HAL_GetAnalogTriggerInWindow(
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -169,7 +181,7 @@ HAL_Bool HAL_GetAnalogTriggerInWindow(
*/
HAL_Bool HAL_GetAnalogTriggerTriggerState(
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -184,7 +196,7 @@ HAL_Bool HAL_GetAnalogTriggerTriggerState(
HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_AnalogTriggerType type,
int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -9,6 +9,12 @@
#include <FRC_NetworkCommunication/CANSessionMux.h>
namespace hal {
namespace init {
void InitializeCAN() {}
} // namespace init
} // namespace hal
extern "C" {
void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -15,6 +15,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeCompressor() {}
} // namespace init
} // namespace hal
extern "C" {
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -11,6 +11,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeConstants() {}
} // namespace init
} // namespace hal
extern "C" {
int32_t HAL_GetSystemClockTicksPerMicrosecond(void) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -25,19 +25,29 @@ struct Counter {
} // namespace
static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
HAL_HandleEnum::Counter>
counterHandles;
HAL_HandleEnum::Counter>* counterHandles;
namespace hal {
namespace init {
void InitializeCounter() {
static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
HAL_HandleEnum::Counter>
ch;
counterHandles = &ch;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
int32_t* status) {
auto handle = counterHandles.Allocate();
auto handle = counterHandles->Allocate();
if (handle == HAL_kInvalidHandle) { // out of resources
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto counter = counterHandles.Get(handle);
auto counter = counterHandles->Get(handle);
if (counter == nullptr) { // would only occur on thread issues
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -52,12 +62,12 @@ HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
}
void HAL_FreeCounter(HAL_CounterHandle counterHandle, int32_t* status) {
counterHandles.Free(counterHandle);
counterHandles->Free(counterHandle);
}
void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -73,7 +83,7 @@ void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -110,7 +120,7 @@ void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -124,7 +134,7 @@ void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
*/
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -144,7 +154,7 @@ void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -184,7 +194,7 @@ void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -198,7 +208,7 @@ void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
*/
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -216,7 +226,7 @@ void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
*/
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -231,7 +241,7 @@ void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
*/
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -245,7 +255,7 @@ void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
*/
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_Bool highSemiPeriod, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -264,7 +274,7 @@ void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
*/
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
double threshold, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -285,7 +295,7 @@ void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
*/
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -301,7 +311,7 @@ int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
*/
void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t samplesToAverage, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -318,7 +328,7 @@ void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
* counter, just sets the current value to zero.
*/
void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -332,7 +342,7 @@ void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
* current value. Next time it is read, it might have a different value.
*/
int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -348,7 +358,7 @@ int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
* @returns The period of the last two pulses in units of seconds.
*/
double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0.0;
@@ -379,7 +389,7 @@ double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
*/
void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -403,7 +413,7 @@ void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
*/
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
HAL_Bool enabled, int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -421,7 +431,7 @@ void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
*/
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -435,7 +445,7 @@ HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
*/
HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -453,7 +463,7 @@ HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection,
int32_t* status) {
auto counter = counterHandles.Get(counterHandle);
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
*status = HAL_HANDLE_ERROR;
return;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -16,13 +16,25 @@
using namespace hal;
// Create a mutex to protect changes to the digital output values
static wpi::mutex digitalDIOMutex;
// Create a mutex to protect changes to the DO PWM config
static wpi::mutex digitalPwmMutex;
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>*
digitalPWMHandles;
namespace hal {
namespace init {
void InitializeDIO() {
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
kNumDigitalPWMOutputs,
HAL_HandleEnum::DigitalPWM>
dpH;
digitalPWMHandles = &dpH;
}
} // namespace init
} // namespace hal
extern "C" {
/**
@@ -41,12 +53,12 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
}
auto handle =
digitalChannelHandles.Allocate(channel, HAL_HandleEnum::DIO, status);
digitalChannelHandles->Allocate(channel, HAL_HandleEnum::DIO, status);
if (*status != 0)
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
auto port = digitalChannelHandles.Get(handle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
if (port == nullptr) { // would only occur on thread issue.
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -54,7 +66,7 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
port->channel = static_cast<uint8_t>(channel);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
tDIO::tOutputEnable outputEnable = digitalSystem->readOutputEnable(status);
@@ -110,12 +122,12 @@ HAL_Bool HAL_CheckDIOChannel(int32_t channel) {
}
void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
// no status, so no need to check for a proper free.
digitalChannelHandles.Free(dioPortHandle, HAL_HandleEnum::DIO);
digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) return;
int32_t status = 0;
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
// Unset the SPI flag
int32_t bitToUnset = 1 << remapSPIChannel(port->channel);
@@ -139,13 +151,13 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
* @return PWM Generator handle
*/
HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
auto handle = digitalPWMHandles.Allocate();
auto handle = digitalPWMHandles->Allocate();
if (handle == HAL_kInvalidHandle) {
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto id = digitalPWMHandles.Get(handle);
auto id = digitalPWMHandles->Get(handle);
if (id == nullptr) { // would only occur on thread issue.
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -162,7 +174,7 @@ HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
* allocateDigitalPWM()
*/
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
digitalPWMHandles.Free(pwmGenerator);
digitalPWMHandles->Free(pwmGenerator);
}
/**
@@ -179,10 +191,8 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
// TODO: Round in the linear rate domain.
initializeDigital(status);
if (*status != 0) return;
uint8_t pwmPeriodPower = static_cast<uint8_t>(
std::log(1.0 / (pwmSystem->readLoopTiming(status) * 0.25E-6 * rate)) /
std::log(2.0) +
0.5);
uint16_t pwmPeriodPower = static_cast<uint16_t>(
std::log(1.0 / (16 * 1.0E-6 * rate)) / std::log(2.0) + 0.5);
digitalSystem->writePWMPeriodPower(pwmPeriodPower, status);
}
@@ -194,7 +204,7 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
*/
void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
double dutyCycle, int32_t* status) {
auto port = digitalPWMHandles.Get(pwmGenerator);
auto port = digitalPWMHandles->Get(pwmGenerator);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -205,7 +215,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
double rawDutyCycle = 256.0 * dutyCycle;
if (rawDutyCycle > 255.5) rawDutyCycle = 255.5;
{
std::lock_guard<wpi::mutex> sync(digitalPwmMutex);
std::lock_guard<wpi::mutex> lock(digitalPwmMutex);
uint16_t pwmPeriodPower = digitalSystem->readPWMPeriodPower(status);
if (pwmPeriodPower < 4) {
// The resolution of the duty cycle drops close to the highest
@@ -229,7 +239,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
*/
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status) {
auto port = digitalPWMHandles.Get(pwmGenerator);
auto port = digitalPWMHandles->Get(pwmGenerator);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -256,7 +266,7 @@ void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
*/
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -265,7 +275,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
if (value != 0) value = 1;
}
{
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
tDIO::tDO currentDIO = digitalSystem->readDO(status);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
@@ -295,6 +305,50 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
}
}
/**
* Set direction of a DIO channel.
*
* @param channel The Digital I/O channel
* @param input true to set input, false for output
*/
void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
{
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
tDIO::tOutputEnable currentDIO = digitalSystem->readOutputEnable(status);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
if (input) {
currentDIO.SPIPort =
currentDIO.SPIPort & ~(1u << remapSPIChannel(port->channel));
} else {
currentDIO.SPIPort =
currentDIO.SPIPort | (1u << remapSPIChannel(port->channel));
}
} else if (port->channel < kNumDigitalHeaders) {
if (input) {
currentDIO.Headers = currentDIO.Headers & ~(1u << port->channel);
} else {
currentDIO.Headers = currentDIO.Headers | (1u << port->channel);
}
} else {
if (input) {
currentDIO.MXP =
currentDIO.MXP & ~(1u << remapMXPChannel(port->channel));
} else {
currentDIO.MXP =
currentDIO.MXP | (1u << remapMXPChannel(port->channel));
}
}
digitalSystem->writeOutputEnable(currentDIO, status);
}
}
/**
* Read a digital I/O bit from the FPGA.
* Get a single value from a digital I/O channel.
@@ -303,7 +357,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
* @return The state of the specified channel
*/
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -331,7 +385,7 @@ HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
* @return The direction of the specified channel
*/
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -364,7 +418,7 @@ HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
*/
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -392,7 +446,7 @@ void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
* @return A pulse is in progress
*/
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -431,13 +485,13 @@ HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
*/
void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
// Channels 10-15 are SPI channels, so subtract our MXP channels
digitalSystem->writeFilterSelectHdr(port->channel - kNumDigitalMXPChannels,
@@ -459,13 +513,13 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
* where 0 means "none" and 1 - 3 means filter # filterIndex - 1.
*/
int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
// Channels 10-15 are SPI channels, so subtract our MXP channels
return digitalSystem->readFilterSelectHdr(
@@ -492,7 +546,7 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
initializeDigital(status);
if (*status != 0) return;
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
digitalSystem->writeFilterPeriodHdr(filterIndex, value, status);
if (*status == 0) {
digitalSystem->writeFilterPeriodMXP(filterIndex, value, status);
@@ -517,7 +571,7 @@ int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
uint32_t hdrPeriod = 0;
uint32_t mxpPeriod = 0;
{
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
hdrPeriod = digitalSystem->readFilterPeriodHdr(filterIndex, status);
if (*status == 0) {
mxpPeriod = digitalSystem->readFilterPeriodMXP(filterIndex, status);

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -18,35 +18,66 @@
#include "HAL/ChipObject.h"
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "HAL/cpp/UnsafeDIO.h"
#include "PortsInternal.h"
namespace hal {
// Create a mutex to protect changes to the DO PWM config
wpi::mutex digitalPwmMutex;
std::unique_ptr<tDIO> digitalSystem;
std::unique_ptr<tRelay> relaySystem;
std::unique_ptr<tPWM> pwmSystem;
std::unique_ptr<tSPI> spiSystem;
static std::atomic<bool> digitalSystemsInitialized{false};
static wpi::mutex initializeMutex;
// Create a mutex to protect changes to the digital output values
wpi::mutex digitalDIOMutex;
DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
kNumDigitalChannels + kNumPWMHeaders>*
digitalChannelHandles;
namespace init {
void InitializeDigitalInternal() {
static DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
dcH;
digitalChannelHandles = &dcH;
}
} // namespace init
namespace detail {
wpi::mutex& UnsafeGetDIOMutex() { return digitalDIOMutex; }
tDIO* UnsafeGetDigialSystem() { return digitalSystem.get(); }
int32_t ComputeDigitalMask(HAL_DigitalHandle handle, int32_t* status) {
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
tDIO::tDO output;
output.value = 0;
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
output.SPIPort = (1u << remapSPIChannel(port->channel));
} else if (port->channel < kNumDigitalHeaders) {
output.Headers = (1u << port->channel);
} else {
output.MXP = (1u << remapMXPChannel(port->channel));
}
return output.value;
}
} // namespace detail
/**
* Initialize the digital system.
*/
void initializeDigital(int32_t* status) {
static std::atomic_bool initialized{false};
static wpi::mutex initializeMutex;
// Initial check, as if it's true initialization has finished
if (digitalSystemsInitialized) return;
if (initialized) return;
std::lock_guard<wpi::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (digitalSystemsInitialized) return;
if (initialized) return;
digitalSystem.reset(tDIO::create(status));
@@ -99,7 +130,7 @@ void initializeDigital(int32_t* status) {
// SPI setup
spiSystem.reset(tSPI::create(status));
digitalSystemsInitialized = true;
initialized = true;
}
/**
@@ -160,3 +191,8 @@ bool remapDigitalSource(HAL_Handle digitalSourceHandle,
}
} // namespace hal
// Unused function here to test template compile.
__attribute__((unused)) static void CompileFunctorTest() {
hal::UnsafeManipulateDIO(0, nullptr, [](hal::DIOSetProxy& proxy) {});
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -59,9 +59,6 @@ constexpr double kDefaultPwmCenter = 1.5;
constexpr int32_t kDefaultPwmStepsDown = 1000;
constexpr int32_t kPwmDisabled = 0;
// Create a mutex to protect changes to the DO PWM config
extern wpi::mutex digitalPwmMutex;
extern std::unique_ptr<tDIO> digitalSystem;
extern std::unique_ptr<tRelay> relaySystem;
extern std::unique_ptr<tPWM> pwmSystem;
@@ -79,9 +76,11 @@ struct DigitalPort {
};
extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
kNumDigitalChannels + kNumPWMHeaders>*
digitalChannelHandles;
extern wpi::mutex digitalDIOMutex;
void initializeDigital(int32_t* status);
bool remapDigitalSource(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -223,8 +223,19 @@ double Encoder::DecodingScaleFactor() const {
static LimitedClassedHandleResource<HAL_EncoderHandle, Encoder,
kNumEncoders + kNumCounters,
HAL_HandleEnum::Encoder>
encoderHandles;
HAL_HandleEnum::Encoder>* encoderHandles;
namespace hal {
namespace init {
void InitializeEncoder() {
static LimitedClassedHandleResource<HAL_EncoderHandle, Encoder,
kNumEncoders + kNumCounters,
HAL_HandleEnum::Encoder>
eH;
encoderHandles = &eH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_EncoderHandle HAL_InitializeEncoder(
@@ -236,7 +247,7 @@ HAL_EncoderHandle HAL_InitializeEncoder(
digitalSourceHandleA, analogTriggerTypeA, digitalSourceHandleB,
analogTriggerTypeB, reverseDirection, encodingType, status);
if (*status != 0) return HAL_kInvalidHandle; // return in creation error
auto handle = encoderHandles.Allocate(encoder);
auto handle = encoderHandles->Allocate(encoder);
if (handle == HAL_kInvalidHandle) {
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
@@ -245,11 +256,11 @@ HAL_EncoderHandle HAL_InitializeEncoder(
}
void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
encoderHandles.Free(encoderHandle);
encoderHandles->Free(encoderHandle);
}
int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -258,7 +269,7 @@ int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
}
int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -268,7 +279,7 @@ int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -277,7 +288,7 @@ int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
}
void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -286,7 +297,7 @@ void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
}
double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -296,7 +307,7 @@ double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -306,7 +317,7 @@ void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -316,7 +327,7 @@ HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -326,7 +337,7 @@ HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -335,7 +346,7 @@ double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
}
double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -345,7 +356,7 @@ double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -355,7 +366,7 @@ void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
double distancePerPulse, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -366,7 +377,7 @@ void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
HAL_Bool reverseDirection,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -376,7 +387,7 @@ void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
int32_t samplesToAverage, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -386,7 +397,7 @@ void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -396,7 +407,7 @@ int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -406,7 +417,7 @@ double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -416,7 +427,7 @@ double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return HAL_Encoder_k4X; // default to k4X
@@ -428,7 +439,7 @@ void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
HAL_EncoderIndexingType type, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -438,7 +449,7 @@ void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -24,11 +24,21 @@ struct Encoder {
} // namespace
static const double DECODING_SCALING_FACTOR = 0.25;
static constexpr double DECODING_SCALING_FACTOR = 0.25;
static LimitedHandleResource<HAL_FPGAEncoderHandle, Encoder, kNumEncoders,
HAL_HandleEnum::FPGAEncoder>
fpgaEncoderHandles;
HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles;
namespace hal {
namespace init {
void InitializeFPGAEncoder() {
static LimitedHandleResource<HAL_FPGAEncoderHandle, Encoder, kNumEncoders,
HAL_HandleEnum::FPGAEncoder>
feH;
fpgaEncoderHandles = &feH;
}
} // namespace init
} // namespace hal
extern "C" {
@@ -54,13 +64,13 @@ HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
return HAL_kInvalidHandle;
}
auto handle = fpgaEncoderHandles.Allocate();
auto handle = fpgaEncoderHandles->Allocate();
if (handle == HAL_kInvalidHandle) { // out of resources
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto encoder = fpgaEncoderHandles.Get(handle);
auto encoder = fpgaEncoderHandles->Get(handle);
if (encoder == nullptr) { // will only error on thread issue
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -87,7 +97,7 @@ HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
fpgaEncoderHandles.Free(fpgaEncoderHandle);
fpgaEncoderHandles->Free(fpgaEncoderHandle);
}
/**
@@ -96,7 +106,7 @@ void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -112,7 +122,7 @@ void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -132,7 +142,7 @@ int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0.0;
@@ -169,7 +179,7 @@ double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
double maxPeriod, int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -188,7 +198,7 @@ void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -202,7 +212,7 @@ HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -219,7 +229,7 @@ HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
HAL_Bool reverseDirection,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -236,7 +246,7 @@ void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t samplesToAverage,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -255,7 +265,7 @@ void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
*/
int32_t HAL_GetFPGAEncoderSamplesToAverage(
HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -272,7 +282,7 @@ void HAL_SetFPGAEncoderIndexSource(HAL_FPGAEncoderHandle fpgaEncoderHandle,
HAL_AnalogTriggerType analogTriggerType,
HAL_Bool activeHigh, HAL_Bool edgeSensitive,
int32_t* status) {
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
if (encoder == nullptr) {
*status = HAL_HANDLE_ERROR;
return;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -28,10 +28,19 @@ struct HAL_JoystickAxesInt {
};
static wpi::mutex msgMutex;
static wpi::condition_variable newDSDataAvailableCond;
static wpi::condition_variable* newDSDataAvailableCond;
static wpi::mutex newDSDataAvailableMutex;
static int newDSDataAvailableCounter{0};
namespace hal {
namespace init {
void InitializeFRCDriverStation() {
static wpi::condition_variable nddaC;
newDSDataAvailableCond = &nddaC;
}
} // namespace init
} // namespace hal
extern "C" {
int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
@@ -341,12 +350,12 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
int currentCount = newDSDataAvailableCounter;
while (newDSDataAvailableCounter == currentCount) {
if (timeout > 0) {
auto timedOut = newDSDataAvailableCond.wait_until(lock, timeoutTime);
auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
if (timedOut == std::cv_status::timeout) {
return false;
}
} else {
newDSDataAvailableCond.wait(lock);
newDSDataAvailableCond->wait(lock);
}
}
return true;
@@ -362,7 +371,7 @@ static void newDataOccur(uint32_t refNum) {
std::lock_guard<wpi::mutex> lock(newDSDataAvailableMutex);
// Nofify all threads
newDSDataAvailableCounter++;
newDSDataAvailableCond.notify_all();
newDSDataAvailableCond->notify_all();
}
/*

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -20,13 +20,14 @@
#include <FRC_NetworkCommunication/LoadOut.h>
#include <llvm/raw_ostream.h>
#include <support/mutex.h>
#include <support/timestamp.h>
#include "HAL/ChipObject.h"
#include "HAL/DriverStation.h"
#include "HAL/Errors.h"
#include "HAL/Notifier.h"
#include "HAL/cpp/NotifierInternal.h"
#include "HAL/handles/HandlesInternal.h"
#include "HALInitializer.h"
#include "ctre/ctre.h"
#include "visa/visa.h"
@@ -37,6 +38,44 @@ static std::unique_ptr<tSysWatchdog> watchdog;
using namespace hal;
namespace hal {
namespace init {
void InitializeHAL() {
InitializeHandlesInternal();
InitializeAccelerometer();
InitializeAnalogAccumulator();
InitializeAnalogGyro();
InitializeAnalogInput();
InitializeAnalogInternal();
InitializeAnalogOutput();
InitializeAnalogTrigger();
InitializeCAN();
InitializeCompressor();
InitializeConstants();
InitializeCounter();
InitializeDigitalInternal();
InitializeDIO();
InitializeEncoder();
InitializeFPGAEncoder();
InitializeFRCDriverStation();
InitializeI2C();
InitialzeInterrupts();
InitializeNotifier();
InitializeOSSerialPort();
InitializePCMInternal();
InitializePDP();
InitializePorts();
InitializePower();
InitializePWM();
InitializeRelay();
InitializeSerialPort();
InitializeSolenoid();
InitializeSPI();
InitializeThreads();
}
} // namespace init
} // namespace hal
extern "C" {
HAL_PortHandle HAL_GetPort(int32_t channel) {
@@ -177,7 +216,7 @@ const char* HAL_GetErrorMessage(int32_t code) {
/**
* Returns the runtime type of this HAL
*/
HAL_RuntimeType HAL_GetRuntimeType() { return HAL_Athena; }
HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Athena; }
/**
* Return the FPGA Version number.
@@ -219,8 +258,6 @@ uint64_t HAL_GetFPGATime(int32_t* status) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
// Because of a bug in FPGA image 10, just return the lower 32 bits of time.
return global->readLocalTime(status);
uint64_t upper1 = global->readLocalTimeUpper(status);
uint32_t lower = global->readLocalTime(status);
@@ -334,6 +371,8 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
// Second check in case another thread was waiting
if (initialized) return true;
hal::init::InitializeHAL();
setlinebuf(stdin);
setlinebuf(stdout);
llvm::outs().SetUnbuffered();
@@ -354,9 +393,24 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
int32_t status = 0;
HAL_BaseInitialize(&status);
if (status != 0) return false;
HAL_InitializeDriverStation();
// Set WPI_Now to use FPGA timestamp
wpi::SetNowImpl([]() -> uint64_t {
int32_t status = 0;
uint64_t rv = HAL_GetFPGATime(&status);
if (status != 0) {
llvm::errs()
<< "Call to HAL_GetFPGATime failed."
<< "Initialization might have failed. Time will not be correct\n";
llvm::errs().flush();
return 0u;
}
return rv;
});
initialized = true;
return true;
}
@@ -373,8 +427,8 @@ int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
// TODO: HACKS
// No need for header definitions, as we should not run from user code.
void NumericArrayResize() {}
void RTSetCleanupProc() {}
void EDVR_CreateReference() {}
void NumericArrayResize(void) {}
void RTSetCleanupProc(void) {}
void EDVR_CreateReference(void) {}
} // extern "C"

View File

@@ -0,0 +1,45 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
namespace hal {
namespace init {
extern void InitializeAccelerometer();
extern void InitializeAnalogAccumulator();
extern void InitializeAnalogGyro();
extern void InitializeAnalogInput();
extern void InitializeAnalogInternal();
extern void InitializeAnalogOutput();
extern void InitializeAnalogTrigger();
extern void InitializeCAN();
extern void InitializeCompressor();
extern void InitializeConstants();
extern void InitializeCounter();
extern void InitializeDigitalInternal();
extern void InitializeDIO();
extern void InitializeEncoder();
extern void InitializeFPGAEncoder();
extern void InitializeFRCDriverStation();
extern void InitializeHAL();
extern void InitializeI2C();
extern void InitialzeInterrupts();
extern void InitializeNotifier();
extern void InitializeOSSerialPort();
extern void InitializePCMInternal();
extern void InitializePDP();
extern void InitializePorts();
extern void InitializePower();
extern void InitializePWM();
extern void InitializeRelay();
extern void InitializeSerialPort();
extern void InitializeSolenoid();
extern void InitializeSPI();
extern void InitializeThreads();
extern void InitializeHandlesInternal();
} // namespace init
} // namespace hal

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -24,13 +24,19 @@ using namespace hal;
static wpi::mutex digitalI2COnBoardMutex;
static wpi::mutex digitalI2CMXPMutex;
static uint8_t i2COnboardObjCount = 0;
static uint8_t i2CMXPObjCount = 0;
static int i2COnBoardHandle = -1;
static int i2CMXPHandle = -1;
static uint8_t i2COnboardObjCount{0};
static uint8_t i2CMXPObjCount{0};
static int i2COnBoardHandle{-1};
static int i2CMXPHandle{-1};
static HAL_DigitalHandle i2CMXPDigitalHandle1 = HAL_kInvalidHandle;
static HAL_DigitalHandle i2CMXPDigitalHandle2 = HAL_kInvalidHandle;
static HAL_DigitalHandle i2CMXPDigitalHandle1{HAL_kInvalidHandle};
static HAL_DigitalHandle i2CMXPDigitalHandle2{HAL_kInvalidHandle};
namespace hal {
namespace init {
void InitializeI2C() {}
} // namespace init
} // namespace hal
extern "C" {
@@ -49,7 +55,7 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
}
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
i2COnboardObjCount++;
if (i2COnboardObjCount > 1) return;
int handle = open("/dev/i2c-2", O_RDWR);
@@ -59,7 +65,7 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
}
i2COnBoardHandle = handle;
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
i2CMXPObjCount++;
if (i2CMXPObjCount > 1) return;
if ((i2CMXPDigitalHandle1 = HAL_InitializeDIOPort(
@@ -117,10 +123,10 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
rdwr.nmsgs = 2;
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
}
}
@@ -154,10 +160,10 @@ int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
rdwr.nmsgs = 1;
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
}
}
@@ -193,10 +199,10 @@ int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
rdwr.nmsgs = 1;
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
}
}
@@ -208,12 +214,12 @@ void HAL_CloseI2C(HAL_I2CPort port) {
}
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
if (i2COnboardObjCount-- == 0) {
close(i2COnBoardHandle);
}
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
if (i2CMXPObjCount-- == 0) {
close(i2CMXPHandle);
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -77,19 +77,29 @@ static void threadedInterruptHandler(uint32_t mask, void* param) {
}
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
HAL_HandleEnum::Interrupt>
interruptHandles;
HAL_HandleEnum::Interrupt>* interruptHandles;
namespace hal {
namespace init {
void InitialzeInterrupts() {
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
HAL_HandleEnum::Interrupt>
iH;
interruptHandles = &iH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
int32_t* status) {
HAL_InterruptHandle handle = interruptHandles.Allocate();
HAL_InterruptHandle handle = interruptHandles->Allocate();
if (handle == HAL_kInvalidHandle) {
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto anInterrupt = interruptHandles.Get(handle);
auto anInterrupt = interruptHandles->Get(handle);
uint32_t interruptIndex = static_cast<uint32_t>(getHandleIndex(handle));
// Expects the calling leaf class to allocate an interrupt index.
anInterrupt->anInterrupt.reset(tInterrupt::create(interruptIndex, status));
@@ -100,7 +110,7 @@ HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
}
void HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status) {
interruptHandles.Free(interruptHandle);
interruptHandles->Free(interruptHandle);
}
/**
@@ -114,7 +124,7 @@ int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
double timeout, HAL_Bool ignorePrevious,
int32_t* status) {
uint32_t result;
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -140,7 +150,7 @@ int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
*/
void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -153,7 +163,7 @@ void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
*/
void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -168,7 +178,7 @@ void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
*/
double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -184,7 +194,7 @@ double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
*/
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -197,7 +207,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -222,7 +232,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
HAL_InterruptHandlerFunction handler,
void* param, int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -248,7 +258,7 @@ void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interrupt_handle,
void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);
auto anInterrupt = interruptHandles->Get(interruptHandle);
if (anInterrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -11,123 +11,62 @@
#include <cstdlib> // For std::atexit()
#include <memory>
#include <support/SafeThread.h>
#include <support/condition_variable.h>
#include <support/mutex.h>
#include "HAL/ChipObject.h"
#include "HAL/Errors.h"
#include "HAL/HAL.h"
#include "HAL/cpp/NotifierInternal.h"
#include "HAL/cpp/make_unique.h"
#include "HAL/handles/UnlimitedHandleResource.h"
using namespace hal;
static const int32_t kTimerInterruptNumber = 28;
static constexpr int32_t kTimerInterruptNumber = 28;
static wpi::mutex notifierInterruptMutex;
static wpi::mutex notifierMutex;
static std::unique_ptr<tAlarm> notifierAlarm;
static std::unique_ptr<tInterruptManager> notifierManager;
static uint64_t closestTrigger = UINT64_MAX;
static uint64_t closestTrigger{UINT64_MAX};
namespace {
struct Notifier {
std::shared_ptr<Notifier> prev, next;
void* param;
HAL_NotifierProcessFunction process;
uint64_t triggerTime = UINT64_MAX;
HAL_NotifierHandle handle;
bool threaded;
};
// Safe thread to allow callbacks to run on their own thread
class NotifierThread : public wpi::SafeThread {
public:
void Main() {
std::unique_lock<wpi::mutex> lock(m_mutex);
while (m_active) {
m_cond.wait(lock, [&] { return !m_active || m_notify; });
if (!m_active) break;
m_notify = false;
uint64_t currentTime = m_currentTime;
HAL_NotifierHandle handle = m_handle;
HAL_NotifierProcessFunction process = m_process;
lock.unlock(); // don't hold mutex during callback execution
process(currentTime, handle);
lock.lock();
}
}
bool m_notify = false;
HAL_NotifierHandle m_handle = HAL_kInvalidHandle;
HAL_NotifierProcessFunction m_process;
uint64_t m_currentTime;
};
class NotifierThreadOwner : public wpi::SafeThreadOwner<NotifierThread> {
public:
void SetFunc(HAL_NotifierProcessFunction process, void* param) {
auto thr = GetThread();
if (!thr) return;
thr->m_process = process;
m_param = param;
}
void Notify(uint64_t currentTime, HAL_NotifierHandle handle) {
auto thr = GetThread();
if (!thr) return;
thr->m_currentTime = currentTime;
thr->m_handle = handle;
thr->m_notify = true;
thr->m_cond.notify_one();
}
void* m_param;
uint64_t triggeredTime = UINT64_MAX;
bool active = true;
wpi::mutex mutex;
wpi::condition_variable cond;
};
} // namespace
static std::shared_ptr<Notifier> notifiers;
static std::atomic_flag notifierAtexitRegistered = ATOMIC_FLAG_INIT;
static std::atomic_flag notifierAtexitRegistered{ATOMIC_FLAG_INIT};
static std::atomic_int notifierRefCount{0};
using namespace hal;
static UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
HAL_HandleEnum::Notifier>
notifierHandles;
// Internal version of updateAlarm used during the alarmCallback when we know
// that the pointer is a valid pointer. This function is synchronized by the
// caller locking notifierMutex.
void updateNotifierAlarmInternal(std::shared_ptr<Notifier> notifierPointer,
uint64_t triggerTime, int32_t* status) {
auto notifier = notifierPointer;
// no need for a null check, as this must always be a valid pointer.
notifier->triggerTime = triggerTime;
bool wasActive = (closestTrigger != UINT64_MAX);
if (!notifierInterruptMutex.try_lock() || notifierRefCount == 0 ||
!notifierAlarm)
return;
// Update alarm time if closer than current.
if (triggerTime < closestTrigger) {
closestTrigger = triggerTime;
// Simply truncate the hardware trigger time to 32-bit.
notifierAlarm->writeTriggerTime(static_cast<uint32_t>(triggerTime), status);
class NotifierHandleContainer
: public UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
HAL_HandleEnum::Notifier> {
public:
~NotifierHandleContainer() {
ForEach([](HAL_NotifierHandle handle, Notifier* notifier) {
{
std::lock_guard<wpi::mutex> lock(notifier->mutex);
notifier->triggerTime = UINT64_MAX;
notifier->triggeredTime = 0;
notifier->active = false;
}
notifier->cond.notify_all(); // wake up any waiting threads
});
}
// Enable the alarm. The hardware disables itself after each alarm.
if (!wasActive) notifierAlarm->writeEnable(true, status);
};
notifierInterruptMutex.unlock();
}
static NotifierHandleContainer* notifierHandles;
static void alarmCallback(uint32_t, void*) {
std::unique_lock<wpi::mutex> sync(notifierMutex);
std::lock_guard<wpi::mutex> lock(notifierMutex);
int32_t status = 0;
uint64_t currentTime = 0;
@@ -135,22 +74,26 @@ static void alarmCallback(uint32_t, void*) {
closestTrigger = UINT64_MAX;
// process all notifiers
std::shared_ptr<Notifier> notifier = notifiers;
while (notifier) {
if (notifier->triggerTime != UINT64_MAX) {
if (currentTime == 0) currentTime = HAL_GetFPGATime(&status);
if (notifier->triggerTime < currentTime) {
notifier->triggerTime = UINT64_MAX;
auto process = notifier->process;
auto handle = notifier->handle;
sync.unlock();
process(currentTime, handle);
sync.lock();
} else if (notifier->triggerTime < closestTrigger) {
updateNotifierAlarmInternal(notifier, notifier->triggerTime, &status);
}
notifierHandles->ForEach([&](HAL_NotifierHandle handle, Notifier* notifier) {
if (notifier->triggerTime == UINT64_MAX) return;
if (currentTime == 0) currentTime = HAL_GetFPGATime(&status);
std::unique_lock<wpi::mutex> lock(notifier->mutex);
if (notifier->triggerTime < currentTime) {
notifier->triggerTime = UINT64_MAX;
notifier->triggeredTime = currentTime;
lock.unlock();
notifier->cond.notify_all();
} else if (notifier->triggerTime < closestTrigger) {
closestTrigger = notifier->triggerTime;
}
notifier = notifier->next;
});
if (notifierAlarm && closestTrigger != UINT64_MAX) {
// Simply truncate the hardware trigger time to 32-bit.
notifierAlarm->writeTriggerTime(static_cast<uint32_t>(closestTrigger),
&status);
// Enable the alarm. The hardware disables itself after each alarm.
notifierAlarm->writeEnable(true, &status);
}
}
@@ -159,30 +102,23 @@ static void cleanupNotifierAtExit() {
notifierManager = nullptr;
}
static void threadedNotifierHandler(uint64_t currentTimeInt,
HAL_NotifierHandle handle) {
// Grab notifier and get handler param
auto notifier = notifierHandles.Get(handle);
if (!notifier) return;
auto notifierPointer = notifier->param;
if (notifierPointer == nullptr) return;
NotifierThreadOwner* owner =
static_cast<NotifierThreadOwner*>(notifierPointer);
owner->Notify(currentTimeInt, handle);
namespace hal {
namespace init {
void InitializeNotifier() {
static NotifierHandleContainer nH;
notifierHandles = &nH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
HAL_NotifierProcessFunction process, void* param, int32_t* status) {
if (!process) {
*status = NULL_PARAMETER;
return 0;
}
HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) {
if (!notifierAtexitRegistered.test_and_set())
std::atexit(cleanupNotifierAtExit);
if (notifierRefCount.fetch_add(1) == 0) {
std::lock_guard<wpi::mutex> sync(notifierInterruptMutex);
std::lock_guard<wpi::mutex> lock(notifierMutex);
// create manager and alarm if not already created
if (!notifierManager) {
notifierManager = std::make_unique<tInterruptManager>(
@@ -193,107 +129,100 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status));
}
std::lock_guard<wpi::mutex> sync(notifierMutex);
std::shared_ptr<Notifier> notifier = std::make_shared<Notifier>();
HAL_NotifierHandle handle = notifierHandles.Allocate(notifier);
HAL_NotifierHandle handle = notifierHandles->Allocate(notifier);
if (handle == HAL_kInvalidHandle) {
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
}
// create notifier structure and add to list
notifier->next = notifiers;
if (notifier->next) notifier->next->prev = notifier;
notifier->param = param;
notifier->process = process;
notifier->handle = handle;
notifier->threaded = false;
notifiers = notifier;
return handle;
}
HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
void* param, int32_t* status) {
NotifierThreadOwner* notify = new NotifierThreadOwner;
notify->Start();
notify->SetFunc(process, param);
void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
if (!notifier) return;
auto notifierHandle = HAL_InitializeNotifierNonThreadedUnsafe(
threadedNotifierHandler, notify, status);
if (notifierHandle == HAL_kInvalidHandle || *status != 0) {
delete notify;
return HAL_kInvalidHandle;
{
std::lock_guard<wpi::mutex> lock(notifier->mutex);
notifier->triggerTime = UINT64_MAX;
notifier->triggeredTime = 0;
notifier->active = false;
}
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) {
return HAL_kInvalidHandle;
}
notifier->threaded = true;
return notifierHandle;
notifier->cond.notify_all(); // wake up any waiting threads
}
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
auto notifier = notifierHandles->Free(notifierHandle);
if (!notifier) return;
// Just in case HAL_StopNotifier() wasn't called...
{
std::lock_guard<wpi::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) return;
// remove from list
if (notifier->prev) notifier->prev->next = notifier->next;
if (notifier->next) notifier->next->prev = notifier->prev;
if (notifiers == notifier) notifiers = notifier->next;
notifierHandles.Free(notifierHandle);
if (notifier->threaded) {
NotifierThreadOwner* owner =
static_cast<NotifierThreadOwner*>(notifier->param);
delete owner;
}
std::lock_guard<wpi::mutex> lock(notifier->mutex);
notifier->triggerTime = UINT64_MAX;
notifier->triggeredTime = 0;
notifier->active = false;
}
notifier->cond.notify_all();
if (notifierRefCount.fetch_sub(1) == 1) {
std::lock_guard<wpi::mutex> sync(notifierInterruptMutex);
// if this was the last notifier, clean up alarm and manager
if (notifierAlarm) {
notifierAlarm->writeEnable(false, status);
notifierAlarm = nullptr;
}
if (notifierManager) {
notifierManager->disable(status);
notifierManager = nullptr;
}
// the notifier can call back into our callback, so don't hold the lock
// here (the atomic fetch_sub will prevent multiple parallel entries
// into this function)
if (notifierAlarm) notifierAlarm->writeEnable(false, status);
if (notifierManager) notifierManager->disable(status);
std::lock_guard<wpi::mutex> lock(notifierMutex);
notifierAlarm = nullptr;
notifierManager = nullptr;
closestTrigger = UINT64_MAX;
}
}
void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status) {
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) return nullptr;
if (notifier->threaded) {
// If threaded, return thread param rather then notifier param
NotifierThreadOwner* owner =
static_cast<NotifierThreadOwner*>(notifier->param);
return owner->m_param;
}
return notifier->param;
}
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
uint64_t triggerTime, int32_t* status) {
std::lock_guard<wpi::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
auto notifier = notifierHandles->Get(notifierHandle);
if (!notifier) return;
updateNotifierAlarmInternal(notifier, triggerTime, status);
{
std::lock_guard<wpi::mutex> lock(notifier->mutex);
notifier->triggerTime = triggerTime;
notifier->triggeredTime = UINT64_MAX;
}
std::lock_guard<wpi::mutex> lock(notifierMutex);
// Update alarm time if closer than current.
if (triggerTime < closestTrigger) {
bool wasActive = (closestTrigger != UINT64_MAX);
closestTrigger = triggerTime;
// Simply truncate the hardware trigger time to 32-bit.
notifierAlarm->writeTriggerTime(static_cast<uint32_t>(closestTrigger),
status);
// Enable the alarm.
if (!wasActive) notifierAlarm->writeEnable(true, status);
}
}
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status) {
std::lock_guard<wpi::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
if (!notifier) return;
notifier->triggerTime = UINT64_MAX;
{
std::lock_guard<wpi::mutex> lock(notifier->mutex);
notifier->triggerTime = UINT64_MAX;
}
}
uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
int32_t* status) {
auto notifier = notifierHandles->Get(notifierHandle);
if (!notifier) return 0;
std::unique_lock<wpi::mutex> lock(notifier->mutex);
notifier->cond.wait(lock, [&] {
return !notifier->active || notifier->triggeredTime != UINT64_MAX;
});
return notifier->active ? notifier->triggeredTime : 0;
}
} // extern "C"

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -24,6 +24,17 @@ static std::chrono::milliseconds portTimeouts[4]{
std::chrono::milliseconds(0), std::chrono::milliseconds(0),
std::chrono::milliseconds(0), std::chrono::milliseconds(0)};
namespace hal {
namespace init {
void InitializeOSSerialPort() {
for (int i = 0; i < 4; i++) {
portHandles[i] = -1;
portTimeouts[i] = std::chrono::milliseconds(0);
}
}
} // namespace init
} // namespace hal
extern "C" {
void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -16,6 +16,14 @@ namespace hal {
std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
namespace init {
void InitializePCMInternal() {
for (int i = 0; i < kNumPCMModules; i++) {
PCM_modules[i] = nullptr;
}
}
} // namespace init
void initializePCM(int32_t module, int32_t* status) {
if (!HAL_CheckSolenoidModule(module)) {
*status = RESOURCE_OUT_OF_RANGE;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -31,6 +31,16 @@ static inline bool checkPDPInit(int32_t module, int32_t* status) {
return true;
}
namespace hal {
namespace init {
void InitializePDP() {
for (int i = 0; i < kNumPDPModules; i++) {
pdp[i] = nullptr;
}
}
} // namespace init
} // namespace hal
extern "C" {
void HAL_InitializePDP(int32_t module, int32_t* status) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -56,6 +56,12 @@ static inline int32_t GetFullRangeScaleFactor(DigitalPort* port) {
return GetMaxPositivePwm(port) - GetMinNegativePwm(port);
} ///< The scale for positions.
namespace hal {
namespace init {
void InitializePWM() {}
} // namespace init
} // namespace hal
extern "C" {
HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
@@ -79,12 +85,12 @@ HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
}
auto handle =
digitalChannelHandles.Allocate(channel, HAL_HandleEnum::PWM, status);
digitalChannelHandles->Allocate(channel, HAL_HandleEnum::PWM, status);
if (*status != 0)
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
auto port = digitalChannelHandles.Get(handle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::PWM);
if (port == nullptr) { // would only occur on thread issue.
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -101,7 +107,7 @@ HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
return handle;
}
void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -115,7 +121,7 @@ void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
status);
}
digitalChannelHandles.Free(pwmPortHandle, HAL_HandleEnum::PWM);
digitalChannelHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM);
}
HAL_Bool HAL_CheckPWMChannel(int32_t channel) {
@@ -125,7 +131,7 @@ HAL_Bool HAL_CheckPWMChannel(int32_t channel) {
void HAL_SetPWMConfig(HAL_DigitalHandle pwmPortHandle, double max,
double deadbandMax, double center, double deadbandMin,
double min, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -159,7 +165,7 @@ void HAL_SetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t maxPwm,
int32_t deadbandMaxPwm, int32_t centerPwm,
int32_t deadbandMinPwm, int32_t minPwm,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -176,7 +182,7 @@ void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
int32_t* deadbandMaxPwm, int32_t* centerPwm,
int32_t* deadbandMinPwm, int32_t* minPwm,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -190,7 +196,7 @@ void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
HAL_Bool eliminateDeadband, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -200,7 +206,7 @@ void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -218,7 +224,7 @@ HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
*/
void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -242,7 +248,7 @@ void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
*/
void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -297,7 +303,7 @@ void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
*/
void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double pos,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -339,7 +345,7 @@ void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
* @return The raw PWM value.
*/
int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -359,7 +365,7 @@ int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
* @return The scaled PWM value.
*/
double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -397,7 +403,7 @@ double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
* @return The scaled PWM value.
*/
double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -422,7 +428,7 @@ double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
}
void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -440,7 +446,7 @@ void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
*/
void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
int32_t* status) {
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -473,9 +479,6 @@ int32_t HAL_GetPWMLoopTiming(int32_t* status) {
uint64_t HAL_GetPWMCycleStartTime(int32_t* status) {
initializeDigital(status);
if (*status != 0) return 0;
// Because of a bug in FPGA image 10, just return the lower 32 bits of cycle
// time.
return pwmSystem->readCycleStartTime(status);
uint64_t upper1 = pwmSystem->readCycleStartTimeUpper(status);
uint32_t lower = pwmSystem->readCycleStartTime(status);

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -11,6 +11,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializePorts() {}
} // namespace init
} // namespace hal
extern "C" {
int32_t HAL_GetNumAccumulators(void) { return kNumAccumulators; }

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -15,7 +15,7 @@ using namespace hal;
namespace hal {
static std::unique_ptr<tPower> power;
static std::unique_ptr<tPower> power{nullptr};
static void initializePower(int32_t* status) {
if (power == nullptr) {
@@ -25,6 +25,12 @@ static void initializePower(int32_t* status) {
} // namespace hal
namespace hal {
namespace init {
void InitializePower() {}
} // namespace init
} // namespace hal
extern "C" {
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -23,12 +23,22 @@ struct Relay {
} // namespace
static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
HAL_HandleEnum::Relay>
relayHandles;
HAL_HandleEnum::Relay>* relayHandles;
// Create a mutex to protect changes to the relay values
static wpi::mutex digitalRelayMutex;
namespace hal {
namespace init {
void InitializeRelay() {
static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
HAL_HandleEnum::Relay>
rH;
relayHandles = &rH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
@@ -45,12 +55,12 @@ HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
if (!fwd) channel += kNumRelayHeaders; // add 4 to reverse channels
auto handle = relayHandles.Allocate(channel, status);
auto handle = relayHandles->Allocate(channel, status);
if (*status != 0)
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
auto port = relayHandles.Get(handle);
auto port = relayHandles->Get(handle);
if (port == nullptr) { // would only occur on thread issue.
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -71,7 +81,7 @@ HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle) {
// no status, so no need to check for a proper free.
relayHandles.Free(relayPortHandle);
relayHandles->Free(relayPortHandle);
}
HAL_Bool HAL_CheckRelayChannel(int32_t channel) {
@@ -87,12 +97,12 @@ HAL_Bool HAL_CheckRelayChannel(int32_t channel) {
*/
void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
int32_t* status) {
auto port = relayHandles.Get(relayPortHandle);
auto port = relayHandles->Get(relayPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
std::lock_guard<wpi::mutex> sync(digitalRelayMutex);
std::lock_guard<wpi::mutex> lock(digitalRelayMutex);
uint8_t relays = 0;
if (port->fwd) {
relays = relaySystem->readValue_Forward(status);
@@ -119,7 +129,7 @@ void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
* Get the current state of the relay channel
*/
HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status) {
auto port = relayHandles.Get(relayPortHandle);
auto port = relayHandles->Get(relayPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -22,17 +22,16 @@
#include "DigitalInternal.h"
#include "HAL/DIO.h"
#include "HAL/HAL.h"
#include "HAL/Notifier.h"
#include "HAL/cpp/make_unique.h"
#include "HAL/handles/HandlesInternal.h"
using namespace hal;
static int32_t m_spiCS0Handle = 0;
static int32_t m_spiCS1Handle = 0;
static int32_t m_spiCS2Handle = 0;
static int32_t m_spiCS3Handle = 0;
static int32_t m_spiMXPHandle = 0;
static int32_t m_spiCS0Handle{0};
static int32_t m_spiCS1Handle{0};
static int32_t m_spiCS2Handle{0};
static int32_t m_spiCS3Handle{0};
static int32_t m_spiMXPHandle{0};
static constexpr int32_t kSpiMaxHandles = 5;
@@ -42,37 +41,33 @@ static std::array<wpi::mutex, kSpiMaxHandles> spiApiMutexes;
static std::array<wpi::mutex, kSpiMaxHandles> spiAccumulatorMutexes;
// MXP SPI does not count towards this
std::atomic<int32_t> spiPortCount{0};
static std::atomic<int32_t> spiPortCount{0};
static HAL_DigitalHandle digitalHandles[9]{HAL_kInvalidHandle};
static wpi::mutex spiAutoMutex;
static int32_t spiAutoPort = kSpiMaxHandles;
static std::atomic_bool spiAutoRunning{false};
static std::unique_ptr<tDMAManager> spiAutoDMA;
static bool SPIInUseByAuto(HAL_SPIPort port) {
// SPI engine conflicts with any other chip selects on the same SPI device.
// There are two SPI devices: one for ports 0-3 (onboard), the other for port
// 4 (MXP).
if (!spiAutoRunning) return false;
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
return (spiAutoPort >= 0 && spiAutoPort <= 3 && port >= 0 && port <= 3) ||
(spiAutoPort == 4 && port == 4);
}
namespace hal {
namespace init {
void InitializeSPI() {}
} // namespace init
} // namespace hal
extern "C" {
struct SPIAccumulator {
std::atomic<HAL_NotifierHandle> notifier{0};
uint64_t triggerTime;
int32_t period;
int64_t value = 0;
uint32_t count = 0;
int32_t lastValue = 0;
int32_t center = 0;
int32_t deadband = 0;
uint8_t cmd[4]; // command to send (up to 4 bytes)
int32_t validMask;
int32_t validValue;
int32_t dataMax; // one more than max data value
int32_t dataMsbMask; // data field MSB mask (for signed)
uint8_t dataShift; // data field shift right amount, in bits
uint8_t xferSize; // SPI transfer size, in bytes (up to 4)
HAL_SPIPort port;
bool isSigned; // is data field signed?
bool bigEndian; // is response big endian?
};
std::unique_ptr<SPIAccumulator> spiAccumulators[5];
static void CommonSPIPortInit(int32_t* status) {
// All false cases will set
if (spiPortCount.fetch_add(1) == 0) {
@@ -97,7 +92,7 @@ static void CommonSPIPortInit(int32_t* status) {
}
}
static void CommonSPIPortFree() {
static void CommonSPIPortFree(void) {
if (spiPortCount.fetch_sub(1) == 1) {
// Clean up SPI Handles
HAL_FreeDIOPort(digitalHandles[3]);
@@ -266,13 +261,15 @@ int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
return -1;
}
if (SPIInUseByAuto(port)) return -1;
struct spi_ioc_transfer xfer;
std::memset(&xfer, 0, sizeof(xfer));
xfer.tx_buf = (__u64)dataToSend;
xfer.rx_buf = (__u64)dataReceived;
xfer.len = size;
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
@@ -292,12 +289,14 @@ int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
return -1;
}
if (SPIInUseByAuto(port)) return -1;
struct spi_ioc_transfer xfer;
std::memset(&xfer, 0, sizeof(xfer));
xfer.tx_buf = (__u64)dataToSend;
xfer.len = sendSize;
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
@@ -319,12 +318,14 @@ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
return -1;
}
if (SPIInUseByAuto(port)) return -1;
struct spi_ioc_transfer xfer;
std::memset(&xfer, 0, sizeof(xfer));
xfer.rx_buf = (__u64)buffer;
xfer.len = count;
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
@@ -339,10 +340,10 @@ void HAL_CloseSPI(HAL_SPIPort port) {
}
int32_t status = 0;
HAL_FreeSPIAccumulator(port, &status);
HAL_FreeSPIAuto(port, &status);
{
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
close(HAL_GetSPIHandle(port));
}
@@ -384,7 +385,7 @@ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
return;
}
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
}
@@ -409,7 +410,7 @@ void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
mode |= (clkIdleHigh ? 2 : 0);
mode |= (sampleOnTrailing ? 1 : 0);
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
}
@@ -424,7 +425,7 @@ void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
if (port < 4) {
spiSystem->writeChipSelectActiveHigh_Hdr(
spiSystem->readChipSelectActiveHigh_Hdr(status) | (1 << port), status);
@@ -444,7 +445,7 @@ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
if (port < 4) {
spiSystem->writeChipSelectActiveHigh_Hdr(
spiSystem->readChipSelectActiveHigh_Hdr(status) & ~(1 << port), status);
@@ -464,7 +465,7 @@ int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
return 0;
}
std::lock_guard<wpi::mutex> sync(spiHandleMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiHandleMutexes[port]);
switch (port) {
case 0:
return m_spiCS0Handle;
@@ -493,7 +494,7 @@ void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
return;
}
std::lock_guard<wpi::mutex> sync(spiHandleMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiHandleMutexes[port]);
switch (port) {
case 0:
m_spiCS0Handle = handle;
@@ -515,311 +516,202 @@ void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
}
}
static void spiAccumulatorProcess(uint64_t currentTime,
HAL_NotifierHandle handle) {
int32_t status = 0;
auto param = HAL_GetNotifierParam(handle, &status);
if (param == nullptr) return;
SPIAccumulator* accum = static_cast<SPIAccumulator*>(param);
void HAL_InitSPIAuto(HAL_SPIPort port, int32_t bufferSize, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
// perform SPI transaction
uint8_t resp_b[4];
HAL_TransactionSPI(accum->port, accum->cmd, resp_b, accum->xferSize);
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (spiAutoPort != kSpiMaxHandles) {
*status = RESOURCE_IS_ALLOCATED;
return;
}
// convert from bytes
uint32_t resp = 0;
if (accum->bigEndian) {
for (int32_t i = 0; i < accum->xferSize; ++i) {
resp <<= 8;
resp |= resp_b[i] & 0xff;
}
// remember the initialized port for other entry points
spiAutoPort = port;
// configure the correct chip select
if (port < 4) {
spiSystem->writeAutoSPI1Select(false, status);
spiSystem->writeAutoChipSelect(port, status);
} else {
for (int32_t i = accum->xferSize - 1; i >= 0; --i) {
resp <<= 8;
resp |= resp_b[i] & 0xff;
}
spiSystem->writeAutoSPI1Select(true, status);
spiSystem->writeAutoChipSelect(0, status);
}
// process response
if ((resp & accum->validMask) == static_cast<uint32_t>(accum->validValue)) {
// valid sensor data; extract data field
int32_t data = static_cast<int32_t>(resp >> accum->dataShift);
data &= accum->dataMax - 1;
// 2s complement conversion if signed MSB is set
if (accum->isSigned && (data & accum->dataMsbMask) != 0)
data -= accum->dataMax;
// center offset
data -= accum->center;
// only accumulate if outside deadband
if (data < -accum->deadband || data > accum->deadband) accum->value += data;
++accum->count;
accum->lastValue = data;
} else {
// no data from the sensor; just clear the last value
accum->lastValue = 0;
}
// reschedule timer
accum->triggerTime += accum->period;
// handle timer slip
if (accum->triggerTime < currentTime)
accum->triggerTime = currentTime + accum->period;
status = 0;
HAL_UpdateNotifierAlarm(accum->notifier, accum->triggerTime, &status);
// configure DMA
tDMAChannelDescriptor desc;
spiSystem->getSystemInterface()->getDmaDescriptor(g_SpiAutoData_index, &desc);
spiAutoDMA = std::make_unique<tDMAManager>(desc.channel, bufferSize, status);
}
/**
* Initialize a SPI accumulator.
*
* @param port SPI port
* @param period Time between reads, in us
* @param cmd SPI command to send to request data
* @param xferSize SPI transfer size, in bytes
* @param validMask Mask to apply to received data for validity checking
* @param valid_data After validMask is applied, required matching value for
* validity checking
* @param dataShift Bit shift to apply to received data to get actual data
* value
* @param dataSize Size (in bits) of data field
* @param isSigned Is data field signed?
* @param bigEndian Is device big endian?
*/
void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
int32_t xferSize, int32_t validMask,
int32_t validValue, int32_t dataShift,
int32_t dataSize, HAL_Bool isSigned,
HAL_Bool bigEndian, int32_t* status) {
void HAL_FreeSPIAuto(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
if (!spiAccumulators[port])
spiAccumulators[port] = std::make_unique<SPIAccumulator>();
SPIAccumulator* accum = spiAccumulators[port].get();
if (bigEndian) {
for (int32_t i = xferSize - 1; i >= 0; --i) {
accum->cmd[i] = cmd & 0xff;
cmd >>= 8;
}
} else {
accum->cmd[0] = cmd & 0xff;
cmd >>= 8;
accum->cmd[1] = cmd & 0xff;
cmd >>= 8;
accum->cmd[2] = cmd & 0xff;
cmd >>= 8;
accum->cmd[3] = cmd & 0xff;
}
accum->period = period;
accum->xferSize = xferSize;
accum->validMask = validMask;
accum->validValue = validValue;
accum->dataShift = dataShift;
accum->dataMax = (1 << dataSize);
accum->dataMsbMask = (1 << (dataSize - 1));
accum->isSigned = isSigned;
accum->bigEndian = bigEndian;
accum->port = port;
if (!accum->notifier) {
accum->notifier =
HAL_InitializeNotifier(spiAccumulatorProcess, accum, status);
accum->triggerTime = HAL_GetFPGATime(status) + period;
if (*status != 0) return;
HAL_UpdateNotifierAlarm(accum->notifier, accum->triggerTime, status);
}
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
if (spiAutoPort != port) return;
spiAutoPort = kSpiMaxHandles;
// disable by setting to internal clock and setting rate=0
spiSystem->writeAutoRate(0, status);
spiSystem->writeAutoTriggerConfig_ExternalClock(false, status);
// stop the DMA
spiAutoDMA->stop(status);
spiAutoDMA.reset(nullptr);
spiAutoRunning = false;
}
/**
* Frees a SPI accumulator.
*/
void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
void HAL_StartSPIAutoRate(HAL_SPIPort port, double period, int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return;
}
spiAutoRunning = true;
// start the DMA
spiAutoDMA->start(status);
// auto rate is in microseconds
spiSystem->writeAutoRate(period * 1000000, status);
// disable the external clock
spiSystem->writeAutoTriggerConfig_ExternalClock(false, status);
}
void HAL_StartSPIAutoTrigger(HAL_SPIPort port, HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
HAL_Bool triggerRising, HAL_Bool triggerFalling,
int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return;
}
spiAutoRunning = true;
// start the DMA
spiAutoDMA->start(status);
// get channel routing
bool routingAnalogTrigger = false;
uint8_t routingChannel = 0;
uint8_t routingModule = 0;
if (!remapDigitalSource(digitalSourceHandle, analogTriggerType,
routingChannel, routingModule,
routingAnalogTrigger)) {
*status = HAL_HANDLE_ERROR;
return;
}
// configure external trigger and enable it
tSPI::tAutoTriggerConfig config;
config.ExternalClock = 1;
config.FallingEdge = triggerFalling ? 1 : 0;
config.RisingEdge = triggerRising ? 1 : 0;
config.ExternalClockSource_AnalogTrigger = routingAnalogTrigger ? 1 : 0;
config.ExternalClockSource_Module = routingModule;
config.ExternalClockSource_Channel = routingChannel;
spiSystem->writeAutoTriggerConfig(config, status);
}
void HAL_StopSPIAuto(HAL_SPIPort port, int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return;
}
// disable by setting to internal clock and setting rate=0
spiSystem->writeAutoRate(0, status);
spiSystem->writeAutoTriggerConfig_ExternalClock(false, status);
// stop the DMA
spiAutoDMA->stop(status);
spiAutoRunning = false;
}
void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t dataSize, int32_t zeroSize,
int32_t* status) {
if (dataSize < 0 || dataSize > 16) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
return;
}
HAL_NotifierHandle handle = accum->notifier.exchange(0);
HAL_CleanNotifier(handle, status);
spiAccumulators[port] = nullptr;
}
/**
* Resets the accumulator to zero.
*/
void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
if (zeroSize < 0 || zeroSize > 127) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return;
}
accum->value = 0;
accum->count = 0;
accum->lastValue = 0;
// set tx data registers
for (int32_t i = 0; i < dataSize; ++i)
spiSystem->writeAutoTx(i >> 2, i & 3, dataToSend[i], status);
// set byte counts
tSPI::tAutoByteCount config;
config.ZeroByteCount = static_cast<unsigned>(zeroSize) & 0x7f;
config.TxByteCount = static_cast<unsigned>(dataSize) & 0xf;
spiSystem->writeAutoByteCount(config, status);
}
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each value before it is added to the
* accumulator. This
* is used for the center value of devices like gyros and accelerometers to make
* integration work
* and to take the device offset into account when integrating.
*/
void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center,
int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
return;
}
accum->center = center;
spiSystem->strobeAutoForceOne(status);
}
/**
* Set the accumulator's deadband.
*/
void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband,
int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
return;
}
accum->deadband = deadband;
}
/**
* Read the last value read by the accumulator engine.
*/
int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint8_t* buffer,
int32_t numToRead, double timeout,
int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return 0;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
return 0;
}
return accum->lastValue;
size_t numRemaining = 0;
// timeout is in ms
spiAutoDMA->read(buffer, numToRead, timeout * 1000, &numRemaining, status);
return numRemaining;
}
/**
* Read the accumulated value.
*
* @return The 64-bit value accumulated since the last Reset().
*/
int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);
// FPGA only has one auto SPI engine
if (port != spiAutoPort) {
*status = INCOMPATIBLE_STATE;
return 0;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
return 0;
}
return accum->value;
}
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last
* Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return 0;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
return 0;
}
return accum->count;
}
/**
* Read the average of the accumulated value.
*
* @return The accumulated average value (value / count).
*/
double HAL_GetSPIAccumulatorAverage(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return 0.0;
}
int64_t value;
int64_t count;
HAL_GetSPIAccumulatorOutput(port, &value, &count, status);
if (count == 0) return 0.0;
return static_cast<double>(value) / count;
}
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count atomically.
* This can be used for averaging.
*
* @param value Pointer to the 64-bit accumulated output.
* @param count Pointer to the number of accumulation cycles.
*/
void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value,
int64_t* count, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
*value = 0;
*count = 0;
return;
}
*value = accum->value;
*count = accum->count;
return spiSystem->readTransferSkippedFullCount(status);
}
} // extern "C"

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -12,9 +12,15 @@
#include "HAL/cpp/SerialHelper.h"
#include "visa/visa.h"
static int32_t resourceManagerHandle;
static int32_t resourceManagerHandle{0};
static HAL_SerialPort portHandles[4];
namespace hal {
namespace init {
void InitializeSerialPort() {}
} // namespace init
} // namespace hal
extern "C" {
void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -31,8 +31,19 @@ using namespace hal;
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
kNumPCMModules * kNumSolenoidChannels,
HAL_HandleEnum::Solenoid>
solenoidHandles;
HAL_HandleEnum::Solenoid>* solenoidHandles;
namespace hal {
namespace init {
void InitializeSolenoid() {
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
kNumPCMModules * kNumSolenoidChannels,
HAL_HandleEnum::Solenoid>
sH;
solenoidHandles = &sH;
}
} // namespace init
} // namespace hal
extern "C" {
@@ -56,12 +67,12 @@ HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
return HAL_kInvalidHandle;
}
auto handle =
solenoidHandles.Allocate(module * kNumSolenoidChannels + channel, status);
auto handle = solenoidHandles->Allocate(
module * kNumSolenoidChannels + channel, status);
if (*status != 0) {
return HAL_kInvalidHandle;
}
auto solenoidPort = solenoidHandles.Get(handle);
auto solenoidPort = solenoidHandles->Get(handle);
if (solenoidPort == nullptr) { // would only occur on thread issues
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -73,7 +84,7 @@ HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
}
void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
solenoidHandles.Free(solenoidPortHandle);
solenoidHandles->Free(solenoidPortHandle);
}
HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
@@ -86,7 +97,7 @@ HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
int32_t* status) {
auto port = solenoidHandles.Get(solenoidPortHandle);
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
@@ -109,7 +120,7 @@ int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
int32_t* status) {
auto port = solenoidHandles.Get(solenoidPortHandle);
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -154,4 +165,25 @@ void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
*status = PCM_modules[module]->ClearStickyFaults();
}
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
int32_t durMS, int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
*status =
PCM_modules[port->module]->SetOneShotDurationMs(port->channel, durMS);
}
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
*status = PCM_modules[port->module]->FireOneShotSolenoid(port->channel);
}
} // extern "C"

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -12,6 +12,12 @@
#include "HAL/Errors.h"
namespace hal {
namespace init {
void InitializeThreads() {}
} // namespace init
} // namespace hal
extern "C" {
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -213,7 +213,9 @@ CTR_Code PCM::FireOneShotSolenoid(UINT8 idx)
return CTR_OKAY;
}
/* Configure the pulse width of a solenoid channel for one-shot pulse.
* Preprogrammed pulsewidth is 10ms resolute and can be between 20ms and 5.1s.
* Preprogrammed pulsewidth is 10ms resolution and can be between 10ms and
* 2.55s.
*
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid [0,7] to configure.
* @Param - durMs - pulse width in ms.

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -28,6 +28,8 @@ void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status);
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
int32_t* status);
void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
int32_t* status);
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status);
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status);
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2013-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2013-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2013-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2013-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -54,7 +54,7 @@ const char* HAL_GetErrorMessage(int32_t code);
int32_t HAL_GetFPGAVersion(int32_t* status);
int64_t HAL_GetFPGARevision(int32_t* status);
HAL_RuntimeType HAL_GetRuntimeType();
HAL_RuntimeType HAL_GetRuntimeType(void);
HAL_Bool HAL_GetFPGAButton(int32_t* status);
HAL_Bool HAL_GetSystemActive(int32_t* status);

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -15,16 +15,16 @@
extern "C" {
#endif
typedef void (*HAL_NotifierProcessFunction)(uint64_t currentTime,
HAL_NotifierHandle handle);
HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
void* param, int32_t* status);
HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status);
void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status);
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
uint64_t triggerTime, int32_t* status);
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status);
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
int32_t* status);
uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "HAL/AnalogTrigger.h"
#include "HAL/Types.h"
enum HAL_SPIPort : int32_t {
@@ -38,23 +39,23 @@ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status);
int32_t HAL_GetSPIHandle(HAL_SPIPort port);
void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle);
void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
int32_t xferSize, int32_t validMask,
int32_t validValue, int32_t dataShift,
int32_t dataSize, HAL_Bool isSigned,
HAL_Bool bigEndian, int32_t* status);
void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status);
void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status);
void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center,
int32_t* status);
void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband,
int32_t* status);
int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status);
int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status);
int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status);
double HAL_GetSPIAccumulatorAverage(HAL_SPIPort port, int32_t* status);
void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value,
int64_t* count, int32_t* status);
void HAL_InitSPIAuto(HAL_SPIPort port, int32_t bufferSize, int32_t* status);
void HAL_FreeSPIAuto(HAL_SPIPort port, int32_t* status);
void HAL_StartSPIAutoRate(HAL_SPIPort port, double period, int32_t* status);
void HAL_StartSPIAutoTrigger(HAL_SPIPort port, HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
HAL_Bool triggerRising, HAL_Bool triggerFalling,
int32_t* status);
void HAL_StopSPIAuto(HAL_SPIPort port, int32_t* status);
void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t dataSize, int32_t zeroSize,
int32_t* status);
void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status);
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint8_t* buffer,
int32_t numToRead, double timeout,
int32_t* status);
int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -30,6 +30,9 @@ int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status);
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status);
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status);
void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status);
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
int32_t durMS, int32_t* status);
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -83,6 +83,14 @@ namespace nUsageReporting
kResourceType_PCM, // 60
kResourceType_PigeonIMU,
kResourceType_NidecBrushless,
kResourceType_CANifier,
kResourceType_CTRE_future0,
kResourceType_CTRE_future1,
kResourceType_CTRE_future2,
kResourceType_CTRE_future3,
kResourceType_CTRE_future4,
kResourceType_CTRE_future5,
kResourceType_CTRE_future6, // 70
} tResourceType;
typedef enum

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -0,0 +1,85 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <support/mutex.h>
#include "HAL/ChipObject.h"
#include "HAL/Types.h"
namespace hal {
struct DIOSetProxy {
DIOSetProxy(const DIOSetProxy&) = delete;
DIOSetProxy(DIOSetProxy&&) = delete;
DIOSetProxy& operator=(const DIOSetProxy&) = delete;
DIOSetProxy& operator=(DIOSetProxy&&) = delete;
void SetOutputMode(int32_t* status) {
m_dio->writeOutputEnable(m_setOutputDirReg, status);
}
void SetInputMode(int32_t* status) {
m_dio->writeOutputEnable(m_unsetOutputDirReg, status);
}
void SetOutputTrue(int32_t* status) {
m_dio->writeDO(m_setOutputStateReg, status);
}
void SetOutputFalse(int32_t* status) {
m_dio->writeDO(m_unsetOutputStateReg, status);
}
tDIO::tOutputEnable m_setOutputDirReg;
tDIO::tOutputEnable m_unsetOutputDirReg;
tDIO::tDO m_setOutputStateReg;
tDIO::tDO m_unsetOutputStateReg;
tDIO* m_dio;
};
namespace detail {
wpi::mutex& UnsafeGetDIOMutex();
tDIO* UnsafeGetDigialSystem();
int32_t ComputeDigitalMask(HAL_DigitalHandle handle, int32_t* status);
} // namespace detail
/**
* Unsafe digital output set function
* This function can be used to perform fast and determinstically set digital
* outputs. This function holds the DIO lock, so calling anyting other then
* functions on the Proxy object passed as a parameter can deadlock your
* program.
*
*/
template <typename Functor>
void UnsafeManipulateDIO(HAL_DigitalHandle handle, int32_t* status,
Functor func) {
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
wpi::mutex& dioMutex = detail::UnsafeGetDIOMutex();
tDIO* dSys = detail::UnsafeGetDigialSystem();
auto mask = detail::ComputeDigitalMask(handle, status);
if (status != 0) return;
std::lock_guard<wpi::mutex> lock(dioMutex);
tDIO::tOutputEnable enableOE = dSys->readOutputEnable(status);
enableOE.value |= mask;
auto disableOE = enableOE;
disableOE.value &= ~mask;
tDIO::tDO enableDO = dSys->readDO(status);
enableDO.value |= mask;
auto disableDO = enableDO;
disableDO.value &= ~mask;
DIOSetProxy dioData{enableOE, disableOE, enableDO, disableDO, dSys};
func(dioData);
}
} // namespace hal

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -60,7 +60,7 @@ THandle DigitalHandleResource<THandle, TStruct, size>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// check for allocation, otherwise allocate and return a valid handle
if (m_structures[index] != nullptr) {
*status = RESOURCE_IS_ALLOCATED;
@@ -78,7 +78,7 @@ std::shared_ptr<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -91,14 +91,14 @@ void DigitalHandleResource<THandle, TStruct, size>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
template <typename THandle, typename TStruct, int16_t size>
void DigitalHandleResource<THandle, TStruct, size>::ResetHandles() {
for (int i = 0; i < size; i++) {
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -77,7 +77,7 @@ static inline int16_t getHandleTypedIndex(HAL_Handle handle,
HAL_HandleEnum enumType,
int16_t version) {
if (!isHandleType(handle, enumType)) return InvalidHandleIndex;
#if !defined(CONFIG_ATHENA)
#if !defined(__FRC_ROBORIO__)
if (!isHandleCorrectVersion(handle, version)) return InvalidHandleIndex;
#endif
return getHandleIndex(handle);

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <array>
#include <memory>
#include <vector>
@@ -17,7 +18,6 @@
#include "HAL/Errors.h"
#include "HAL/Types.h"
#include "HAL/cpp/make_unique.h"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/handles/HandlesInternal.h"
namespace hal {
@@ -41,7 +41,7 @@ class IndexedClassedHandleResource : public HandleBase {
friend class IndexedClassedHandleResourceTest;
public:
IndexedClassedHandleResource();
IndexedClassedHandleResource() = default;
IndexedClassedHandleResource(const IndexedClassedHandleResource&) = delete;
IndexedClassedHandleResource& operator=(const IndexedClassedHandleResource&) =
delete;
@@ -50,20 +50,13 @@ class IndexedClassedHandleResource : public HandleBase {
int32_t* status);
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);
void ResetHandles();
private:
std::array<std::shared_ptr<TStruct>[], size> m_structures;
std::array<wpi::mutex[], size> m_handleMutexes;
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<wpi::mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
IndexedClassedHandleResource<THandle, TStruct, size,
enumValue>::IndexedClassedHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<wpi::mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
THandle
@@ -74,7 +67,7 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// check for allocation, otherwise allocate and return a valid handle
if (m_structures[index] != nullptr) {
*status = RESOURCE_IS_ALLOCATED;
@@ -94,7 +87,7 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -108,7 +101,7 @@ void IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -117,7 +110,7 @@ template <typename THandle, typename TStruct, int16_t size,
void IndexedClassedHandleResource<THandle, TStruct, size,
enumValue>::ResetHandles() {
for (int i = 0; i < size; i++) {
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -62,7 +62,7 @@ THandle IndexedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// check for allocation, otherwise allocate and return a valid handle
if (m_structures[index] != nullptr) {
*status = RESOURCE_IS_ALLOCATED;
@@ -81,7 +81,7 @@ IndexedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -95,7 +95,7 @@ void IndexedHandleResource<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -103,7 +103,7 @@ template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
void IndexedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
for (int i = 0; i < size; i++) {
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -59,12 +59,12 @@ THandle
LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
std::shared_ptr<TStruct> toSet) {
// globally lock to loop through indices
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
for (int16_t i = 0; i < size; i++) {
if (m_structures[i] == nullptr) {
// if a false index is found, grab its specific mutex
// and allocate it.
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
m_structures[i] = toSet;
return static_cast<THandle>(createHandle(i, enumValue, m_version));
}
@@ -82,7 +82,7 @@ LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -96,8 +96,8 @@ void LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -106,9 +106,9 @@ template <typename THandle, typename TStruct, int16_t size,
void LimitedClassedHandleResource<THandle, TStruct, size,
enumValue>::ResetHandles() {
{
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
for (int i = 0; i < size; i++) {
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
m_structures[i].reset();
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -55,12 +55,12 @@ template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
THandle LimitedHandleResource<THandle, TStruct, size, enumValue>::Allocate() {
// globally lock to loop through indices
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
for (int16_t i = 0; i < size; i++) {
if (m_structures[i] == nullptr) {
// if a false index is found, grab its specific mutex
// and allocate it.
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
m_structures[i] = std::make_shared<TStruct>();
return static_cast<THandle>(createHandle(i, enumValue, m_version));
}
@@ -77,7 +77,7 @@ LimitedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -91,8 +91,8 @@ void LimitedHandleResource<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -100,9 +100,9 @@ template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
void LimitedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
{
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
for (int i = 0; i < size; i++) {
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
m_structures[i].reset();
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -10,6 +10,7 @@
#include <stdint.h>
#include <memory>
#include <utility>
#include <vector>
#include <support/mutex.h>
@@ -44,9 +45,16 @@ class UnlimitedHandleResource : public HandleBase {
THandle Allocate(std::shared_ptr<TStruct> structure);
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);
/* Returns structure previously at that handle (or nullptr if none) */
std::shared_ptr<TStruct> Free(THandle handle);
void ResetHandles() override;
/* Calls func(THandle, TStruct*) for each handle. Note this holds the
* global lock for the entirety of execution.
*/
template <typename Functor>
void ForEach(Functor func);
private:
std::vector<std::shared_ptr<TStruct>> m_structures;
wpi::mutex m_handleMutex;
@@ -55,7 +63,7 @@ class UnlimitedHandleResource : public HandleBase {
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
THandle UnlimitedHandleResource<THandle, TStruct, enumValue>::Allocate(
std::shared_ptr<TStruct> structure) {
std::lock_guard<wpi::mutex> sync(m_handleMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutex);
size_t i;
for (i = 0; i < m_structures.size(); i++) {
if (m_structures[i] == nullptr) {
@@ -74,19 +82,20 @@ template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
std::shared_ptr<TStruct>
UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
std::lock_guard<wpi::mutex> sync(m_handleMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
return nullptr;
return m_structures[index];
}
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
THandle handle) {
std::shared_ptr<TStruct>
UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(THandle handle) {
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
std::lock_guard<wpi::mutex> sync(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
m_structures[index].reset();
std::lock_guard<wpi::mutex> lock(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
return nullptr;
return std::move(m_structures[index]);
}
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
@@ -99,4 +108,19 @@ void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
}
HandleBase::ResetHandles();
}
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
template <typename Functor>
void UnlimitedHandleResource<THandle, TStruct, enumValue>::ForEach(
Functor func) {
std::lock_guard<wpi::mutex> lock(m_handleMutex);
size_t i;
for (i = 0; i < m_structures.size(); i++) {
if (m_structures[i] != nullptr) {
func(static_cast<THandle>(createHandle(i, enumValue, m_version)),
m_structures[i].get());
}
}
}
} // namespace hal

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -63,3 +65,5 @@ void HALSIM_RegisterAccelerometerAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -45,3 +47,5 @@ void HALSIM_RegisterAnalogGyroAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -95,3 +97,5 @@ void HALSIM_RegisterAnalogInAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -38,3 +40,5 @@ void HALSIM_RegisterAnalogOutAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -62,3 +64,5 @@ void HALSIM_RegisterAnalogTriggerAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,78 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "HAL_Value.h"
#include "NotifyListener.h"
typedef void (*HAL_CAN_SendMessageCallback)(const char* name, void* param,
uint32_t messageID,
const uint8_t* data,
uint8_t dataSize, int32_t periodMs,
int32_t* status);
typedef void (*HAL_CAN_ReceiveMessageCallback)(
const char* name, void* param, uint32_t* messageID, uint32_t messageIDMask,
uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, int32_t* status);
typedef void (*HAL_CAN_OpenStreamSessionCallback)(
const char* name, void* param, uint32_t* sessionHandle, uint32_t messageID,
uint32_t messageIDMask, uint32_t maxMessages, int32_t* status);
typedef void (*HAL_CAN_CloseStreamSessionCallback)(const char* name,
void* param,
uint32_t sessionHandle);
typedef void (*HAL_CAN_ReadStreamSessionCallback)(
const char* name, void* param, uint32_t sessionHandle,
struct HAL_CANStreamMessage* messages, uint32_t messagesToRead,
uint32_t* messagesRead, int32_t* status);
typedef void (*HAL_CAN_GetCANStatusCallback)(
const char* name, void* param, float* percentBusUtilization,
uint32_t* busOffCount, uint32_t* txFullCount, uint32_t* receiveErrorCount,
uint32_t* transmitErrorCount, int32_t* status);
#ifdef __cplusplus
extern "C" {
#endif
void HALSIM_ResetCanData(void);
int32_t HALSIM_RegisterCanSendMessageCallback(
HAL_CAN_SendMessageCallback callback, void* param);
void HALSIM_CancelCanSendMessageCallback(int32_t uid);
int32_t HALSIM_RegisterCanReceiveMessageCallback(
HAL_CAN_ReceiveMessageCallback callback, void* param);
void HALSIM_CancelCanReceiveMessageCallback(int32_t uid);
int32_t HALSIM_RegisterCanOpenStreamCallback(
HAL_CAN_OpenStreamSessionCallback callback, void* param);
void HALSIM_CancelCanOpenStreamCallback(int32_t uid);
int32_t HALSIM_RegisterCanCloseStreamCallback(
HAL_CAN_CloseStreamSessionCallback callback, void* param);
void HALSIM_CancelCanCloseStreamCallback(int32_t uid);
int32_t HALSIM_RegisterCanReadStreamCallback(
HAL_CAN_ReadStreamSessionCallback callback, void* param);
void HALSIM_CancelCanReadStreamCallback(int32_t uid);
int32_t HALSIM_RegisterCanGetCANStatusCallback(
HAL_CAN_GetCANStatusCallback callback, void* param);
void HALSIM_CancelCanGetCANStatusCallback(int32_t uid);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -59,3 +61,5 @@ void HALSIM_RegisterDIOAllCallbacks(int32_t index, HAL_NotifyCallback callback,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -45,3 +47,5 @@ void HALSIM_RegisterDigitalPWMAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More