Compare commits

...

76 Commits

Author SHA1 Message Date
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
551 changed files with 12911 additions and 7032 deletions

View File

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

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

@@ -8,7 +8,7 @@ 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']
'-Wno-unused-parameter', '-Wno-error=deprecated-declarations', '-fPIC', '-rdynamic', '-pthread']
def linuxLinkerArgs = ['-rdynamic', '-pthread']
def linuxReleaseCompilerArgs = ['-O2']
def linuxDebugCompilerArgs = ['-O0']

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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -19,10 +19,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 +56,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 +69,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 +125,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 +154,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 +177,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 +194,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 +207,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 +218,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 +242,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 +269,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 +278,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) {
@@ -303,7 +316,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 +344,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 +377,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 +405,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 +444,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 +472,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 +505,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 +530,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

@@ -22,31 +22,36 @@
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;
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
/**
* 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 +104,16 @@ void initializeDigital(int32_t* status) {
// SPI setup
spiSystem.reset(tSPI::create(status));
digitalSystemsInitialized = true;
// Image 13 requires a SPI select and a strobe to enable SPI CS on MXP.
// Switch to SPI 1, strobe the signal, and then switch back to previous.
bool existingSelect = spiSystem->readAutoSPI1Select(status);
spiSystem->writeAutoSPI1Select(true, status);
spiSystem->strobeAutoForceOne(status);
// Delay enough time to actually trigger strobe
std::this_thread::sleep_for(std::chrono::milliseconds(50));
spiSystem->writeAutoSPI1Select(existingSelect, status);
initialized = true;
}
/**

View File

@@ -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,7 +76,7 @@ struct DigitalPort {
};
extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
kNumDigitalChannels + kNumPWMHeaders>*
digitalChannelHandles;
void initializeDigital(int32_t* status);

View File

@@ -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

@@ -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

@@ -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

@@ -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 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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -15,6 +15,7 @@
#include <array>
#include <atomic>
#include <cstring>
#include <thread>
#include <llvm/raw_ostream.h>
#include <support/mutex.h>
@@ -28,11 +29,11 @@
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;
@@ -46,8 +47,6 @@ std::atomic<int32_t> spiPortCount{0};
static HAL_DigitalHandle digitalHandles[9]{HAL_kInvalidHandle};
extern "C" {
struct SPIAccumulator {
std::atomic<HAL_NotifierHandle> notifier{0};
uint64_t triggerTime;
@@ -73,6 +72,14 @@ struct SPIAccumulator {
};
std::unique_ptr<SPIAccumulator> spiAccumulators[5];
namespace hal {
namespace init {
void InitializeSPI() {}
} // namespace init
} // namespace hal
extern "C" {
static void CommonSPIPortInit(int32_t* status) {
// All false cases will set
if (spiPortCount.fetch_add(1) == 0) {
@@ -97,7 +104,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]);
@@ -272,7 +279,7 @@ int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* 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);
}
@@ -297,7 +304,7 @@ int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
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);
}
@@ -324,7 +331,7 @@ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
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);
}
@@ -342,7 +349,7 @@ void HAL_CloseSPI(HAL_SPIPort port) {
HAL_FreeSPIAccumulator(port, &status);
{
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
close(HAL_GetSPIHandle(port));
}
@@ -384,7 +391,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 +416,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 +431,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 +451,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 +471,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 +500,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,13 +522,7 @@ 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);
static void spiAccumulatorProcess(uint64_t currentTime, SPIAccumulator* accum) {
// perform SPI transaction
uint8_t resp_b[4];
HAL_TransactionSPI(accum->port, accum->cmd, resp_b, accum->xferSize);
@@ -564,7 +565,7 @@ static void spiAccumulatorProcess(uint64_t currentTime,
// handle timer slip
if (accum->triggerTime < currentTime)
accum->triggerTime = currentTime + accum->period;
status = 0;
int32_t status = 0;
HAL_UpdateNotifierAlarm(accum->notifier, accum->triggerTime, &status);
}
@@ -594,7 +595,7 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
if (!spiAccumulators[port])
spiAccumulators[port] = std::make_unique<SPIAccumulator>();
SPIAccumulator* accum = spiAccumulators[port].get();
@@ -623,10 +624,18 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
accum->bigEndian = bigEndian;
accum->port = port;
if (!accum->notifier) {
accum->notifier =
HAL_InitializeNotifier(spiAccumulatorProcess, accum, status);
accum->notifier = HAL_InitializeNotifier(status);
accum->triggerTime = HAL_GetFPGATime(status) + period;
if (*status != 0) return;
std::thread thr([=] {
int32_t status2 = 0;
while (status2 == 0) {
uint64_t curTime = HAL_WaitForNotifierAlarm(accum->notifier, &status2);
if (curTime == 0 || status2 != 0) break;
spiAccumulatorProcess(curTime, accum);
}
});
thr.detach();
HAL_UpdateNotifierAlarm(accum->notifier, accum->triggerTime, status);
}
}
@@ -640,7 +649,7 @@ void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -660,7 +669,7 @@ void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -687,7 +696,7 @@ void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center,
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -706,7 +715,7 @@ void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband,
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -724,7 +733,7 @@ int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status) {
return 0;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -744,7 +753,7 @@ int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status) {
return 0;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -767,7 +776,7 @@ int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status) {
return 0;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -810,7 +819,7 @@ void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value,
return;
}
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;

View File

@@ -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

@@ -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

@@ -12,6 +12,12 @@
#include "HAL/Errors.h"
namespace hal {
namespace init {
void InitializeThreads() {}
} // namespace init
} // namespace hal
extern "C" {
/**

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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -17,7 +17,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 {
@@ -74,7 +73,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 +93,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 +107,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 +116,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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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 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

@@ -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

@@ -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

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/DriverStation.h"
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -20,52 +22,52 @@ int32_t HALSIM_RegisterDriverStationEnabledCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelDriverStationEnabledCallback(int32_t uid);
HAL_Bool HALSIM_GetDriverStationEnabled();
HAL_Bool HALSIM_GetDriverStationEnabled(void);
void HALSIM_SetDriverStationEnabled(HAL_Bool enabled);
int32_t HALSIM_RegisterDriverStationAutonomousCallback(
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
void HALSIM_CancelDriverStationAutonomousCallback(int32_t uid);
HAL_Bool HALSIM_GetDriverStationAutonomous();
HAL_Bool HALSIM_GetDriverStationAutonomous(void);
void HALSIM_SetDriverStationAutonomous(HAL_Bool autonomous);
int32_t HALSIM_RegisterDriverStationTestCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelDriverStationTestCallback(int32_t uid);
HAL_Bool HALSIM_GetDriverStationTest();
HAL_Bool HALSIM_GetDriverStationTest(void);
void HALSIM_SetDriverStationTest(HAL_Bool test);
int32_t HALSIM_RegisterDriverStationEStopCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelDriverStationEStopCallback(int32_t uid);
HAL_Bool HALSIM_GetDriverStationEStop();
HAL_Bool HALSIM_GetDriverStationEStop(void);
void HALSIM_SetDriverStationEStop(HAL_Bool eStop);
int32_t HALSIM_RegisterDriverStationFmsAttachedCallback(
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
void HALSIM_CancelDriverStationFmsAttachedCallback(int32_t uid);
HAL_Bool HALSIM_GetDriverStationFmsAttached();
HAL_Bool HALSIM_GetDriverStationFmsAttached(void);
void HALSIM_SetDriverStationFmsAttached(HAL_Bool fmsAttached);
int32_t HALSIM_RegisterDriverStationDsAttachedCallback(
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
void HALSIM_CancelDriverStationDsAttachedCallback(int32_t uid);
HAL_Bool HALSIM_GetDriverStationDsAttached();
HAL_Bool HALSIM_GetDriverStationDsAttached(void);
void HALSIM_SetDriverStationDsAttached(HAL_Bool dsAttached);
int32_t HALSIM_RegisterDriverStationAllianceStationIdCallback(
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
void HALSIM_CancelDriverStationAllianceStationIdCallback(int32_t uid);
HAL_AllianceStationID HALSIM_GetDriverStationAllianceStationId();
HAL_AllianceStationID HALSIM_GetDriverStationAllianceStationId(void);
void HALSIM_SetDriverStationAllianceStationId(
HAL_AllianceStationID allianceStationId);
int32_t HALSIM_RegisterDriverStationMatchTimeCallback(
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
void HALSIM_CancelDriverStationMatchTimeCallback(int32_t uid);
double HALSIM_GetDriverStationMatchTime();
double HALSIM_GetDriverStationMatchTime(void);
void HALSIM_SetDriverStationMatchTime(double matchTime);
void HALSIM_SetJoystickAxes(int32_t joystickNum, const HAL_JoystickAxes* axes);
@@ -86,6 +88,12 @@ void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
void HALSIM_NotifyDriverStationNewData(void);
void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -85,3 +87,5 @@ void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/Types.h"
/** HAL data types. */
@@ -65,3 +67,5 @@ inline HAL_Value MakeDouble(double v) {
value.data.v_double = v;
return value;
}
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -37,3 +39,5 @@ void HALSIM_CancelI2CWriteCallback(int32_t index, int32_t uid);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,8 +7,12 @@
#pragma once
#ifndef __FRC_ROBORIO__
extern "C" {
void HALSIM_WaitForProgramStart(void);
void HALSIM_SetProgramStarted(void);
void HALSIM_RestartTiming(void);
} // extern "C"
#endif

View File

@@ -7,10 +7,35 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include <memory>
#include "MockData/NotifyListenerVector.h"
template <typename VectorType, typename CallbackType>
std::shared_ptr<VectorType> RegisterCallbackImpl(
std::shared_ptr<VectorType> currentVector, const char* name,
CallbackType callback, void* param, int32_t* newUid) {
std::shared_ptr<VectorType> newCallbacks;
if (currentVector == nullptr) {
newCallbacks = std::make_shared<VectorType>(
param, callback, reinterpret_cast<unsigned int*>(newUid));
} else {
newCallbacks = currentVector->emplace_back(
param, callback, reinterpret_cast<unsigned int*>(newUid));
}
return newCallbacks;
}
template <typename VectorType, typename CallbackType>
std::shared_ptr<VectorType> CancelCallbackImpl(
std::shared_ptr<VectorType> currentVector, int32_t uid) {
// Create a copy of the callbacks to erase from
auto newCallbacks = currentVector->erase(uid);
return newCallbacks;
}
std::shared_ptr<hal::NotifyListenerVector> RegisterCallback(
std::shared_ptr<hal::NotifyListenerVector> currentVector, const char* name,
HAL_NotifyCallback callback, void* param, int32_t* newUid);
@@ -42,3 +67,5 @@ std::shared_ptr<hal::ConstBufferListenerVector> CancelCallback(
void InvokeCallback(
std::shared_ptr<hal::ConstBufferListenerVector> currentVector,
const char* name, const uint8_t* buffer, int32_t count);
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL_Value.h"
typedef void (*HAL_NotifyCallback)(const char* name, void* param,
@@ -34,3 +36,5 @@ struct HalCallbackListener {
};
} // namespace hal
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include <memory>
#include <queue>
#include <vector>
@@ -136,3 +138,5 @@ typedef HalCallbackListenerVectorImpl<HAL_ConstBufferCallback>
ConstBufferListenerVector;
} // namespace hal
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -87,3 +89,5 @@ void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -54,3 +56,5 @@ void HALSIM_RegisterPDPAllNonCurrentCallbacks(int32_t index, int32_t channel,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -66,3 +68,5 @@ void HALSIM_RegisterPWMAllCallbacks(int32_t index, HAL_NotifyCallback callback,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -54,3 +56,5 @@ void HALSIM_RegisterRelayAllCallcbaks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -140,3 +142,5 @@ void HALSIM_RegisterRoboRioAllCallbacks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -61,3 +63,5 @@ void HALSIM_RegisterSPIAccelerometerAllCallbcaks(int32_t index,
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -7,6 +7,8 @@
#pragma once
#ifndef __FRC_ROBORIO__
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -50,3 +52,5 @@ int64_t HALSIM_GetSPIGetAccumulatorValue(int32_t index);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -22,7 +22,7 @@ fpga_clock::time_point fpga_clock::now() noexcept {
if (status != 0) {
llvm::errs()
<< "Call to HAL_GetFPGATime failed."
<< "Initialization might have failed. Time will not be correct";
<< "Initialization might have failed. Time will not be correct\n";
llvm::errs().flush();
return epoch();
}

View File

@@ -13,40 +13,39 @@
#include <support/mutex.h>
namespace hal {
static llvm::SmallVector<HandleBase*, 32> globalHandles;
static wpi::mutex& GetGlobalHandleMutex() {
static wpi::mutex globalHandleMutex;
return globalHandleMutex;
static llvm::SmallVector<HandleBase*, 32>* globalHandles;
static wpi::mutex globalHandleMutex;
namespace init {
void InitializeHandlesInternal() {
static llvm::SmallVector<HandleBase*, 32> gH;
globalHandles = &gH;
}
} // namespace init
HandleBase::HandleBase() {
std::lock_guard<wpi::mutex> lock(GetGlobalHandleMutex());
auto index = std::find(globalHandles.begin(), globalHandles.end(), this);
if (index == globalHandles.end()) {
globalHandles.push_back(this);
std::lock_guard<wpi::mutex> lock(globalHandleMutex);
auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
if (index == globalHandles->end()) {
globalHandles->push_back(this);
} else {
*index = this;
}
}
HandleBase::~HandleBase() {
std::lock_guard<wpi::mutex> lock(GetGlobalHandleMutex());
auto index = std::find(globalHandles.begin(), globalHandles.end(), this);
if (index != globalHandles.end()) {
std::lock_guard<wpi::mutex> lock(globalHandleMutex);
auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
if (index != globalHandles->end()) {
*index = nullptr;
}
}
void HandleBase::ResetHandles() {
m_version++;
if (m_version > 255) {
m_version = 0;
}
}
void HandleBase::ResetGlobalHandles() {
std::unique_lock<wpi::mutex> lock(GetGlobalHandleMutex());
for (auto&& i : globalHandles) {
std::unique_lock<wpi::mutex> lock(globalHandleMutex);
for (auto&& i : *globalHandles) {
if (i != nullptr) {
lock.unlock();
i->ResetHandles();
@@ -54,7 +53,6 @@ void HandleBase::ResetGlobalHandles() {
}
}
}
HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module) {
// set last 8 bits, then shift to first 8 bits
HAL_PortHandle handle = static_cast<HAL_PortHandle>(HAL_HandleEnum::Port);
@@ -67,7 +65,6 @@ HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module) {
handle += channel;
return handle;
}
HAL_PortHandle createPortHandleForSPI(uint8_t channel) {
// set last 8 bits, then shift to first 8 bits
HAL_PortHandle handle = static_cast<HAL_PortHandle>(HAL_HandleEnum::Port);
@@ -82,7 +79,6 @@ HAL_PortHandle createPortHandleForSPI(uint8_t channel) {
handle += channel;
return handle;
}
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
int16_t version) {
if (index < 0) return HAL_kInvalidHandle;

View File

@@ -11,6 +11,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeAccelerometer() {}
} // namespace init
} // namespace hal
extern "C" {
void HAL_SetAccelerometerActive(HAL_Bool active) {
SimAccelerometerData[0].SetActive(active);

View File

@@ -12,10 +12,16 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeAnalogAccumulator() {}
} // namespace init
} // namespace hal
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;
@@ -27,7 +33,7 @@ HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
}
void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -42,7 +48,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;
@@ -54,7 +60,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;
@@ -64,7 +70,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;
@@ -74,7 +80,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;
@@ -84,7 +90,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;
@@ -94,7 +100,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

@@ -26,8 +26,18 @@ struct AnalogGyro {
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>
agH;
analogGyroHandles = &agH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
@@ -42,13 +52,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;
@@ -67,8 +77,8 @@ void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
}
void HAL_FreeAnalogGyro(HAL_GyroHandle handle) {
auto gyro = analogGyroHandles.Get(handle);
analogGyroHandles.Free(handle);
auto gyro = analogGyroHandles->Get(handle);
analogGyroHandles->Free(handle);
if (gyro == nullptr) return;
SimAnalogGyroData[gyro->index].SetInitialized(false);
}
@@ -86,7 +96,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;
@@ -106,7 +116,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;
@@ -116,7 +126,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;

View File

@@ -14,6 +14,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeAnalogInput() {}
} // namespace init
} // namespace hal
extern "C" {
HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
int32_t* status) {
@@ -23,13 +29,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;
@@ -48,9 +54,9 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
return handle;
}
void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
auto port = analogInputHandles.Get(analogPortHandle);
auto port = analogInputHandles->Get(analogPortHandle);
// no status, so no need to check for a proper free.
analogInputHandles.Free(analogPortHandle);
analogInputHandles->Free(analogPortHandle);
if (port == nullptr) return;
SimAnalogInData[port->channel].SetInitialized(false);
SimAnalogInData[port->channel].SetAccumulatorInitialized(false);
@@ -68,7 +74,7 @@ void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status) {
double HAL_GetAnalogSampleRate(int32_t* status) { return kDefaultSampleRate; }
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;
@@ -78,7 +84,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 0;
@@ -88,7 +94,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;
@@ -98,7 +104,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 0;
@@ -108,7 +114,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;
@@ -140,7 +146,7 @@ int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
}
double HAL_GetAnalogVoltage(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.0;
@@ -150,7 +156,7 @@ double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
}
double HAL_GetAnalogAverageVoltage(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.0;

View File

@@ -12,6 +12,16 @@
namespace hal {
IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort, kNumAnalogInputs,
HAL_HandleEnum::AnalogInput>
analogInputHandles;
HAL_HandleEnum::AnalogInput>* analogInputHandles;
} // namespace hal
namespace hal {
namespace init {
void InitializeAnalogInternal() {
static IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
aiH;
analogInputHandles = &aiH;
}
} // namespace init
} // namespace hal

View File

@@ -1,36 +1,36 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 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 <stdint.h>
#include <memory>
#include "HAL/Ports.h"
#include "HAL/handles/IndexedHandleResource.h"
#include "PortsInternal.h"
namespace hal {
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};
struct AnalogPort {
uint8_t channel;
bool isAccumulator;
};
extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
analogInputHandles;
int32_t GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
int32_t* status);
} // namespace hal
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 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 <stdint.h>
#include <memory>
#include "HAL/Ports.h"
#include "HAL/handles/IndexedHandleResource.h"
#include "PortsInternal.h"
namespace hal {
constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock
constexpr int32_t kDefaultOversampleBits = 0;
constexpr int32_t kDefaultAverageBits = 7;
constexpr double kDefaultSampleRate = 50000.0;
static constexpr uint32_t kAccumulatorChannels[] = {0, 1};
struct AnalogPort {
uint8_t channel;
bool isAccumulator;
};
extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
analogInputHandles;
int32_t GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
int32_t* status);
} // namespace hal

View File

@@ -22,9 +22,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" {
HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
int32_t* status) {
@@ -34,12 +45,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;
@@ -54,9 +66,9 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
// no status, so no need to check for a proper free.
auto port = analogOutputHandles.Get(analogOutputHandle);
auto port = analogOutputHandles->Get(analogOutputHandle);
if (port == nullptr) return;
analogOutputHandles.Free(analogOutputHandle);
analogOutputHandles->Free(analogOutputHandle);
SimAnalogOutData[port->channel].SetInitialized(false);
}
@@ -66,7 +78,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;
@@ -77,7 +89,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

@@ -27,23 +27,54 @@ struct AnalogTrigger {
using namespace hal;
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
int32_t hal::GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
int32_t* status) {
auto trigger = analogTriggerHandles->Get(handle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return -1;
}
auto analog_port = analogInputHandles->Get(trigger->analogHandle);
if (analog_port == nullptr) {
*status = HAL_HANDLE_ERROR;
return -1;
}
return analog_port->channel;
}
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,8 +92,8 @@ HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
int32_t* status) {
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
analogTriggerHandles.Free(analogTriggerHandle);
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
analogTriggerHandles->Free(analogTriggerHandle);
if (trigger == nullptr) return;
SimAnalogTriggerData[trigger->index].SetInitialized(false);
// caller owns the analog input handle.
@@ -78,27 +109,10 @@ static double GetAnalogValueToVoltage(
return voltage;
}
int32_t hal::GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
int32_t* status) {
auto trigger = analogTriggerHandles.Get(handle);
if (trigger == nullptr) {
*status = HAL_HANDLE_ERROR;
return -1;
}
auto analog_port = analogInputHandles.Get(trigger->analogHandle);
if (analog_port == nullptr) {
*status = HAL_HANDLE_ERROR;
return -1;
}
return analog_port->channel;
}
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;
@@ -120,7 +134,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;
@@ -134,7 +148,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;
@@ -153,7 +167,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;
@@ -172,7 +186,7 @@ void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
}
static double GetTriggerValue(AnalogTrigger* trigger, int32_t* status) {
auto analogIn = analogInputHandles.Get(trigger->analogHandle);
auto analogIn = analogInputHandles->Get(trigger->analogHandle);
if (analogIn == nullptr) {
// Returning HAL Handle Error, but going to ignore lower down
*status = HAL_HANDLE_ERROR;
@@ -184,7 +198,7 @@ static double GetTriggerValue(AnalogTrigger* trigger, int32_t* status) {
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;
@@ -204,7 +218,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;
@@ -242,3 +256,4 @@ HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
return false;
}
}
} // extern "C"

View File

@@ -7,22 +7,49 @@
#include "HAL/CAN.h"
#include "MockData/CanDataInternal.h"
using namespace hal;
namespace hal {
namespace init {
void InitializeCAN() {}
} // namespace init
} // namespace hal
extern "C" {
void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,
uint8_t dataSize, int32_t periodMs, int32_t* status) {}
uint8_t dataSize, int32_t periodMs, int32_t* status) {
SimCanData->SendMessage(messageID, data, dataSize, periodMs, status);
}
void HAL_CAN_ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
uint8_t* data, uint8_t* dataSize,
uint32_t* timeStamp, int32_t* status) {}
uint32_t* timeStamp, int32_t* status) {
SimCanData->ReceiveMessage(messageID, messageIDMask, data, dataSize,
timeStamp, status);
}
void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
uint32_t messageIDMask, uint32_t maxMessages,
int32_t* status) {}
void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {}
int32_t* status) {
SimCanData->OpenStreamSession(sessionHandle, messageID, messageIDMask,
maxMessages, status);
}
void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {
SimCanData->CloseStreamSession(sessionHandle);
}
void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
struct HAL_CANStreamMessage* messages,
uint32_t messagesToRead, uint32_t* messagesRead,
int32_t* status) {}
int32_t* status) {
SimCanData->ReadStreamSession(sessionHandle, messages, messagesToRead,
messagesRead, status);
}
void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
uint32_t* txFullCount, uint32_t* receiveErrorCount,
uint32_t* transmitErrorCount, int32_t* status) {}
uint32_t* transmitErrorCount, int32_t* status) {
SimCanData->GetCANStatus(percentBusUtilization, busOffCount, txFullCount,
receiveErrorCount, transmitErrorCount, status);
}
} // extern "C"

View File

@@ -1,115 +1,121 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 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. */
/*----------------------------------------------------------------------------*/
#include "HAL/Compressor.h"
#include "HAL/Errors.h"
#include "HAL/handles/HandlesInternal.h"
#include "MockData/PCMDataInternal.h"
#include "PortsInternal.h"
using namespace hal;
extern "C" {
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
// As compressors can have unlimited objects, just create a
// handle with the module number as the index.
SimPCMData[module].SetCompressorInitialized(true);
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
HAL_HandleEnum::Compressor, 0);
}
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
return module < kNumPCMModules && module >= 0;
}
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].GetCompressorOn();
}
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
HAL_Bool value, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return;
}
SimPCMData[index].SetClosedLoopEnabled(value);
}
HAL_Bool HAL_GetCompressorClosedLoopControl(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].GetClosedLoopEnabled();
}
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].GetPressureSwitch();
}
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return 0;
}
return SimPCMData[index].GetCompressorCurrent();
}
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorShortedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorNotConnectedFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
} // extern "C"
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2017 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. */
/*----------------------------------------------------------------------------*/
#include "HAL/Compressor.h"
#include "HAL/Errors.h"
#include "HAL/handles/HandlesInternal.h"
#include "MockData/PCMDataInternal.h"
#include "PortsInternal.h"
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) {
// As compressors can have unlimited objects, just create a
// handle with the module number as the index.
SimPCMData[module].SetCompressorInitialized(true);
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
HAL_HandleEnum::Compressor, 0);
}
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
return module < kNumPCMModules && module >= 0;
}
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].GetCompressorOn();
}
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
HAL_Bool value, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return;
}
SimPCMData[index].SetClosedLoopEnabled(value);
}
HAL_Bool HAL_GetCompressorClosedLoopControl(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].GetClosedLoopEnabled();
}
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].GetPressureSwitch();
}
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return 0;
}
return SimPCMData[index].GetCompressorCurrent();
}
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorShortedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorNotConnectedFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
} // extern "C"

View File

@@ -11,6 +11,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeConstants() {}
} // namespace init
} // namespace hal
extern "C" {
int32_t HAL_GetSystemClockTicksPerMicrosecond(void) {
return kSystemClockTicksPerMicrosecond;

View File

@@ -16,8 +16,18 @@
namespace hal {
LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
HAL_HandleEnum::Counter>
counterHandles;
HAL_HandleEnum::Counter>* counterHandles;
} // namespace hal
namespace hal {
namespace init {
void InitializeCounter() {
static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
HAL_HandleEnum::Counter>
cH;
counterHandles = &cH;
}
} // namespace init
} // namespace hal
extern "C" {

View File

@@ -18,7 +18,6 @@ struct Counter {
};
extern LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
HAL_HandleEnum::Counter>
counterHandles;
HAL_HandleEnum::Counter>* counterHandles;
} // namespace hal

View File

@@ -19,9 +19,21 @@
using namespace hal;
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" {
/**
@@ -38,12 +50,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;
@@ -63,9 +75,9 @@ 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;
SimDIOData[port->channel].SetInitialized(true);
}
@@ -77,13 +89,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;
@@ -102,8 +114,8 @@ HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
* allocateDigitalPWM()
*/
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
auto port = digitalPWMHandles.Get(pwmGenerator);
digitalPWMHandles.Free(pwmGenerator);
auto port = digitalPWMHandles->Get(pwmGenerator);
digitalPWMHandles->Free(pwmGenerator);
if (port == nullptr) return;
int32_t id = *port;
SimDigitalPWMData[id].SetInitialized(false);
@@ -137,7 +149,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;
@@ -156,7 +168,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;
@@ -175,7 +187,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;
@@ -194,7 +206,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;
@@ -213,7 +225,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;
@@ -234,7 +246,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;
@@ -248,7 +260,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;
@@ -276,7 +288,7 @@ 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;
@@ -294,7 +306,7 @@ 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;

View File

@@ -15,12 +15,19 @@
namespace hal {
bool digitalSystemsInitialized = false;
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
/**
* Map DIO channel numbers from their physical number (10 to 26) to their
* position in the bit field.
@@ -69,7 +76,7 @@ bool remapDigitalSource(HAL_Handle digitalSourceHandle,
}
int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status) {
auto digital = digitalChannelHandles.Get(handle, HAL_HandleEnum::DIO);
auto digital = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
if (digital == nullptr) {
*status = HAL_HANDLE_ERROR;
return -1;

View File

@@ -67,7 +67,7 @@ struct DigitalPort {
};
extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
kNumDigitalChannels + kNumPWMHeaders>*
digitalChannelHandles;
bool remapDigitalSource(HAL_Handle digitalSourceHandle,

View File

@@ -23,10 +23,19 @@
#include "MockData/MockHooks.h"
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 InitializeDriverStation() {
static wpi::condition_variable nddaC;
newDSDataAvailableCond = &nddaC;
}
} // namespace init
} // namespace hal
using namespace hal;
extern "C" {
@@ -85,33 +94,33 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
}
int32_t HAL_GetControlWord(HAL_ControlWord* controlWord) {
controlWord->enabled = SimDriverStationData.GetEnabled();
controlWord->autonomous = SimDriverStationData.GetAutonomous();
controlWord->test = SimDriverStationData.GetTest();
controlWord->eStop = SimDriverStationData.GetEStop();
controlWord->fmsAttached = SimDriverStationData.GetFmsAttached();
controlWord->dsAttached = SimDriverStationData.GetDsAttached();
controlWord->enabled = SimDriverStationData->GetEnabled();
controlWord->autonomous = SimDriverStationData->GetAutonomous();
controlWord->test = SimDriverStationData->GetTest();
controlWord->eStop = SimDriverStationData->GetEStop();
controlWord->fmsAttached = SimDriverStationData->GetFmsAttached();
controlWord->dsAttached = SimDriverStationData->GetDsAttached();
return 0;
}
HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
*status = 0;
return SimDriverStationData.GetAllianceStationId();
return SimDriverStationData->GetAllianceStationId();
}
int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes) {
SimDriverStationData.GetJoystickAxes(joystickNum, axes);
SimDriverStationData->GetJoystickAxes(joystickNum, axes);
return 0;
}
int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
SimDriverStationData.GetJoystickPOVs(joystickNum, povs);
SimDriverStationData->GetJoystickPOVs(joystickNum, povs);
return 0;
}
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
HAL_JoystickButtons* buttons) {
SimDriverStationData.GetJoystickButtons(joystickNum, buttons);
SimDriverStationData->GetJoystickButtons(joystickNum, buttons);
return 0;
}
/**
@@ -127,25 +136,25 @@ int32_t HAL_GetJoystickButtons(int32_t joystickNum,
*/
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
HAL_JoystickDescriptor* desc) {
SimDriverStationData.GetJoystickDescriptor(joystickNum, desc);
SimDriverStationData->GetJoystickDescriptor(joystickNum, desc);
return 0;
}
HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum) {
HAL_JoystickDescriptor desc;
SimDriverStationData.GetJoystickDescriptor(joystickNum, &desc);
SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
return desc.isXbox;
}
int32_t HAL_GetJoystickType(int32_t joystickNum) {
HAL_JoystickDescriptor desc;
SimDriverStationData.GetJoystickDescriptor(joystickNum, &desc);
SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
return desc.type;
}
char* HAL_GetJoystickName(int32_t joystickNum) {
HAL_JoystickDescriptor desc;
SimDriverStationData.GetJoystickDescriptor(joystickNum, &desc);
SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
size_t len = std::strlen(desc.name);
char* name = static_cast<char*>(std::malloc(len + 1));
std::strncpy(name, desc.name, len);
@@ -159,22 +168,22 @@ int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) { return 0; }
int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble) {
SimDriverStationData.SetJoystickOutputs(joystickNum, outputs, leftRumble,
rightRumble);
SimDriverStationData->SetJoystickOutputs(joystickNum, outputs, leftRumble,
rightRumble);
return 0;
}
double HAL_GetMatchTime(int32_t* status) {
return SimDriverStationData.GetMatchTime();
return SimDriverStationData->GetMatchTime();
}
int HAL_GetMatchInfo(HAL_MatchInfo* info) {
SimDriverStationData.GetMatchInfo(info);
SimDriverStationData->GetMatchInfo(info);
return 0;
}
void HAL_FreeMatchInfo(HAL_MatchInfo* info) {
SimDriverStationData.FreeMatchInfo(info);
SimDriverStationData->FreeMatchInfo(info);
}
void HAL_ObserveUserProgramStarting(void) { HALSIM_SetProgramStarted(); }
@@ -199,7 +208,9 @@ void HAL_ObserveUserProgramTest(void) {
static pthread_key_t lastCountKey;
static pthread_once_t lastCountKeyOnce = PTHREAD_ONCE_INIT;
static void InitLastCountKey() { pthread_key_create(&lastCountKey, std::free); }
static void InitLastCountKey(void) {
pthread_key_create(&lastCountKey, std::free);
}
#endif
bool HAL_IsNewControlData(void) {
@@ -247,12 +258,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;
@@ -268,7 +279,7 @@ static int32_t newDataOccur(uint32_t refNum) {
std::lock_guard<wpi::mutex> lock(newDSDataAvailableMutex);
// Nofify all threads
newDSDataAvailableCounter++;
newDSDataAvailableCond.notify_all();
newDSDataAvailableCond->notify_all();
return 0;
}
@@ -287,7 +298,7 @@ void HAL_InitializeDriverStation(void) {
// Second check in case another thread was waiting
if (initialized) return;
SimDriverStationData.ResetData();
SimDriverStationData->ResetData();
initialized = true;
}

View File

@@ -29,12 +29,26 @@ struct Empty {};
static LimitedHandleResource<HAL_EncoderHandle, Encoder,
kNumEncoders + kNumCounters,
HAL_HandleEnum::Encoder>
encoderHandles;
HAL_HandleEnum::Encoder>* encoderHandles;
static LimitedHandleResource<HAL_FPGAEncoderHandle, Empty, kNumEncoders,
HAL_HandleEnum::FPGAEncoder>
fpgaEncoderHandles;
HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles;
namespace hal {
namespace init {
void InitializeEncoder() {
static LimitedHandleResource<HAL_FPGAEncoderHandle, Empty, kNumEncoders,
HAL_HandleEnum::FPGAEncoder>
feH;
fpgaEncoderHandles = &feH;
static LimitedHandleResource<HAL_EncoderHandle, Encoder,
kNumEncoders + kNumCounters,
HAL_HandleEnum::Encoder>
eH;
encoderHandles = &eH;
}
} // namespace init
} // namespace hal
extern "C" {
HAL_EncoderHandle HAL_InitializeEncoder(
@@ -45,21 +59,21 @@ HAL_EncoderHandle HAL_InitializeEncoder(
HAL_Handle nativeHandle = HAL_kInvalidHandle;
if (encodingType == HAL_EncoderEncodingType::HAL_Encoder_k4X) {
// k4x, allocate encoder
nativeHandle = fpgaEncoderHandles.Allocate();
nativeHandle = fpgaEncoderHandles->Allocate();
} else {
// k2x or k1x, allocate counter
nativeHandle = counterHandles.Allocate();
nativeHandle = counterHandles->Allocate();
}
if (nativeHandle == HAL_kInvalidHandle) {
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto handle = encoderHandles.Allocate();
auto handle = encoderHandles->Allocate();
if (handle == HAL_kInvalidHandle) {
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
auto encoder = encoderHandles.Get(handle);
auto encoder = encoderHandles->Get(handle);
if (encoder == nullptr) { // would only occur on thread issue
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -75,13 +89,13 @@ HAL_EncoderHandle HAL_InitializeEncoder(
}
void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
auto encoder = encoderHandles.Get(encoderHandle);
encoderHandles.Free(encoderHandle);
auto encoder = encoderHandles->Get(encoderHandle);
encoderHandles->Free(encoderHandle);
if (encoder == nullptr) return;
if (isHandleType(encoder->nativeHandle, HAL_HandleEnum::FPGAEncoder)) {
fpgaEncoderHandles.Free(encoder->nativeHandle);
fpgaEncoderHandles->Free(encoder->nativeHandle);
} else if (isHandleType(encoder->nativeHandle, HAL_HandleEnum::Counter)) {
counterHandles.Free(encoder->nativeHandle);
counterHandles->Free(encoder->nativeHandle);
}
SimEncoderData[encoder->index].SetInitialized(false);
}
@@ -113,7 +127,7 @@ static inline double DecodingScaleFactor(Encoder* encoder) {
}
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;
@@ -122,7 +136,7 @@ int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
return SimEncoderData[encoder->index].GetCount();
}
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;
@@ -133,7 +147,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;
@@ -142,7 +156,7 @@ int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
return EncodingScaleFactor(encoder.get());
}
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;
@@ -153,7 +167,7 @@ void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
SimEncoderData[encoder->index].SetReset(true);
}
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;
@@ -163,7 +177,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;
@@ -173,7 +187,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;
@@ -184,7 +198,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;
@@ -194,7 +208,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;
@@ -203,7 +217,7 @@ double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
return SimEncoderData[encoder->index].GetCount() * encoder->distancePerPulse;
}
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;
@@ -213,7 +227,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;
@@ -229,7 +243,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;
@@ -244,7 +258,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;
@@ -254,7 +268,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;
@@ -264,7 +278,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;
@@ -282,7 +296,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;
@@ -293,7 +307,7 @@ int32_t HAL_GetEncoderFPGAIndex(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.0;
@@ -304,7 +318,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.0;
@@ -315,7 +329,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

View File

@@ -33,6 +33,12 @@
#define DLCLOSE dlclose
#endif
namespace hal {
namespace init {
void InitializeExtensions() {}
} // namespace init
} // namespace hal
extern "C" {
int HAL_LoadOneExtension(const char* library) {

View File

@@ -14,11 +14,66 @@
#include "HAL/Errors.h"
#include "HAL/Extensions.h"
#include "HAL/handles/HandlesInternal.h"
#include "HALInitializer.h"
#include "MockData/RoboRioDataInternal.h"
#include "MockHooksInternal.h"
using namespace hal;
namespace hal {
namespace init {
void InitializeHAL() {
InitializeHandlesInternal();
InitializeAccelerometerData();
InitializeAnalogGyroData();
InitializeAnalogInData();
InitializeAnalogOutData();
InitializeAnalogTriggerData();
InitializeCanData();
InitializeDigitalPWMData();
InitializeDIOData();
InitializeDriverStationData();
InitializeEncoderData();
InitializeI2CData();
InitializePCMData();
InitializePDPData();
InitializePWMData();
InitializeRelayData();
InitializeRoboRioData();
InitializeSPIAccelerometerData();
InitializeSPIData();
InitializeAccelerometer();
InitializeAnalogAccumulator();
InitializeAnalogGyro();
InitializeAnalogInput();
InitializeAnalogInternal();
InitializeAnalogOutput();
InitializeCAN();
InitializeCompressor();
InitializeConstants();
InitializeCounter();
InitializeDigitalInternal();
InitializeDIO();
InitializeDriverStation();
InitializeExtensions();
InitializeI2C();
InitializeInterrupts();
InitializeMockHooks();
InitializeNotifier();
InitializeOSSerialPort();
InitializePDP();
InitializePorts();
InitializePower();
InitializePWM();
InitializeRelay();
InitializeSerialPort();
InitializeSolenoid();
InitializeSPI();
InitializeThreads();
}
} // namespace init
} // namespace hal
extern "C" {
HAL_PortHandle HAL_GetPort(int32_t channel) {
@@ -149,7 +204,7 @@ const char* HAL_GetErrorMessage(int32_t code) {
/**
* Returns the runtime type of this HAL
*/
HAL_RuntimeType HAL_GetRuntimeType() { return HAL_Mock; }
HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
/**
* Return the FPGA Version number.
@@ -206,6 +261,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();
llvm::outs().SetUnbuffered();
if (HAL_LoadExtensions() < 0) return false;
hal::RestartTiming();

View File

@@ -0,0 +1,62 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 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 InitializeHandlesInternal();
extern void InitializeAccelerometerData();
extern void InitializeAnalogGyroData();
extern void InitializeAnalogInData();
extern void InitializeAnalogOutData();
extern void InitializeAnalogTriggerData();
extern void InitializeCanData();
extern void InitializeDigitalPWMData();
extern void InitializeDIOData();
extern void InitializeDriverStationData();
extern void InitializeEncoderData();
extern void InitializeI2CData();
extern void InitializePCMData();
extern void InitializePDPData();
extern void InitializePWMData();
extern void InitializeRelayData();
extern void InitializeRoboRioData();
extern void InitializeSPIAccelerometerData();
extern void InitializeSPIData();
extern void InitializeAccelerometer();
extern void InitializeAnalogAccumulator();
extern void InitializeAnalogGyro();
extern void InitializeAnalogInput();
extern void InitializeAnalogInternal();
extern void InitializeAnalogOutput();
extern void InitializeCAN();
extern void InitializeCompressor();
extern void InitializeConstants();
extern void InitializeCounter();
extern void InitializeDigitalInternal();
extern void InitializeDIO();
extern void InitializeDriverStation();
extern void InitializeExtensions();
extern void InitializeHAL();
extern void InitializeI2C();
extern void InitializeInterrupts();
extern void InitializeMockHooks();
extern void InitializeNotifier();
extern void InitializeOSSerialPort();
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();
} // namespace init
} // namespace hal

View File

@@ -11,6 +11,12 @@
using namespace hal;
namespace hal {
namespace init {
void InitializeI2C() {}
} // namespace init
} // namespace hal
extern "C" {
void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
SimI2CData[port].SetInitialized(true);

View File

@@ -60,23 +60,37 @@ struct SynchronousWaitData {
} // namespace
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
HAL_HandleEnum::Interrupt>
interruptHandles;
HAL_HandleEnum::Interrupt>* interruptHandles;
typedef HAL_Handle SynchronousWaitDataHandle;
static UnlimitedHandleResource<SynchronousWaitDataHandle, SynchronousWaitData,
HAL_HandleEnum::Vendor>
HAL_HandleEnum::Vendor>*
synchronousInterruptHandles;
namespace hal {
namespace init {
void InitializeInterrupts() {
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
HAL_HandleEnum::Interrupt>
iH;
interruptHandles = &iH;
static UnlimitedHandleResource<SynchronousWaitDataHandle, SynchronousWaitData,
HAL_HandleEnum::Vendor>
siH;
synchronousInterruptHandles = &siH;
}
} // 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);
if (anInterrupt == nullptr) { // would only occur on thread issue.
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
@@ -91,8 +105,8 @@ HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
}
void HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status) {
HAL_DisableInterrupts(interruptHandle, status);
auto interrupt = interruptHandles.Get(interruptHandle);
interruptHandles.Free(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
interruptHandles->Free(interruptHandle);
}
static void ProcessInterruptDigitalSynchronous(const char* name, void* param,
@@ -102,9 +116,9 @@ static void ProcessInterruptDigitalSynchronous(const char* name, void* param,
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
SynchronousWaitDataHandle handle =
static_cast<SynchronousWaitDataHandle>(handleTmp);
auto interruptData = synchronousInterruptHandles.Get(handle);
auto interruptData = synchronousInterruptHandles->Get(handle);
if (interruptData == nullptr) return;
auto interrupt = interruptHandles.Get(interruptData->interruptHandle);
auto interrupt = interruptHandles->Get(interruptData->interruptHandle);
if (interrupt == nullptr) return;
// Have a valid interrupt
if (value->type != HAL_Type::HAL_BOOLEAN) return;
@@ -135,9 +149,9 @@ static void ProcessInterruptAnalogSynchronous(const char* name, void* param,
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
SynchronousWaitDataHandle handle =
static_cast<SynchronousWaitDataHandle>(handleTmp);
auto interruptData = synchronousInterruptHandles.Get(handle);
auto interruptData = synchronousInterruptHandles->Get(handle);
if (interruptData == nullptr) return;
auto interrupt = interruptHandles.Get(interruptData->interruptHandle);
auto interrupt = interruptHandles->Get(interruptData->interruptHandle);
if (interrupt == nullptr) return;
// Have a valid interrupt
if (value->type != HAL_Type::HAL_DOUBLE) return;
@@ -168,13 +182,13 @@ static int64_t WaitForInterruptDigital(HAL_InterruptHandle handle,
bool ignorePrevious) {
auto data = std::make_shared<SynchronousWaitData>();
auto dataHandle = synchronousInterruptHandles.Allocate(data);
auto dataHandle = synchronousInterruptHandles->Allocate(data);
if (dataHandle == HAL_kInvalidHandle) {
// Error allocating data
return WaitResult::Timeout;
}
// auto data = synchronousInterruptHandles.Get(dataHandle);
// auto data = synchronousInterruptHandles->Get(dataHandle);
data->waitPredicate = false;
data->interruptHandle = handle;
@@ -216,7 +230,7 @@ static int64_t WaitForInterruptDigital(HAL_InterruptHandle handle,
// Cancel our callback
SimDIOData[digitalIndex].CancelValueCallback(uid);
synchronousInterruptHandles.Free(dataHandle);
synchronousInterruptHandles->Free(dataHandle);
// Check for what to return
if (timedOut) return WaitResult::Timeout;
@@ -236,7 +250,7 @@ static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
bool ignorePrevious) {
auto data = std::make_shared<SynchronousWaitData>();
auto dataHandle = synchronousInterruptHandles.Allocate(data);
auto dataHandle = synchronousInterruptHandles->Allocate(data);
if (dataHandle == HAL_kInvalidHandle) {
// Error allocating data
return WaitResult::Timeout;
@@ -286,7 +300,7 @@ static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
// Cancel our callback
SimAnalogInData[analogIndex].CancelVoltageCallback(uid);
synchronousInterruptHandles.Free(dataHandle);
synchronousInterruptHandles->Free(dataHandle);
// Check for what to return
if (timedOut) return WaitResult::Timeout;
@@ -304,7 +318,7 @@ static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
double timeout, HAL_Bool ignorePrevious,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return WaitResult::Timeout;
@@ -331,7 +345,7 @@ static void ProcessInterruptDigitalAsynchronous(const char* name, void* param,
// convert to uintptr_t first, then to handle
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
HAL_InterruptHandle handle = static_cast<HAL_InterruptHandle>(handleTmp);
auto interrupt = interruptHandles.Get(handle);
auto interrupt = interruptHandles->Get(handle);
if (interrupt == nullptr) return;
// Have a valid interrupt
if (value->type != HAL_Type::HAL_BOOLEAN) return;
@@ -363,7 +377,7 @@ static void ProcessInterruptAnalogAsynchronous(const char* name, void* param,
// convert to intptr_t first, then to handle
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
HAL_InterruptHandle handle = static_cast<HAL_InterruptHandle>(handleTmp);
auto interrupt = interruptHandles.Get(handle);
auto interrupt = interruptHandles->Get(handle);
if (interrupt == nullptr) return;
// Have a valid interrupt
if (value->type != HAL_Type::HAL_DOUBLE) return;
@@ -426,7 +440,7 @@ static void EnableInterruptsAnalog(HAL_InterruptHandle handle,
void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -452,7 +466,7 @@ void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
}
void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -479,7 +493,7 @@ void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
}
double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -489,7 +503,7 @@ double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
}
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
@@ -501,7 +515,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -525,7 +539,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
HAL_InterruptHandlerFunction handler,
void* param, int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
@@ -544,7 +558,7 @@ void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interruptHandle,
void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
auto interrupt = interruptHandles.Get(interruptHandle);
auto interrupt = interruptHandles->Get(interruptHandle);
if (interrupt == nullptr) {
*status = HAL_HANDLE_ERROR;
return;

View File

@@ -7,11 +7,20 @@
#include "../PortsInternal.h"
#include "AccelerometerDataInternal.h"
#include "NotifyCallbackHelpers.h"
#include "MockData/NotifyCallbackHelpers.h"
using namespace hal;
AccelerometerData hal::SimAccelerometerData[1];
namespace hal {
namespace init {
void InitializeAccelerometerData() {
static AccelerometerData sad[1];
::hal::SimAccelerometerData = sad;
}
} // namespace init
} // namespace hal
AccelerometerData* hal::SimAccelerometerData;
void AccelerometerData::ResetData() {
m_active = false;
m_activeCallbacks = nullptr;

View File

@@ -69,5 +69,5 @@ class AccelerometerData {
std::atomic<double> m_z{0.0};
std::shared_ptr<NotifyListenerVector> m_zCallbacks = nullptr;
};
extern AccelerometerData SimAccelerometerData[];
extern AccelerometerData* SimAccelerometerData;
} // namespace hal

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