Compare commits

...

75 Commits

Author SHA1 Message Date
Thad House
cd1dbb1e3a Adds a const buffer listener (#742)
Replaces need for const_cast in SPI and I2C functions
2017-11-17 10:01:49 -08:00
Peter Johnson
a20474bfc7 Update sensors to not use direct byte buffers. 2017-11-17 09:36:57 -08:00
Peter Johnson
479d0beb5a SerialPort: Use byte[] instead of ByteBuffer in JNI. 2017-11-17 09:36:57 -08:00
Peter Johnson
b93aa176d6 AnalogInput: Remove byte buffer usage. 2017-11-17 09:36:57 -08:00
Peter Johnson
9021b37fd2 I2C: Provide byte[] JNI interfaces.
This avoids a direct byte buffer allocation on every read/write/transaction
on the byte[] variants.

Changes HAL I2C interfaces to use const for dataToSend.
2017-11-17 09:36:57 -08:00
Peter Johnson
6307d41002 SPI: Provide byte[] JNI interfaces.
This avoids a direct byte buffer allocation on every read/write/transaction
for the byte[] variants.

Also change spiGetAccumulatorOutput() to directly set the AccumulatorResult
object, avoiding a ByteBuffer allocation.

Changes HAL SPI interfaces to use const for dataToSend.

Fixes #733.
2017-11-17 09:36:57 -08:00
Peter Johnson
df7c1389de Remove ni-libraries libi2c and libspi. 2017-11-16 23:01:28 -08:00
Peter Johnson
6accc31ee7 HAL: implement I2C and SPI directly instead of using i2clib and spilib.
This reduces library dependencies, improves error handling, and makes
future enhancements easier.
2017-11-16 23:01:28 -08:00
Thad House
f56ec10bcf Only return lower 32 bits of FPGA time (#741)
Works around an NI bug in image 10.
2017-11-16 20:52:50 -08:00
Tyler Veness
e5e6d6a193 Ran formatter based on styleguide#95 (#737) 2017-11-16 01:05:20 -08:00
Tyler Veness
c663d7cd16 Reflowed comments and removed commented out code (#735) 2017-11-16 00:33:51 -08:00
Tyler Veness
1e8d18b328 Upgrade Travis CI Python version to 3.5 (#740) 2017-11-16 00:19:16 -08:00
Peter Johnson
c2d95db3ab Fix PreferencesTest. (#739) 2017-11-15 23:56:17 -08:00
Thad House
dd7563376b Force load OpenCV and cscore libraries on program initialization (#716)
Fixes bugs where Mat's are initialized before anything cscore was
called.
2017-11-14 22:04:53 -08:00
Tyler Veness
14fcf3f2f0 Simplified PIDController integration logic (#645)
A clamp() helper function was written based on C++17's std::clamp().
2017-11-13 22:28:55 -08:00
Peter Johnson
020ee227d2 Move ctre headers to hal/src so they aren't user-visible. (#728)
Also removes ctre_frames.h entirely since it's not used.

Fixes #683.
2017-11-13 22:23:18 -08:00
Peter Johnson
4d559f3856 Use wpi::mutex instead of std::mutex. (#730)
This uses a priority-aware mutex on Linux platforms.

Fixes #729.
2017-11-13 09:51:48 -08:00
Thad House
35d68d2a34 Adds ability to simulate joysticks and event info (#727)
Thanks @pjreiniger for the initiali implementation and work on this.
2017-11-12 19:33:43 -08:00
Peter Johnson
7007725d9f SerialHelper: Check error_code to prevent infinite loop. (#725) 2017-11-11 22:13:59 -08:00
Tyler Veness
0c83cad70c Upgraded clang-format to 5.0 (#431) 2017-11-11 22:09:51 -08:00
sciencewhiz
0001047b8b Add NidecBrushless to WPILib.h (#724) 2017-11-11 16:35:43 -08:00
Thad House
c885251367 Fixes HALSim_Print build to be the standardized pattern (#721)
Now publishes in zips, and with proper artifacts.

The code files just moved, and no changes.
2017-11-10 19:26:33 -08:00
Tyler Veness
42096fac3f Ran formatter (#722) 2017-11-10 18:29:27 -08:00
sciencewhiz
6be9e69d13 Switch Command Templates to TimedRobot (#719) 2017-11-09 20:08:41 -08:00
Thad House
7bbd13d914 Adds match specific calls to Java and C++ (#720)
Uses caching, matching the joystick calls.
2017-11-09 19:59:29 -08:00
Thad House
2225c4fee2 Fixes warnings for casts in sim interrupt functions (#718) 2017-11-09 14:01:24 -08:00
Tyler Veness
7efab4c43a Replaced ternary operators with if statements (#346)
Instances of the ternary operator were replaced with if statements to make the code base more consistent.
2017-11-08 23:44:03 -08:00
Thad House
c8e44256ef Uses NI provided function for SetOccurDataRef rather then importing the symbol ourselves. (#714) 2017-11-08 23:41:16 -08:00
Peter Johnson
f3cd883c5c Add Nidec Brushless motor. (#705) 2017-11-08 23:40:01 -08:00
Thad House
f34c736fb2 Adds warning prints to native library builds (#710)
Can be disabled with -PskipWarningPrints
2017-11-08 23:14:21 -08:00
Tyler Veness
1276489961 Removed uses of deprecated functions (#709) 2017-11-08 21:29:29 -08:00
Tyler Veness
8b2e656bde Fixed Java velocity PID not calculating result when P = 0 (#717) 2017-11-08 21:28:09 -08:00
Thad House
6e9d1f55c6 Updates image to 2018 v10 image (#713) 2017-11-08 11:26:11 -08:00
Thad House
f4dce9e608 Fixes receive size in Java I2C (#715)
Allows underrun, which matches c++ behavior.

Fixes #711
2017-11-07 18:43:23 -08:00
Thad House
b9aabc71b0 Fixes publishing basenames for examples to make combiner script work. (#712) 2017-11-07 14:54:17 -08:00
Jaci R
0d54772362 Add IDEA plugin to root project (#707) 2017-11-05 19:57:53 -08:00
Tyler Veness
faf134a674 C++ examples no longer use deprecated APIs (#703) 2017-11-05 19:39:47 -08:00
Thad House
c24e755409 Fixes java example publishing and xml file (#706) 2017-11-04 10:09:41 -07:00
Thad House
bee9f1cb17 Adds header task to print out all headers (#704)
Will be used to create a generator for IDE's to get include paths.
2017-11-03 22:50:06 -07:00
Tyler Veness
45d48d6b5a Cleaned up C++ examples (#672) 2017-11-03 13:22:56 -07:00
Peter Johnson
6401aa1fde SerialHelper: Use llvm path functions instead of popen. (#702)
This avoids a fork that causes an out-of-memory error in Java.

Depends on wpilibsuite/wpiutil#43
2017-11-03 12:30:56 -07:00
Thad House
6af4940c22 Adds HAL calls for match data from DS (#691) 2017-11-01 21:58:44 -07:00
Sam Carlberg
237b2df82f Add .type metadata to preferences table (#701)
Allows shuffleboard to automatically discover the type, instead of inflexibly hardcoding it
2017-10-30 21:50:49 -07:00
Peter Johnson
a70687aaec Improve error reporting for the new TCP netconsole. (#700)
Fixes #695.
2017-10-30 21:50:14 -07:00
sciencewhiz
fbfe85568b Fix preferences test (#699) 2017-10-29 21:30:50 -07:00
Tyler Veness
595b1df380 Fixed minimum number of joystick axes (#696) 2017-10-29 17:21:50 -07:00
Thad House
efc7770e9b Fixes NPE in DriverStation initialization (#694)
Introduced by #626.
2017-10-27 23:16:42 -07:00
Tyler Veness
21585f70a8 Added functions for detecting button press and release events (#626)
I also shuffled around the HID interfaces to be more intuitive, deprecated some
Joystick and XboxController member functions, and deprecated the JoystickBase
and GamepadBase classes.

Supersedes #89.
2017-10-27 21:45:56 -07:00
Tyler Veness
c33fca34e9 Added TimedRobot template (#673) 2017-10-27 21:33:04 -07:00
PJ Reiniger
de95f08a10 Adding call to notify program started (#692)
Causes the HALSIM_WaitForProgramStart loop to break, essentially
notifying simulators the robot is good to go.
2017-10-27 21:00:52 -07:00
Thad House
90f99dc571 Adds PWM to LoopTiming and CycleStart HAL calls (#693) 2017-10-27 19:44:40 -07:00
Thad House
f34332643a Uses new FPGA calls to get 64 bit FPGA time and 64 bit PWM cycle start time. (#687) 2017-10-27 18:03:10 -07:00
Tyler Veness
4ab095e9c9 Fix formatting in CameraServer.cpp (#689)
A PR didn't rerun the formatter before merging.
2017-10-27 11:35:57 -07:00
Thad House
541753c814 Updates to 2018 v9 image (#686) 2017-10-27 00:47:56 -07:00
Jeremy White
f02bb058bd Set the llvm standard output stream to be unbuffered. (#678)
This is particularly useful for the simulation when invokved
inside Eclipse.  Otherwise, you won't see the robot starting
message.
2017-10-27 00:46:56 -07:00
sciencewhiz
12e96c6f13 Add usage reporting to CameraServer (#682) 2017-10-27 00:45:54 -07:00
Austin Shalit
b65447b6f5 Fix spelling typos (#595) 2017-10-27 00:44:51 -07:00
Tyler Veness
9945a5b3c6 Ran formatter (#681) 2017-10-26 19:28:59 -07:00
Thad House
ce4c9edd1f Fixes halsim_print to not try and build when the 'onlyAthena' flag has been set (#685)
Building a non-athena library in athena only is not possible.
2017-10-25 10:52:35 -07:00
PJ Reiniger
a6e6ae41b9 Add function that can register all the HAL callbacks at once (#646)
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-10-21 22:45:41 -07:00
Austin Shalit
f4e2e41aaf Remove leading '*' from license and rename to LICENSE.txt (#596) 2017-10-21 16:04:57 -07:00
Thad House
1e528669ff Adds publishing for examples and templates so they can be grabbed from eclipse (#674) 2017-10-21 15:33:42 -07:00
Thad House
a1ea448406 Adds JNI call to get CANStatus (#677)
Call already existed in the HAL.
2017-10-21 15:32:05 -07:00
Tyler Veness
9dc1de1d09 Specified angle units for Vector2d rotate() function. (#679)
Fixes #676.
2017-10-21 15:29:39 -07:00
Tyler Veness
0521d85048 Moved comment after include line so include order is determined properly (#680) 2017-10-21 15:28:46 -07:00
PJ Reiniger
3c842d8234 SPI and I2C simulator (#662)
* Creating SPI and I2C simulation abilities

* Update the callback helpers to support different function callback
types
* Create callback type that uses a buffer
* Created I2C/SPI data classes that manage the callbacks and don't do
much of anything else

* Ran format, cleaned up some issues
2017-10-18 23:01:58 -07:00
Jeremy White
be77f9cb26 Pull request for the Extensions interface only (#655)
* Modify halsim to be able to load extension libraries if they are available.

It will read the list of libraries to try from the HALSIM_EXTENSIONS
environment variable.  Multiple libraries can be given if separated
by ';' (Windows) or ':' (Unix).

The library must have an 'HALSIM_InitExtension' method that returns >= 0 on success.

The library is expected to use the interface expressed by
  hal/src/src/main/native/include/MockData

* Add a simple halsim library that just prints robot values.

This makes a good test bed for cross platform purposes,
and provides the ultimate in light weight simulators.

This initial version only prints PWM values.
2017-10-18 00:27:55 -07:00
Austin Shalit
2fc60680f4 Remove RedundantModifiers (#578) 2017-10-17 21:47:55 -07:00
Tyler Veness
0291a95f68 Add cpp examples (#659)
* Added C++ robot project examples and set up sub .clang-format for them

* Ran formatter
2017-10-17 21:37:58 -07:00
Austin Shalit
66002d6cac [WIP] Move examples to allwpilib (Java) (#569)
* Move examples to allwpilib

* Add checkstyle config to examples project

* Ran wpiformat

* Run checkstyle on examples

* Change maximum line length for examples to 80 chars

This number was chosen based on testing of the number of characters shown by default in Eclipse done by @Kevin-OConnor: 51 chars by default on an E09 @ 1024x600 (which has the welcome window open on the right), 71 with welcome closed, 95 with the right-hand outline pane closed

* Add mavenCentral repository

* Rename subproject & error on deprecated API use

* Remove deprecated API usage
2017-10-16 22:30:21 -07:00
Tyler Veness
a7e9ac1062 Fix capitalization of class names in PIDToleranceTest.cpp (#588) 2017-10-16 21:16:33 -07:00
Thad House
434d60592c Adds HAL_Initialize to ErrorBase constructor, and makes HAL_Initialize properly reentrant (#668)
Partial fix to #663, and most likely the best we are going to be able to
get.
2017-10-16 20:00:32 -07:00
Thad House
ee20747255 Adds WPILib JNI shared debug file publish. (#671) 2017-10-16 19:59:05 -07:00
Tyler Veness
f4779379c3 Added brace comments (#670)
Enforced by wpilibsuite/styleguide#80.
2017-10-16 19:56:08 -07:00
Austin Shalit
877a9eae1f Add SpeedControllerGroup (#362) 2017-10-16 19:54:36 -07:00
560 changed files with 15575 additions and 3613 deletions

View File

@@ -5,7 +5,7 @@ AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
@@ -32,12 +32,20 @@ BraceWrapping:
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
@@ -45,7 +53,11 @@ Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
@@ -53,9 +65,12 @@ IncludeCategories:
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
@@ -64,6 +79,7 @@ NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
@@ -72,8 +88,10 @@ PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false

2
.gitignore vendored
View File

@@ -12,6 +12,8 @@ test-reports
# IntelliJ
*.iml
*.ipr
*.iws
.idea/
# Created by http://www.gitignore.io

View File

@@ -1,19 +1,26 @@
sudo: false
sudo: true
dist: trusty
language: java
addons:
apt:
sources:
- deadsnakes
- ubuntu-toolchain-r-test
packages:
- g++-6
- python3
- python3-pip
- clang-format-3.8
- python3.5
before_install:
- sudo sh -c 'echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" > /etc/apt/sources.list.d/llvm.list'
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
- sudo apt-get update -q || true
- sudo apt-get install clang-format-5.0 -y
install:
- pip3 install --user wpiformat
- wget https://bootstrap.pypa.io/get-pip.py
- sudo python3.5 get-pip.py
- python3.5 -m pip install --user wpiformat
- mkdir -p $HOME/latest-gcc-symlinks # see travis-ci/travis-ci#3668
- ln -s /usr/bin/g++-6 $HOME/latest-gcc-symlinks/g++
- ln -s /usr/bin/gcc-6 $HOME/latest-gcc-symlinks/gcc
@@ -28,6 +35,6 @@ cache:
- $HOME/.gradle/wrapper/
script:
- wpiformat -y 2017 -clang 3.8
- python3.5 -m wpiformat -y 2017 -clang 5.0
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
- ./gradlew --no-daemon --console=plain -PskipAthena :hal:halSimSharedLibrary :wpilibc:wpilibcSharedLibrary :wpilibj:wpilibJNISharedSharedLibrary :wpilibj:jar

24
LICENSE.txt Normal file
View File

@@ -0,0 +1,24 @@
Copyright (c) 2009-2017 FIRST
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the FIRST nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -9,16 +9,17 @@ buildscript {
}
}
dependencies {
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.2.12'
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.3.0'
}
}
plugins {
id 'net.ltgt.errorprone' version '0.0.10'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '2.0'
id 'idea'
}
ext.licenseFile = file("$rootDir/license.txt")
ext.licenseFile = file("$rootDir/LICENSE.txt")
ext.getJNIHeadersClass = {
return JNIHeaders
@@ -174,6 +175,10 @@ subprojects {
apply plugin: 'idea'
apply plugin: 'checkstyle'
repositories {
mavenCentral()
}
checkstyle {
toolVersion = "8.1"
configFile = new File(rootDir, "styleguide/checkstyle.xml")

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

View File

@@ -108,6 +108,11 @@ model {
}
}
}
binaries.all { binary ->
if (binary.targetPlatform.operatingSystem.linux) {
linker.args "-ldl"
}
}
}
if (project.hasProperty('buildHalStaticDeps')) {
halSimStaticDeps(NativeLibrarySpec) {
@@ -197,6 +202,32 @@ model {
}
}
}
getHeaders(Task) {
def list = []
$.components.each {
if (it in NativeLibrarySpec && (it.name == 'halAthena' || it.name == 'halSim')) {
it.sources.each {
it.exportedHeaders.srcDirs.each {
list.add(it)
}
}
it.binaries.each {
it.libs.each {
it.includeRoots.each {
list.add(it)
}
}
}
}
}
list = list.unique(false)
doLast {
list.each {
print "WPIHEADER: "
println it
}
}
}
}
}

View File

@@ -7,9 +7,8 @@
#include "HAL/AnalogInput.h"
#include <mutex>
#include <FRC_NetworkCommunication/AICalibration.h>
#include <support/mutex.h>
#include "AnalogInternal.h"
#include "HAL/AnalogAccumulator.h"
@@ -230,7 +229,7 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
readSelect.Channel = port->channel;
readSelect.Averaged = false;
std::lock_guard<std::mutex> sync(analogRegisterWindowMutex);
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
return static_cast<int16_t>(analogInputSystem->readOutput(status));
@@ -261,7 +260,7 @@ int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
readSelect.Channel = port->channel;
readSelect.Averaged = true;
std::lock_guard<std::mutex> sync(analogRegisterWindowMutex);
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
return static_cast<int32_t>(analogInputSystem->readOutput(status));

View File

@@ -8,7 +8,8 @@
#include "AnalogInternal.h"
#include <atomic>
#include <mutex>
#include <support/mutex.h>
#include "HAL/AnalogInput.h"
#include "HAL/ChipObject.h"
@@ -16,7 +17,7 @@
namespace hal {
std::mutex analogRegisterWindowMutex;
wpi::mutex analogRegisterWindowMutex;
std::unique_ptr<tAI> analogInputSystem;
std::unique_ptr<tAO> analogOutputSystem;
@@ -35,7 +36,7 @@ bool analogSampleRateSet = false;
*/
void initializeAnalog(int32_t* status) {
if (analogSystemInitialized) return;
std::lock_guard<std::mutex> sync(analogRegisterWindowMutex);
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
if (analogSystemInitialized) return;
analogInputSystem.reset(tAI::create(status));
analogOutputSystem.reset(tAO::create(status));

View File

@@ -10,7 +10,8 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#include <support/mutex.h>
#include "HAL/ChipObject.h"
#include "HAL/Ports.h"
@@ -27,7 +28,7 @@ static const uint32_t kAccumulatorChannels[] = {0, 1};
extern std::unique_ptr<tAI> analogInputSystem;
extern std::unique_ptr<tAO> analogOutputSystem;
extern std::mutex analogRegisterWindowMutex;
extern wpi::mutex analogRegisterWindowMutex;
extern bool analogSampleRateSet;
struct AnalogPort {

View File

@@ -46,4 +46,4 @@ void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
percentBusUtilization, busOffCount, txFullCount, receiveErrorCount,
transmitErrorCount, status);
}
}
} // extern "C"

View File

@@ -17,7 +17,7 @@
using namespace hal;
// Create a mutex to protect changes to the digital output values
static std::mutex digitalDIOMutex;
static wpi::mutex digitalDIOMutex;
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>
@@ -54,7 +54,7 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
port->channel = static_cast<uint8_t>(channel);
std::lock_guard<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
tDIO::tOutputEnable outputEnable = digitalSystem->readOutputEnable(status);
@@ -115,7 +115,7 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
digitalChannelHandles.Free(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) return;
int32_t status = 0;
std::lock_guard<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
// Unset the SPI flag
int32_t bitToUnset = 1 << remapSPIChannel(port->channel);
@@ -205,7 +205,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
double rawDutyCycle = 256.0 * dutyCycle;
if (rawDutyCycle > 255.5) rawDutyCycle = 255.5;
{
std::lock_guard<std::mutex> sync(digitalPwmMutex);
std::lock_guard<wpi::mutex> sync(digitalPwmMutex);
uint16_t pwmPeriodPower = digitalSystem->readPWMPeriodPower(status);
if (pwmPeriodPower < 4) {
// The resolution of the duty cycle drops close to the highest
@@ -265,7 +265,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
if (value != 0) value = 1;
}
{
std::lock_guard<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
tDIO::tDO currentDIO = digitalSystem->readDO(status);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
@@ -437,7 +437,7 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
return;
}
std::lock_guard<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
// Channels 10-15 are SPI channels, so subtract our MXP channels
digitalSystem->writeFilterSelectHdr(port->channel - kNumDigitalMXPChannels,
@@ -465,7 +465,7 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
return 0;
}
std::lock_guard<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
// Channels 10-15 are SPI channels, so subtract our MXP channels
return digitalSystem->readFilterSelectHdr(
@@ -492,7 +492,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<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
digitalSystem->writeFilterPeriodHdr(filterIndex, value, status);
if (*status == 0) {
digitalSystem->writeFilterPeriodMXP(filterIndex, value, status);
@@ -517,7 +517,7 @@ int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
uint32_t hdrPeriod = 0;
uint32_t mxpPeriod = 0;
{
std::lock_guard<std::mutex> sync(digitalDIOMutex);
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
hdrPeriod = digitalSystem->readFilterPeriodHdr(filterIndex, status);
if (*status == 0) {
mxpPeriod = digitalSystem->readFilterPeriodMXP(filterIndex, status);

View File

@@ -8,10 +8,10 @@
#include "DigitalInternal.h"
#include <atomic>
#include <mutex>
#include <thread>
#include <FRC_NetworkCommunication/LoadOut.h>
#include <support/mutex.h>
#include "ConstantsInternal.h"
#include "HAL/AnalogTrigger.h"
@@ -23,7 +23,7 @@
namespace hal {
// Create a mutex to protect changes to the DO PWM config
std::mutex digitalPwmMutex;
wpi::mutex digitalPwmMutex;
std::unique_ptr<tDIO> digitalSystem;
std::unique_ptr<tRelay> relaySystem;
@@ -31,7 +31,7 @@ std::unique_ptr<tPWM> pwmSystem;
std::unique_ptr<tSPI> spiSystem;
static std::atomic<bool> digitalSystemsInitialized{false};
static std::mutex initializeMutex;
static wpi::mutex initializeMutex;
DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
@@ -44,7 +44,7 @@ void initializeDigital(int32_t* status) {
// Initial check, as if it's true initialization has finished
if (digitalSystemsInitialized) return;
std::lock_guard<std::mutex> lock(initializeMutex);
std::lock_guard<wpi::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (digitalSystemsInitialized) return;

View File

@@ -10,7 +10,8 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#include <support/mutex.h>
#include "HAL/AnalogTrigger.h"
#include "HAL/ChipObject.h"
@@ -59,7 +60,7 @@ constexpr int32_t kDefaultPwmStepsDown = 1000;
constexpr int32_t kPwmDisabled = 0;
// Create a mutex to protect changes to the DO PWM config
extern std::mutex digitalPwmMutex;
extern wpi::mutex digitalPwmMutex;
extern std::unique_ptr<tDIO> digitalSystem;
extern std::unique_ptr<tRelay> relaySystem;

View File

@@ -7,14 +7,15 @@
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <mutex>
#include <FRC_NetworkCommunication/FRCComm.h>
#include <FRC_NetworkCommunication/NetCommRPCProxy_Occur.h>
#include <llvm/raw_ostream.h>
#include <support/condition_variable.h>
#include <support/mutex.h>
#include "HAL/DriverStation.h"
@@ -26,25 +27,20 @@ struct HAL_JoystickAxesInt {
int16_t axes[HAL_kMaxJoystickAxes];
};
static std::mutex msgMutex;
static std::condition_variable newDSDataAvailableCond;
static std::mutex newDSDataAvailableMutex;
static wpi::mutex msgMutex;
static wpi::condition_variable newDSDataAvailableCond;
static wpi::mutex newDSDataAvailableMutex;
static int newDSDataAvailableCounter{0};
extern "C" {
int32_t HAL_SetErrorData(const char* errors, int32_t errorsLength,
int32_t waitMs) {
return setErrorData(errors, errorsLength, waitMs);
}
int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
const char* details, const char* location,
const char* callStack, HAL_Bool printMsg) {
// Avoid flooding console by keeping track of previous 5 error
// messages and only printing again if they're longer than 1 second old.
static constexpr int KEEP_MSGS = 5;
std::lock_guard<std::mutex> lock(msgMutex);
std::lock_guard<wpi::mutex> lock(msgMutex);
static std::string prevMsg[KEEP_MSGS];
static std::chrono::time_point<std::chrono::steady_clock>
prevMsgTime[KEEP_MSGS];
@@ -230,6 +226,67 @@ double HAL_GetMatchTime(int32_t* status) {
return matchTime;
}
int HAL_GetMatchInfo(HAL_MatchInfo* info) {
uint16_t gameSpecificMessageSize = 0;
int status = FRC_NetworkCommunication_getMatchInfo(
nullptr, nullptr, nullptr, nullptr, nullptr, &gameSpecificMessageSize);
if (status < 0) {
info->eventName = nullptr;
info->gameSpecificMessage = nullptr;
return status;
}
info->eventName = static_cast<char*>(std::malloc(256));
gameSpecificMessageSize = ((gameSpecificMessageSize + 1023) / 1024) * 1024;
uint16_t originalGameSpecificSize = gameSpecificMessageSize;
uint8_t* gameSpecificMessage =
static_cast<uint8_t*>(std::malloc(gameSpecificMessageSize));
MatchType_t matchType = MatchType_t::kMatchType_none;
uint16_t matchNumber = 0;
uint8_t replayNumber = 0;
status = FRC_NetworkCommunication_getMatchInfo(
info->eventName, &matchType, &matchNumber, &replayNumber,
gameSpecificMessage, &gameSpecificMessageSize);
if (status < 0) {
std::free(info->eventName);
std::free(gameSpecificMessage);
info->eventName = nullptr;
info->gameSpecificMessage = nullptr;
return status;
}
if (gameSpecificMessageSize >= originalGameSpecificSize) {
// Data has updated between size and read calls. Retry.
// Unless large lag, this call will be right.
std::free(gameSpecificMessage);
gameSpecificMessageSize = ((gameSpecificMessageSize + 1023) / 1024) * 1024;
gameSpecificMessage =
static_cast<uint8_t*>(std::malloc(gameSpecificMessageSize));
int status = FRC_NetworkCommunication_getMatchInfo(
nullptr, nullptr, nullptr, nullptr, gameSpecificMessage,
&gameSpecificMessageSize);
if (status < 0) {
std::free(info->eventName);
std::free(gameSpecificMessage);
info->eventName = nullptr;
info->gameSpecificMessage = nullptr;
return status;
}
}
info->eventName[255] = '\0';
info->matchType = static_cast<HAL_MatchType>(matchType);
info->matchNumber = matchNumber;
info->replayNumber = replayNumber;
info->gameSpecificMessage = reinterpret_cast<char*>(gameSpecificMessage);
info->gameSpecificMessage[gameSpecificMessageSize] = '\0';
return status;
}
void HAL_FreeMatchInfo(HAL_MatchInfo* info) {
std::free(info->eventName);
std::free(info->gameSpecificMessage);
info->eventName = nullptr;
info->gameSpecificMessage = nullptr;
}
void HAL_ObserveUserProgramStarting(void) {
FRC_NetworkCommunication_observeUserProgramStarting();
}
@@ -258,7 +315,7 @@ bool HAL_IsNewControlData(void) {
thread_local int lastCount{-1};
int currentCount = 0;
{
std::unique_lock<std::mutex> lock(newDSDataAvailableMutex);
std::unique_lock<wpi::mutex> lock(newDSDataAvailableMutex);
currentCount = newDSDataAvailableCounter;
}
if (lastCount == currentCount) return false;
@@ -280,7 +337,7 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
auto timeoutTime =
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
std::unique_lock<std::mutex> lock(newDSDataAvailableMutex);
std::unique_lock<wpi::mutex> lock(newDSDataAvailableMutex);
int currentCount = newDSDataAvailableCounter;
while (newDSDataAvailableCounter == currentCount) {
if (timeout > 0) {
@@ -295,22 +352,17 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
return true;
}
// Internal NetComm function to set new packet callback
extern int NetCommRPCProxy_SetOccurFuncPointer(
int32_t (*occurFunc)(uint32_t refNum));
// Constant number to be used for our occur handle
constexpr int32_t refNumber = 42;
static int32_t newDataOccur(uint32_t refNum) {
static void newDataOccur(uint32_t refNum) {
// Since we could get other values, require our specific handle
// to signal our threads
if (refNum != refNumber) return 0;
std::lock_guard<std::mutex> lock(newDSDataAvailableMutex);
if (refNum != refNumber) return;
std::lock_guard<wpi::mutex> lock(newDSDataAvailableMutex);
// Nofify all threads
newDSDataAvailableCounter++;
newDSDataAvailableCond.notify_all();
return 0;
}
/*
@@ -320,11 +372,11 @@ static int32_t newDataOccur(uint32_t refNum) {
*/
void HAL_InitializeDriverStation(void) {
static std::atomic_bool initialized{false};
static std::mutex initializeMutex;
static wpi::mutex initializeMutex;
// Initial check, as if it's true initialization has finished
if (initialized) return;
std::lock_guard<std::mutex> lock(initializeMutex);
std::lock_guard<wpi::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (initialized) return;

View File

@@ -14,12 +14,12 @@
#include <atomic>
#include <cstdlib>
#include <fstream>
#include <mutex>
#include <thread>
#include <FRC_NetworkCommunication/FRCComm.h>
#include <FRC_NetworkCommunication/LoadOut.h>
#include <llvm/raw_ostream.h>
#include <support/mutex.h>
#include "HAL/ChipObject.h"
#include "HAL/DriverStation.h"
@@ -35,11 +35,6 @@ using namespace hal;
static std::unique_ptr<tGlobal> global;
static std::unique_ptr<tSysWatchdog> watchdog;
static std::mutex timeMutex;
static uint32_t timeEpoch = 0;
static uint32_t prevFPGATime = 0;
static HAL_NotifierHandle rolloverNotifier = 0;
using namespace hal;
extern "C" {
@@ -224,14 +219,19 @@ uint64_t HAL_GetFPGATime(int32_t* status) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
std::lock_guard<std::mutex> lock(timeMutex);
uint32_t fpgaTime = global->readLocalTime(status);
// 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);
uint64_t upper2 = global->readLocalTimeUpper(status);
if (*status != 0) return 0;
// check for rollover
if (fpgaTime < prevFPGATime) ++timeEpoch;
prevFPGATime = fpgaTime;
return static_cast<uint64_t>(timeEpoch) << 32 |
static_cast<uint64_t>(fpgaTime);
if (upper1 != upper2) {
// Rolled over between the lower call, reread lower
lower = global->readLocalTime(status);
if (*status != 0) return 0;
}
return (upper2 << 32) + lower;
}
/**
@@ -262,19 +262,13 @@ HAL_Bool HAL_GetBrownedOut(int32_t* status) {
return !(watchdog->readStatus_PowerAlive(status));
}
static void timerRollover(uint64_t currentTime, HAL_NotifierHandle handle) {
// reschedule timer for next rollover
int32_t status = 0;
HAL_UpdateNotifierAlarm(handle, currentTime + 0x80000000ULL, &status);
}
void HAL_BaseInitialize(int32_t* status) {
static std::atomic_bool initialized{false};
static std::mutex initializeMutex;
static wpi::mutex initializeMutex;
// Initial check, as if it's true initialization has finished
if (initialized) return;
std::lock_guard<std::mutex> lock(initializeMutex);
std::lock_guard<wpi::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (initialized) return;
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
@@ -331,8 +325,18 @@ static bool killExistingProgram(int timeout, int mode) {
* Call this to start up HAL. This is required for robot programs.
*/
HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
static std::atomic_bool initialized{false};
static wpi::mutex initializeMutex;
// Initial check, as if it's true initialization has finished
if (initialized) return true;
std::lock_guard<wpi::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (initialized) return true;
setlinebuf(stdin);
setlinebuf(stdout);
llvm::outs().SetUnbuffered();
prctl(PR_SET_PDEATHSIG, SIGTERM);
@@ -351,25 +355,9 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
int32_t status = 0;
HAL_BaseInitialize(&status);
if (!rolloverNotifier)
rolloverNotifier = HAL_InitializeNotifierNonThreadedUnsafe(
timerRollover, nullptr, &status);
if (status == 0) {
uint64_t curTime = HAL_GetFPGATime(&status);
if (status == 0) {
HAL_UpdateNotifierAlarm(rolloverNotifier, curTime + 0x80000000ULL,
&status);
} else {
// return false if status failed.
return false;
}
} else {
// return false if status failed.
return false;
}
HAL_InitializeDriverStation();
initialized = true;
return true;
}

View File

@@ -7,7 +7,13 @@
#include "HAL/I2C.h"
#include <i2clib/i2c-lib.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <cstring>
#include "DigitalInternal.h"
#include "HAL/DIO.h"
@@ -15,13 +21,13 @@
using namespace hal;
static std::mutex digitalI2COnBoardMutex;
static std::mutex digitalI2CMXPMutex;
static wpi::mutex digitalI2COnBoardMutex;
static wpi::mutex digitalI2CMXPMutex;
static uint8_t i2COnboardObjCount = 0;
static uint8_t i2CMXPObjCount = 0;
static uint8_t i2COnBoardHandle = 0;
static uint8_t i2CMXPHandle = 0;
static int i2COnBoardHandle = -1;
static int i2CMXPHandle = -1;
static HAL_DigitalHandle i2CMXPDigitalHandle1 = HAL_kInvalidHandle;
static HAL_DigitalHandle i2CMXPDigitalHandle2 = HAL_kInvalidHandle;
@@ -42,30 +48,37 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
return;
}
std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex;
{
std::lock_guard<std::mutex> sync(lock);
if (port == 0) {
i2COnboardObjCount++;
if (i2COnBoardHandle > 0) return;
i2COnBoardHandle = i2clib_open("/dev/i2c-2");
} else if (port == 1) {
i2CMXPObjCount++;
if (i2CMXPHandle > 0) return;
if ((i2CMXPDigitalHandle1 = HAL_InitializeDIOPort(
HAL_GetPort(24), false, status)) == HAL_kInvalidHandle) {
return;
}
if ((i2CMXPDigitalHandle2 = HAL_InitializeDIOPort(
HAL_GetPort(25), false, status)) == HAL_kInvalidHandle) {
HAL_FreeDIOPort(i2CMXPDigitalHandle1); // free the first port allocated
return;
}
digitalSystem->writeEnableMXPSpecialFunction(
digitalSystem->readEnableMXPSpecialFunction(status) | 0xC000, status);
i2CMXPHandle = i2clib_open("/dev/i2c-1");
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
i2COnboardObjCount++;
if (i2COnboardObjCount > 1) return;
int handle = open("/dev/i2c-2", O_RDWR);
if (handle < 0) {
std::printf("Failed to open onboard i2c bus: %s\n", std::strerror(errno));
return;
}
return;
i2COnBoardHandle = handle;
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
i2CMXPObjCount++;
if (i2CMXPObjCount > 1) return;
if ((i2CMXPDigitalHandle1 = HAL_InitializeDIOPort(
HAL_GetPort(24), false, status)) == HAL_kInvalidHandle) {
return;
}
if ((i2CMXPDigitalHandle2 = HAL_InitializeDIOPort(
HAL_GetPort(25), false, status)) == HAL_kInvalidHandle) {
HAL_FreeDIOPort(i2CMXPDigitalHandle1); // free the first port allocated
return;
}
digitalSystem->writeEnableMXPSpecialFunction(
digitalSystem->readEnableMXPSpecialFunction(status) | 0xC000, status);
int handle = open("/dev/i2c-1", O_RDWR);
if (handle < 0) {
std::printf("Failed to open MXP i2c bus: %s\n", std::strerror(errno));
return;
}
i2CMXPHandle = handle;
}
}
@@ -82,22 +95,33 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
uint8_t* dataToSend, int32_t sendSize,
const uint8_t* dataToSend, int32_t sendSize,
uint8_t* dataReceived, int32_t receiveSize) {
if (port > 1) {
// Set port out of range error here
return -1;
}
int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle;
std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex;
struct i2c_msg msgs[2];
msgs[0].addr = deviceAddress;
msgs[0].flags = 0;
msgs[0].len = sendSize;
msgs[0].buf = const_cast<uint8_t*>(dataToSend);
msgs[1].addr = deviceAddress;
msgs[1].flags = I2C_M_RD;
msgs[1].len = receiveSize;
msgs[1].buf = dataReceived;
{
std::lock_guard<std::mutex> sync(lock);
return i2clib_writeread(
handle, deviceAddress, reinterpret_cast<const char*>(dataToSend),
static_cast<int32_t>(sendSize), reinterpret_cast<char*>(dataReceived),
static_cast<int32_t>(receiveSize));
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = msgs;
rdwr.nmsgs = 2;
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
}
}
@@ -113,18 +137,28 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
uint8_t* dataToSend, int32_t sendSize) {
const uint8_t* dataToSend, int32_t sendSize) {
if (port > 1) {
// Set port out of range error here
return -1;
}
int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle;
std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex;
{
std::lock_guard<std::mutex> sync(lock);
return i2clib_write(handle, deviceAddress,
reinterpret_cast<const char*>(dataToSend), sendSize);
struct i2c_msg msg;
msg.addr = deviceAddress;
msg.flags = 0;
msg.len = sendSize;
msg.buf = const_cast<uint8_t*>(dataToSend);
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = &msg;
rdwr.nmsgs = 1;
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
}
}
@@ -148,12 +182,22 @@ int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
return -1;
}
int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle;
std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex;
{
std::lock_guard<std::mutex> sync(lock);
return i2clib_read(handle, deviceAddress, reinterpret_cast<char*>(buffer),
static_cast<int32_t>(count));
struct i2c_msg msg;
msg.addr = deviceAddress;
msg.flags = I2C_M_RD;
msg.len = count;
msg.buf = buffer;
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = &msg;
rdwr.nmsgs = 1;
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
}
}
@@ -162,20 +206,20 @@ void HAL_CloseI2C(HAL_I2CPort port) {
// Set port out of range error here
return;
}
std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex;
{
std::lock_guard<std::mutex> sync(lock);
if ((port == 0 ? i2COnboardObjCount-- : i2CMXPObjCount--) == 0) {
int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle;
i2clib_close(handle);
}
}
if (port == 1) {
if (port == 0) {
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
if (i2COnboardObjCount-- == 0) {
close(i2COnBoardHandle);
}
} else {
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
if (i2CMXPObjCount-- == 0) {
close(i2CMXPHandle);
}
HAL_FreeDIOPort(i2CMXPDigitalHandle1);
HAL_FreeDIOPort(i2CMXPDigitalHandle2);
}
return;
}
} // extern "C"

View File

@@ -32,7 +32,7 @@ struct Interrupt {
class InterruptThread : public wpi::SafeThread {
public:
void Main() {
std::unique_lock<std::mutex> lock(m_mutex);
std::unique_lock<wpi::mutex> lock(m_mutex);
while (m_active) {
m_cond.wait(lock, [&] { return !m_active || m_notify; });
if (!m_active) break;
@@ -178,10 +178,10 @@ double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
}
/**
* Return the timestamp for the falling interrupt that occurred most recently.
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
* Return the timestamp for the falling interrupt that occurred most recently.
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles.Get(interruptHandle);

View File

@@ -7,12 +7,12 @@
#include "HAL/Notifier.h"
// For std::atexit()
#include <cstdlib>
#include <atomic>
#include <cstdlib> // For std::atexit()
#include <memory>
#include <mutex>
#include <support/SafeThread.h>
#include <support/mutex.h>
#include "HAL/ChipObject.h"
#include "HAL/Errors.h"
@@ -20,14 +20,13 @@
#include "HAL/cpp/NotifierInternal.h"
#include "HAL/cpp/make_unique.h"
#include "HAL/handles/UnlimitedHandleResource.h"
#include "support/SafeThread.h"
using namespace hal;
static const int32_t kTimerInterruptNumber = 28;
static std::mutex notifierInterruptMutex;
static std::mutex notifierMutex;
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;
@@ -47,7 +46,7 @@ struct Notifier {
class NotifierThread : public wpi::SafeThread {
public:
void Main() {
std::unique_lock<std::mutex> lock(m_mutex);
std::unique_lock<wpi::mutex> lock(m_mutex);
while (m_active) {
m_cond.wait(lock, [&] { return !m_active || m_notify; });
if (!m_active) break;
@@ -127,7 +126,7 @@ void updateNotifierAlarmInternal(std::shared_ptr<Notifier> notifierPointer,
}
static void alarmCallback(uint32_t, void*) {
std::unique_lock<std::mutex> sync(notifierMutex);
std::unique_lock<wpi::mutex> sync(notifierMutex);
int32_t status = 0;
uint64_t currentTime = 0;
@@ -183,7 +182,7 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
if (!notifierAtexitRegistered.test_and_set())
std::atexit(cleanupNotifierAtExit);
if (notifierRefCount.fetch_add(1) == 0) {
std::lock_guard<std::mutex> sync(notifierInterruptMutex);
std::lock_guard<wpi::mutex> sync(notifierInterruptMutex);
// create manager and alarm if not already created
if (!notifierManager) {
notifierManager = std::make_unique<tInterruptManager>(
@@ -194,7 +193,7 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status));
}
std::lock_guard<std::mutex> sync(notifierMutex);
std::lock_guard<wpi::mutex> sync(notifierMutex);
std::shared_ptr<Notifier> notifier = std::make_shared<Notifier>();
HAL_NotifierHandle handle = notifierHandles.Allocate(notifier);
if (handle == HAL_kInvalidHandle) {
@@ -237,7 +236,7 @@ HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
{
std::lock_guard<std::mutex> sync(notifierMutex);
std::lock_guard<wpi::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) return;
@@ -255,7 +254,7 @@ void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
}
if (notifierRefCount.fetch_sub(1) == 1) {
std::lock_guard<std::mutex> sync(notifierInterruptMutex);
std::lock_guard<wpi::mutex> sync(notifierInterruptMutex);
// if this was the last notifier, clean up alarm and manager
if (notifierAlarm) {
notifierAlarm->writeEnable(false, status);
@@ -283,7 +282,7 @@ void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status) {
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
uint64_t triggerTime, int32_t* status) {
std::lock_guard<std::mutex> sync(notifierMutex);
std::lock_guard<wpi::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) return;
@@ -291,7 +290,7 @@ void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
}
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status) {
std::lock_guard<std::mutex> sync(notifierMutex);
std::lock_guard<wpi::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) return;
notifier->triggerTime = UINT64_MAX;

View File

@@ -19,24 +19,39 @@ using namespace hal;
static inline int32_t GetMaxPositivePwm(DigitalPort* port) {
return port->maxPwm;
}
static inline int32_t GetMinPositivePwm(DigitalPort* port) {
return port->eliminateDeadband ? port->deadbandMaxPwm : port->centerPwm + 1;
if (port->eliminateDeadband) {
return port->deadbandMaxPwm;
} else {
return port->centerPwm + 1;
}
}
static inline int32_t GetCenterPwm(DigitalPort* port) {
return port->centerPwm;
}
static inline int32_t GetMaxNegativePwm(DigitalPort* port) {
return port->eliminateDeadband ? port->deadbandMinPwm : port->centerPwm - 1;
if (port->eliminateDeadband) {
return port->deadbandMinPwm;
} else {
return port->centerPwm - 1;
}
}
static inline int32_t GetMinNegativePwm(DigitalPort* port) {
return port->minPwm;
}
static inline int32_t GetPositiveScaleFactor(DigitalPort* port) {
return GetMaxPositivePwm(port) - GetMinPositivePwm(port);
} ///< The scale for positive speeds.
static inline int32_t GetNegativeScaleFactor(DigitalPort* port) {
return GetMaxNegativePwm(port) - GetMinNegativePwm(port);
} ///< The scale for negative speeds.
static inline int32_t GetFullRangeScaleFactor(DigitalPort* port) {
return GetMaxPositivePwm(port) - GetMinNegativePwm(port);
} ///< The scale for positions.
@@ -118,7 +133,7 @@ void HAL_SetPWMConfig(HAL_DigitalHandle pwmPortHandle, double max,
// calculate the loop time in milliseconds
double loopTime =
HAL_GetLoopTiming(status) / (kSystemClockTicksPerMicrosecond * 1e3);
HAL_GetPWMLoopTiming(status) / (kSystemClockTicksPerMicrosecond * 1e3);
if (*status != 0) return;
int32_t maxPwm = static_cast<int32_t>((max - kDefaultPwmCenter) / loopTime +
@@ -444,10 +459,34 @@ void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
*
* @return The loop time
*/
int32_t HAL_GetLoopTiming(int32_t* status) {
int32_t HAL_GetPWMLoopTiming(int32_t* status) {
initializeDigital(status);
if (*status != 0) return 0;
return pwmSystem->readLoopTiming(status);
}
/**
* Get the pwm starting cycle time
*
* @return The pwm cycle start time.
*/
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);
uint64_t upper2 = pwmSystem->readCycleStartTimeUpper(status);
if (*status != 0) return 0;
if (upper1 != upper2) {
// Rolled over between the lower call, reread lower
lower = pwmSystem->readCycleStartTime(status);
if (*status != 0) return 0;
}
return (upper2 << 32) + lower;
}
} // extern "C"

View File

@@ -27,7 +27,7 @@ static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
relayHandles;
// Create a mutex to protect changes to the relay values
static std::mutex digitalRelayMutex;
static wpi::mutex digitalRelayMutex;
extern "C" {
@@ -92,7 +92,7 @@ void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
*status = HAL_HANDLE_ERROR;
return;
}
std::lock_guard<std::mutex> sync(digitalRelayMutex);
std::lock_guard<wpi::mutex> sync(digitalRelayMutex);
uint8_t relays = 0;
if (port->fwd) {
relays = relaySystem->readValue_Forward(status);

View File

@@ -7,12 +7,17 @@
#include "HAL/SPI.h"
#include <fcntl.h>
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <array>
#include <atomic>
#include <mutex>
#include <cstring>
#include <llvm/raw_ostream.h>
#include <spilib/spi-lib.h>
#include <support/mutex.h>
#include "DigitalInternal.h"
#include "HAL/DIO.h"
@@ -32,9 +37,9 @@ static int32_t m_spiMXPHandle = 0;
static constexpr int32_t kSpiMaxHandles = 5;
// Indices 0-3 are for onboard CS0-CS2. Index 4 is for MXP.
static std::array<std::mutex, kSpiMaxHandles> spiHandleMutexes;
static std::array<std::mutex, kSpiMaxHandles> spiApiMutexes;
static std::array<std::mutex, kSpiMaxHandles> spiAccumulatorMutexes;
static std::array<wpi::mutex, kSpiMaxHandles> spiHandleMutexes;
static std::array<wpi::mutex, kSpiMaxHandles> spiApiMutexes;
static std::array<wpi::mutex, kSpiMaxHandles> spiAccumulatorMutexes;
// MXP SPI does not count towards this
std::atomic<int32_t> spiPortCount{0};
@@ -111,13 +116,21 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
return;
}
int handle;
if (HAL_GetSPIHandle(port) != 0) return;
switch (port) {
case 0:
CommonSPIPortInit(status);
if (*status != 0) return;
// CS0 is not a DIO port, so nothing to allocate
HAL_SetSPIHandle(HAL_SPI_kOnboardCS0, spilib_open("/dev/spidev0.0"));
handle = open("/dev/spidev0.0", O_RDWR);
if (handle < 0) {
std::printf("Failed to open SPI port %d: %s\n", port,
std::strerror(errno));
CommonSPIPortFree();
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS0, handle);
break;
case 1:
CommonSPIPortInit(status);
@@ -130,7 +143,15 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
CommonSPIPortFree();
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS1, spilib_open("/dev/spidev0.1"));
handle = open("/dev/spidev0.1", O_RDWR);
if (handle < 0) {
std::printf("Failed to open SPI port %d: %s\n", port,
std::strerror(errno));
CommonSPIPortFree();
HAL_FreeDIOPort(digitalHandles[0]);
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS1, handle);
break;
case 2:
CommonSPIPortInit(status);
@@ -143,7 +164,15 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
CommonSPIPortFree();
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS2, spilib_open("/dev/spidev0.2"));
handle = open("/dev/spidev0.2", O_RDWR);
if (handle < 0) {
std::printf("Failed to open SPI port %d: %s\n", port,
std::strerror(errno));
CommonSPIPortFree();
HAL_FreeDIOPort(digitalHandles[1]);
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS2, handle);
break;
case 3:
CommonSPIPortInit(status);
@@ -156,7 +185,15 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
CommonSPIPortFree();
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS3, spilib_open("/dev/spidev0.3"));
handle = open("/dev/spidev0.3", O_RDWR);
if (handle < 0) {
std::printf("Failed to open SPI port %d: %s\n", port,
std::strerror(errno));
CommonSPIPortFree();
HAL_FreeDIOPort(digitalHandles[2]);
return;
}
HAL_SetSPIHandle(HAL_SPI_kOnboardCS3, handle);
break;
case 4:
initializeDigital(status);
@@ -193,13 +230,22 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
}
digitalSystem->writeEnableMXPSpecialFunction(
digitalSystem->readEnableMXPSpecialFunction(status) | 0x00F0, status);
HAL_SetSPIHandle(HAL_SPI_kMXP, spilib_open("/dev/spidev1.0"));
handle = open("/dev/spidev1.0", O_RDWR);
if (handle < 0) {
std::printf("Failed to open SPI port %d: %s\n", port,
std::strerror(errno));
HAL_FreeDIOPort(digitalHandles[5]); // free the first port allocated
HAL_FreeDIOPort(digitalHandles[6]); // free the second port allocated
HAL_FreeDIOPort(digitalHandles[7]); // free the third port allocated
HAL_FreeDIOPort(digitalHandles[8]); // free the fourth port allocated
return;
}
HAL_SetSPIHandle(HAL_SPI_kMXP, handle);
break;
default:
*status = PARAMETER_OUT_OF_RANGE;
break;
}
return;
}
/**
@@ -214,16 +260,20 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
* @param size Number of bytes to transfer. [0..7]
* @return Number of bytes transferred, -1 for error
*/
int32_t HAL_TransactionSPI(HAL_SPIPort port, uint8_t* dataToSend,
int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
uint8_t* dataReceived, int32_t size) {
if (port < 0 || port >= kSpiMaxHandles) {
return -1;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
return spilib_writeread(
HAL_GetSPIHandle(port), reinterpret_cast<const char*>(dataToSend),
reinterpret_cast<char*>(dataReceived), static_cast<int32_t>(size));
struct spi_ioc_transfer xfer;
std::memset(&xfer, 0, sizeof(xfer));
xfer.tx_buf = (__u64)dataToSend;
xfer.rx_buf = (__u64)dataReceived;
xfer.len = size;
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
/**
@@ -236,15 +286,19 @@ int32_t HAL_TransactionSPI(HAL_SPIPort port, uint8_t* dataToSend,
* @param sendSize The number of bytes to be written
* @return The number of bytes written. -1 for an error
*/
int32_t HAL_WriteSPI(HAL_SPIPort port, uint8_t* dataToSend, int32_t sendSize) {
int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t sendSize) {
if (port < 0 || port >= kSpiMaxHandles) {
return -1;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
return spilib_write(HAL_GetSPIHandle(port),
reinterpret_cast<const char*>(dataToSend),
static_cast<int32_t>(sendSize));
struct spi_ioc_transfer xfer;
std::memset(&xfer, 0, sizeof(xfer));
xfer.tx_buf = (__u64)dataToSend;
xfer.len = sendSize;
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
/**
@@ -265,9 +319,13 @@ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
return -1;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
return spilib_read(HAL_GetSPIHandle(port), reinterpret_cast<char*>(buffer),
static_cast<int32_t>(count));
struct spi_ioc_transfer xfer;
std::memset(&xfer, 0, sizeof(xfer));
xfer.rx_buf = (__u64)buffer;
xfer.len = count;
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
/**
@@ -284,8 +342,8 @@ void HAL_CloseSPI(HAL_SPIPort port) {
HAL_FreeSPIAccumulator(port, &status);
{
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
spilib_close(HAL_GetSPIHandle(port));
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
close(HAL_GetSPIHandle(port));
}
HAL_SetSPIHandle(port, 0);
@@ -326,8 +384,8 @@ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
return;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
spilib_setspeed(HAL_GetSPIHandle(port), speed);
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
}
/**
@@ -346,9 +404,13 @@ void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
return;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
spilib_setopts(HAL_GetSPIHandle(port), msbFirst, sampleOnTrailing,
clkIdleHigh);
uint8_t mode = 0;
mode |= (!msbFirst ? 8 : 0);
mode |= (clkIdleHigh ? 2 : 0);
mode |= (sampleOnTrailing ? 1 : 0);
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
}
/**
@@ -362,7 +424,7 @@ void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
if (port < 4) {
spiSystem->writeChipSelectActiveHigh_Hdr(
spiSystem->readChipSelectActiveHigh_Hdr(status) | (1 << port), status);
@@ -382,7 +444,7 @@ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
if (port < 4) {
spiSystem->writeChipSelectActiveHigh_Hdr(
spiSystem->readChipSelectActiveHigh_Hdr(status) & ~(1 << port), status);
@@ -402,7 +464,7 @@ int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
return 0;
}
std::lock_guard<std::mutex> sync(spiHandleMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiHandleMutexes[port]);
switch (port) {
case 0:
return m_spiCS0Handle;
@@ -431,7 +493,7 @@ void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
return;
}
std::lock_guard<std::mutex> sync(spiHandleMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiHandleMutexes[port]);
switch (port) {
case 0:
m_spiCS0Handle = handle;
@@ -462,13 +524,7 @@ static void spiAccumulatorProcess(uint64_t currentTime,
// perform SPI transaction
uint8_t resp_b[4];
{
std::lock_guard<std::mutex> sync(spiApiMutexes[accum->port]);
spilib_writeread(HAL_GetSPIHandle(accum->port),
reinterpret_cast<const char*>(accum->cmd),
reinterpret_cast<char*>(resp_b),
static_cast<int32_t>(accum->xferSize));
}
HAL_TransactionSPI(accum->port, accum->cmd, resp_b, accum->xferSize);
// convert from bytes
uint32_t resp = 0;
@@ -538,7 +594,7 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
if (!spiAccumulators[port])
spiAccumulators[port] = std::make_unique<SPIAccumulator>();
SPIAccumulator* accum = spiAccumulators[port].get();
@@ -584,7 +640,7 @@ void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -604,7 +660,7 @@ void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status) {
return;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -631,7 +687,7 @@ void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center,
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -650,7 +706,7 @@ void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband,
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -668,7 +724,7 @@ int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status) {
return 0;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -688,7 +744,7 @@ int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status) {
return 0;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -711,7 +767,7 @@ int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status) {
return 0;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;
@@ -754,7 +810,7 @@ void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value,
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;

View File

@@ -11,6 +11,7 @@
#include <cstdio>
#include <cstring>
#include <llvm/FileSystem.h>
#include <llvm/StringRef.h>
#include "../visa/visa.h"
@@ -26,7 +27,7 @@ namespace hal {
std::string SerialHelper::m_usbNames[2]{"", ""};
std::mutex SerialHelper::m_nameMutex;
wpi::mutex SerialHelper::m_nameMutex;
SerialHelper::SerialHelper() {
viOpenDefaultRM(reinterpret_cast<ViSession*>(&m_resourceHandle));
@@ -178,9 +179,8 @@ void SerialHelper::QueryHubPaths(int32_t* status) {
// Status might be positive, so reset it to 0
*status = 0;
// Storage buffers for Visa calls and system exec calls
// Storage buffer for Visa call
char osName[256];
char execBuffer[128];
// Loop through all returned VISA objects.
// Increment the internal VISA ptr every loop
@@ -214,45 +214,30 @@ void SerialHelper::QueryHubPaths(int32_t* status) {
llvm::StringRef matchString = devNameRef.split(')').first;
if (matchString.equals(devNameRef)) continue;
// Run find using pipe to get a list of system accessors
llvm::SmallString<128> val(
"sh -c \"find /sys/devices/soc0 | grep amba | grep usb | grep ");
val += matchString;
val += "\"";
// Search directories to get a list of system accessors
std::error_code ec;
for (auto p = llvm::sys::fs::recursive_directory_iterator(
"/sys/devices/soc0", ec);
p != llvm::sys::fs::recursive_directory_iterator(); p.increment(ec)) {
if (ec) break;
llvm::StringRef path{p->path()};
if (path.find("amba") == llvm::StringRef::npos) continue;
if (path.find("usb") == llvm::StringRef::npos) continue;
if (path.find(matchString) == llvm::StringRef::npos) continue;
// Pipe code found on StackOverflow
// http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c-using-posix
// Using std::string because this is guarenteed to be large
std::string output = "";
std::shared_ptr<FILE> pipe(popen(val.c_str(), "r"), pclose);
// Just check the next item on a pipe failure
if (!pipe) continue;
while (!feof(pipe.get())) {
if (std::fgets(execBuffer, 128, pipe.get()) != 0) output += execBuffer;
}
if (!output.empty()) {
llvm::SmallVector<llvm::StringRef, 16> pathSplitVec;
// Split output by line, grab first line, and split it into
// individual directories
llvm::StringRef{output}.split('\n').first.split(pathSplitVec, '/', -1,
false);
// Split path into individual directories
path.split(pathSplitVec, '/', -1, false);
// Find each individual item index
const char* usb1 = "usb1";
const char* tty = "tty";
int findusb = -1;
int findtty = -1;
int findregex = -1;
for (size_t i = 0; i < pathSplitVec.size(); i++) {
if (findusb == -1 && pathSplitVec[i].equals(usb1)) {
if (findusb == -1 && pathSplitVec[i].equals("usb1")) {
findusb = i;
}
if (findtty == -1 && pathSplitVec[i].equals(tty)) {
if (findtty == -1 && pathSplitVec[i].equals("tty")) {
findtty = i;
}
if (findregex == -1 && pathSplitVec[i].equals(matchString)) {
@@ -274,6 +259,7 @@ void SerialHelper::QueryHubPaths(int32_t* status) {
m_visaResource.emplace_back(desc);
m_osResource.emplace_back(
llvm::StringRef{osName}.split("(").second.split(")").first);
break;
}
}
@@ -287,7 +273,7 @@ done:
int32_t SerialHelper::GetIndexForPort(HAL_SerialPort port, int32_t* status) {
// Hold lock whenever we're using the names array
std::lock_guard<std::mutex> lock(m_nameMutex);
std::lock_guard<wpi::mutex> lock(m_nameMutex);
std::string portString = m_usbNames[port - 2];

View File

@@ -1,6 +1,6 @@
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "ctre/CtreCanNode.h"
#include "CtreCanNode.h"
#include "FRC_NetworkCommunication/CANSessionMux.h"
#include <string.h> // memset

View File

@@ -1,6 +1,6 @@
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "ctre/PCM.h"
#include "PCM.h"
#include "FRC_NetworkCommunication/CANSessionMux.h"
#include <string.h> // memset
/* This can be a constant, as long as nobody needs to update solenoids within

View File

@@ -1,4 +1,4 @@
#include "ctre/PDP.h"
#include "PDP.h"
#include "FRC_NetworkCommunication/CANSessionMux.h" //CAN Comm
#include <string.h> // memset

View File

@@ -52,6 +52,4 @@ typedef enum {
CTR_BufferFull, //!< Caller attempted to insert data into a buffer that is full.
}CTR_Code;
#include "ctre_frames.h"
#endif /* CTRE_H */

View File

@@ -24,5 +24,5 @@ double HAL_GetAccelerometerX(void);
double HAL_GetAccelerometerY(void);
double HAL_GetAccelerometerZ(void);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -32,5 +32,5 @@ int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
int64_t* value, int64_t* count, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -34,5 +34,5 @@ double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status);
double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status);
int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -46,5 +46,5 @@ int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -24,5 +24,5 @@ double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
int32_t* status);
HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -43,5 +43,5 @@ HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_AnalogTriggerType type,
int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -56,5 +56,5 @@ void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
uint32_t* transmitErrorCount, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -44,5 +44,5 @@ HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
HAL_Bool HAL_GetCompressorNotConnectedFault(
HAL_CompressorHandle compressorHandle, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -15,5 +15,5 @@ extern "C" {
int32_t HAL_GetSystemClockTicksPerMicrosecond(void);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -69,5 +69,5 @@ HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -41,5 +41,5 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status);
void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status);
int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -47,6 +47,13 @@ enum HAL_AllianceStationID : int32_t {
HAL_AllianceStationID_kBlue3,
};
enum HAL_MatchType {
HAL_kMatchType_none,
HAL_kMatchType_practice,
HAL_kMatchType_qualification,
HAL_kMatchType_elimination,
};
/* The maximum number of axes that will be stored in a single HALJoystickAxes
* struct. This is used for allocating buffers, not bounds checking, since
* there are usually less axes in practice.
@@ -79,11 +86,18 @@ struct HAL_JoystickDescriptor {
uint8_t povCount;
};
struct HAL_MatchInfo {
char* eventName;
HAL_MatchType matchType;
uint16_t matchNumber;
uint8_t replayNumber;
char* gameSpecificMessage;
};
#ifdef __cplusplus
extern "C" {
#endif
int32_t HAL_SetErrorData(const char* errors, int32_t errorsLength,
int32_t waitMs);
int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
const char* details, const char* location,
const char* callStack, HAL_Bool printMsg);
@@ -105,6 +119,9 @@ int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble);
double HAL_GetMatchTime(int32_t* status);
int HAL_GetMatchInfo(HAL_MatchInfo* info);
void HAL_FreeMatchInfo(HAL_MatchInfo* info);
#ifndef HAL_USE_LABVIEW
void HAL_ReleaseDSMutex(void);

View File

@@ -75,5 +75,5 @@ double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
HAL_EncoderHandle encoderHandle, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -0,0 +1,25 @@
/*----------------------------------------------------------------------------*/
/* 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
/**
* HAL Simulator Extensions are libraries that provide additional simulator
* functionality, such as a Gazebo interface, or a more light weight simulation.
*
* An extension must expose the HALSIM_InitExtension entry point which is
* invoked after the library is loaded.
*
* The entry point is expected to return < 0 for errors that should stop
* the HAL completely, 0 for success, and > 0 for a non fatal error.
*/
typedef int halsim_extension_init_func_t(void);
extern "C" {
int HAL_LoadOneExtension(const char* library);
int HAL_LoadExtensions(void);
} // extern "C"

View File

@@ -82,5 +82,5 @@ int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
#endif // HAL_USE_LABVIEW
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -17,13 +17,13 @@ extern "C" {
void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status);
int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
uint8_t* dataToSend, int32_t sendSize,
const uint8_t* dataToSend, int32_t sendSize,
uint8_t* dataReceived, int32_t receiveSize);
int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
uint8_t* dataToSend, int32_t sendSize);
const uint8_t* dataToSend, int32_t sendSize);
int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
int32_t count);
void HAL_CloseI2C(HAL_I2CPort port);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -46,5 +46,5 @@ void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -26,5 +26,5 @@ void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
uint64_t triggerTime, int32_t* status);
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -46,5 +46,5 @@ void HAL_FlushOSSerial(HAL_SerialPort port, int32_t* status);
void HAL_ClearOSSerial(HAL_SerialPort port, int32_t* status);
void HAL_CloseOSSerial(HAL_SerialPort port, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -28,5 +28,5 @@ double HAL_GetPDPTotalEnergy(int32_t module, int32_t* status);
void HAL_ResetPDPTotalEnergy(int32_t module, int32_t* status);
void HAL_ClearPDPStickyFaults(int32_t module, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -49,7 +49,8 @@ double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status);
void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status);
void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
int32_t* status);
int32_t HAL_GetLoopTiming(int32_t* status);
int32_t HAL_GetPWMLoopTiming(int32_t* status);
uint64_t HAL_GetPWMCycleStartTime(int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -32,5 +32,5 @@ int32_t HAL_GetNumSolenoidChannels(void);
int32_t HAL_GetNumPDPModules(void);
int32_t HAL_GetNumPDPChannels(void);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -30,5 +30,5 @@ double HAL_GetUserCurrent3V3(int32_t* status);
HAL_Bool HAL_GetUserActive3V3(int32_t* status);
int32_t HAL_GetUserCurrentFaults3V3(int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -25,5 +25,5 @@ void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
int32_t* status);
HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -24,9 +24,10 @@ extern "C" {
#endif
void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status);
int32_t HAL_TransactionSPI(HAL_SPIPort port, uint8_t* dataToSend,
int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
uint8_t* dataReceived, int32_t size);
int32_t HAL_WriteSPI(HAL_SPIPort port, uint8_t* dataToSend, int32_t sendSize);
int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t sendSize);
int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count);
void HAL_CloseSPI(HAL_SPIPort port);
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed);
@@ -55,5 +56,5 @@ double HAL_GetSPIAccumulatorAverage(HAL_SPIPort port, int32_t* status);
void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value,
int64_t* count, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -46,5 +46,5 @@ void HAL_FlushSerial(HAL_SerialPort port, int32_t* status);
void HAL_ClearSerial(HAL_SerialPort port, int32_t* status);
void HAL_CloseSerial(HAL_SerialPort port, int32_t* status);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -31,5 +31,5 @@ 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);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -25,4 +25,4 @@ HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
int32_t priority, int32_t* status);
HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
int32_t* status);
}
} // extern "C"

View File

@@ -82,6 +82,7 @@ namespace nUsageReporting
kResourceType_PDP,
kResourceType_PCM, // 60
kResourceType_PigeonIMU,
kResourceType_NidecBrushless,
} tResourceType;
typedef enum

View File

@@ -52,7 +52,9 @@ inline Log::Log() {}
inline llvm::raw_ostream& Log::Get(TLogLevel level) {
oss << "- " << NowTime();
oss << " " << ToString(level) << ": ";
oss << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
if (level > logDEBUG) {
oss << std::string(level - logDEBUG, '\t');
}
return oss;
}
@@ -94,7 +96,7 @@ typedef Log FILELog;
if (level > FILELog::ReportingLevel()) \
; \
else \
Log().Get(level)
Log().Get(level)
inline std::string NowTime() {
llvm::SmallString<128> buf;

View File

@@ -12,4 +12,4 @@
extern "C" {
HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
HAL_NotifierProcessFunction process, void* param, int32_t* status);
}
} // extern "C"

View File

@@ -9,12 +9,12 @@
#include <stdint.h>
#include <mutex>
#include <string>
#include <vector>
#include <llvm/SmallString.h>
#include <llvm/SmallVector.h>
#include <support/mutex.h>
#include "HAL/SerialPort.h"
@@ -46,7 +46,7 @@ class SerialHelper {
int32_t m_resourceHandle;
static std::mutex m_nameMutex;
static wpi::mutex m_nameMutex;
static std::string m_usbNames[2];
};
} // namespace hal

View File

@@ -1,92 +0,0 @@
/*----------------------------------------------------------------------------*/
/* 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
// Allows usage with std::lock_guard without including <mutex> separately
#include <mutex>
#if !defined(__linux__)
namespace hal {
// We do not want to use pthreads if in the simulator; however, in the
// simulator, we do not care about priority inversion.
typedef std::mutex priority_mutex;
typedef std::recursive_mutex priority_recursive_mutex;
} // namespace hal
#else // Covers rest of file.
#include <pthread.h>
namespace hal {
class priority_recursive_mutex {
public:
typedef pthread_mutex_t* native_handle_type;
constexpr priority_recursive_mutex() noexcept = default;
priority_recursive_mutex(const priority_recursive_mutex&) = delete;
priority_recursive_mutex& operator=(const priority_recursive_mutex&) = delete;
// Lock the mutex, blocking until it's available.
void lock();
// Unlock the mutex.
void unlock();
// Tries to lock the mutex.
bool try_lock() noexcept;
pthread_mutex_t* native_handle();
private:
// Do the equivalent of setting PTHREAD_PRIO_INHERIT and
// PTHREAD_MUTEX_RECURSIVE_NP.
#if __WORDSIZE == 64
pthread_mutex_t m_mutex = {
{0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, {0, 0}}};
#else
pthread_mutex_t m_mutex = {
{0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0}}};
#endif
};
class priority_mutex {
public:
typedef pthread_mutex_t* native_handle_type;
constexpr priority_mutex() noexcept = default;
priority_mutex(const priority_mutex&) = delete;
priority_mutex& operator=(const priority_mutex&) = delete;
// Lock the mutex, blocking until it's available.
void lock();
// Unlock the mutex.
void unlock();
// Tries to lock the mutex.
bool try_lock() noexcept;
pthread_mutex_t* native_handle();
private:
// Do the equivalent of setting PTHREAD_PRIO_INHERIT.
#if __WORDSIZE == 64
pthread_mutex_t m_mutex = {{0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
#else
pthread_mutex_t m_mutex = {{0, 0, 0, 0x20, 0, {0}}};
#endif
};
} // namespace hal
#endif // FRC_SIMULATOR
// For backwards compatibility
#ifndef NAMESPACED_PRIORITY
using hal::priority_mutex; // NOLINT
using hal::priority_recursive_mutex; // NOLINT
#endif

View File

@@ -11,7 +11,8 @@
#include <array>
#include <memory>
#include <mutex>
#include <support/mutex.h>
#include "HAL/Errors.h"
#include "HAL/Types.h"
@@ -48,7 +49,7 @@ class DigitalHandleResource : public HandleBase {
private:
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<std::mutex, size> m_handleMutexes;
std::array<wpi::mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size>
@@ -59,7 +60,7 @@ THandle DigitalHandleResource<THandle, TStruct, size>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// check for allocation, otherwise allocate and return a valid handle
if (m_structures[index] != nullptr) {
*status = RESOURCE_IS_ALLOCATED;
@@ -77,7 +78,7 @@ std::shared_ptr<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -90,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<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(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<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -12,6 +12,8 @@
#include <memory>
#include <vector>
#include <support/mutex.h>
#include "HAL/Errors.h"
#include "HAL/Types.h"
#include "HAL/cpp/make_unique.h"
@@ -51,7 +53,7 @@ class IndexedClassedHandleResource : public HandleBase {
private:
std::array<std::shared_ptr<TStruct>[], size> m_structures;
std::array<std::mutex[], size> m_handleMutexes;
std::array<wpi::mutex[], size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size,
@@ -59,7 +61,7 @@ template <typename THandle, typename TStruct, int16_t size,
IndexedClassedHandleResource<THandle, TStruct, size,
enumValue>::IndexedClassedHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<std::mutex[]>(size);
m_handleMutexes = std::make_unique<wpi::mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size,
@@ -72,7 +74,7 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// check for allocation, otherwise allocate and return a valid handle
if (m_structures[index] != nullptr) {
*status = RESOURCE_IS_ALLOCATED;
@@ -84,14 +86,15 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
std::shared_ptr<TStruct> IndexedClassedHandleResource<
THandle, TStruct, size, enumValue>::Get(THandle handle) {
std::shared_ptr<TStruct>
IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
THandle handle) {
// get handle index, and fail early if index out of range or wrong handle
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -105,7 +108,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<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -114,7 +117,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<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -11,7 +11,8 @@
#include <array>
#include <memory>
#include <mutex>
#include <support/mutex.h>
#include "HAL/Errors.h"
#include "HAL/Types.h"
@@ -49,7 +50,7 @@ class IndexedHandleResource : public HandleBase {
private:
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<std::mutex, size> m_handleMutexes;
std::array<wpi::mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size,
@@ -61,7 +62,7 @@ THandle IndexedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// check for allocation, otherwise allocate and return a valid handle
if (m_structures[index] != nullptr) {
*status = RESOURCE_IS_ALLOCATED;
@@ -80,7 +81,7 @@ IndexedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -94,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<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -102,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<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -11,7 +11,8 @@
#include <array>
#include <memory>
#include <mutex>
#include <support/mutex.h>
#include "HAL/Types.h"
#include "HAL/cpp/make_unique.h"
@@ -48,8 +49,8 @@ class LimitedClassedHandleResource : public HandleBase {
private:
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<std::mutex, size> m_handleMutexes;
std::mutex m_allocateMutex;
std::array<wpi::mutex, size> m_handleMutexes;
wpi::mutex m_allocateMutex;
};
template <typename THandle, typename TStruct, int16_t size,
@@ -58,12 +59,12 @@ THandle
LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
std::shared_ptr<TStruct> toSet) {
// globally lock to loop through indices
std::lock_guard<std::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> sync(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<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i] = toSet;
return static_cast<THandle>(createHandle(i, enumValue, m_version));
}
@@ -73,14 +74,15 @@ LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
std::shared_ptr<TStruct> LimitedClassedHandleResource<
THandle, TStruct, size, enumValue>::Get(THandle handle) {
std::shared_ptr<TStruct>
LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
THandle handle) {
// get handle index, and fail early if index out of range or wrong handle
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -94,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<std::mutex> sync(m_allocateMutex);
std::lock_guard<std::mutex> lock(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -104,9 +106,9 @@ template <typename THandle, typename TStruct, int16_t size,
void LimitedClassedHandleResource<THandle, TStruct, size,
enumValue>::ResetHandles() {
{
std::lock_guard<std::mutex> lock(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
for (int i = 0; i < size; i++) {
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
}

View File

@@ -11,7 +11,8 @@
#include <array>
#include <memory>
#include <mutex>
#include <support/mutex.h>
#include "HAL/Types.h"
#include "HAL/cpp/make_unique.h"
@@ -46,20 +47,20 @@ class LimitedHandleResource : public HandleBase {
private:
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<std::mutex, size> m_handleMutexes;
std::mutex m_allocateMutex;
std::array<wpi::mutex, size> m_handleMutexes;
wpi::mutex m_allocateMutex;
};
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<std::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> sync(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<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i] = std::make_shared<TStruct>();
return static_cast<THandle>(createHandle(i, enumValue, m_version));
}
@@ -76,7 +77,7 @@ LimitedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
// return structure. Null will propogate correctly, so no need to manually
// check.
return m_structures[index];
@@ -90,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<std::mutex> sync(m_allocateMutex);
std::lock_guard<std::mutex> lock(m_handleMutexes[index]);
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -99,9 +100,9 @@ template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
void LimitedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
{
std::lock_guard<std::mutex> lock(m_allocateMutex);
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
for (int i = 0; i < size; i++) {
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
}

View File

@@ -10,9 +10,10 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#include <vector>
#include <support/mutex.h>
#include "HAL/Types.h"
#include "HAL/handles/HandlesInternal.h"
@@ -48,13 +49,13 @@ class UnlimitedHandleResource : public HandleBase {
private:
std::vector<std::shared_ptr<TStruct>> m_structures;
std::mutex m_handleMutex;
wpi::mutex m_handleMutex;
};
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
THandle UnlimitedHandleResource<THandle, TStruct, enumValue>::Allocate(
std::shared_ptr<TStruct> structure) {
std::lock_guard<std::mutex> sync(m_handleMutex);
std::lock_guard<wpi::mutex> sync(m_handleMutex);
size_t i;
for (i = 0; i < m_structures.size(); i++) {
if (m_structures[i] == nullptr) {
@@ -73,7 +74,7 @@ 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<std::mutex> sync(m_handleMutex);
std::lock_guard<wpi::mutex> sync(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
return nullptr;
return m_structures[index];
@@ -83,7 +84,7 @@ template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
THandle handle) {
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
std::lock_guard<std::mutex> sync(m_handleMutex);
std::lock_guard<wpi::mutex> sync(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
m_structures[index].reset();
}
@@ -91,7 +92,7 @@ void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
{
std::lock_guard<std::mutex> lock(m_handleMutex);
std::lock_guard<wpi::mutex> lock(m_handleMutex);
for (size_t i = 0; i < m_structures.size(); i++) {
m_structures[i].reset();
}

View File

@@ -55,6 +55,11 @@ void HALSIM_CancelAccelerometerZCallback(int32_t index, int32_t uid);
double HALSIM_GetAccelerometerZ(int32_t index);
void HALSIM_SetAccelerometerZ(int32_t index, double z);
void HALSIM_RegisterAccelerometerAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -38,6 +38,10 @@ void HALSIM_CancelAnalogGyroInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetAnalogGyroInitialized(int32_t index);
void HALSIM_SetAnalogGyroInitialized(int32_t index, HAL_Bool initialized);
void HALSIM_RegisterAnalogGyroAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -88,6 +88,10 @@ int32_t HALSIM_GetAnalogInAccumulatorDeadband(int32_t index);
void HALSIM_SetAnalogInAccumulatorDeadband(int32_t index,
int32_t accumulatorDeadband);
void HALSIM_RegisterAnalogInAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -31,6 +31,10 @@ void HALSIM_CancelAnalogOutInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetAnalogOutInitialized(int32_t index);
void HALSIM_SetAnalogOutInitialized(int32_t index, HAL_Bool initialized);
void HALSIM_RegisterAnalogOutAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -54,6 +54,11 @@ HALSIM_AnalogTriggerMode HALSIM_GetAnalogTriggerTriggerMode(int32_t index);
void HALSIM_SetAnalogTriggerTriggerMode(int32_t index,
HALSIM_AnalogTriggerMode triggerMode);
void HALSIM_RegisterAnalogTriggerAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -53,6 +53,9 @@ void HALSIM_CancelDIOFilterIndexCallback(int32_t index, int32_t uid);
int32_t HALSIM_GetDIOFilterIndex(int32_t index);
void HALSIM_SetDIOFilterIndex(int32_t index, int32_t filterIndex);
void HALSIM_RegisterDIOAllCallbacks(int32_t index, HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -38,6 +38,10 @@ void HALSIM_CancelDigitalPWMPinCallback(int32_t index, int32_t uid);
int32_t HALSIM_GetDigitalPWMPin(int32_t index);
void HALSIM_SetDigitalPWMPin(int32_t index, int32_t pin);
void HALSIM_RegisterDigitalPWMAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -7,6 +7,7 @@
#pragma once
#include "HAL/DriverStation.h"
#include "HAL/HAL.h"
#include "NotifyListener.h"
@@ -67,8 +68,24 @@ void HALSIM_CancelDriverStationMatchTimeCallback(int32_t uid);
double HALSIM_GetDriverStationMatchTime();
void HALSIM_SetDriverStationMatchTime(double matchTime);
void HALSIM_SetJoystickAxes(int32_t joystickNum, const HAL_JoystickAxes* axes);
void HALSIM_SetJoystickPOVs(int32_t joystickNum, const HAL_JoystickPOVs* povs);
void HALSIM_SetJoystickButtons(int32_t joystickNum,
const HAL_JoystickButtons* buttons);
void HALSIM_SetJoystickDescriptor(int32_t joystickNum,
const HAL_JoystickDescriptor* descriptor);
void HALSIM_GetJoystickOutputs(int32_t joystickNum, int64_t* outputs,
int32_t* leftRumble, int32_t* rightRumble);
void HALSIM_SetMatchInfo(const HAL_MatchInfo* info);
void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_NotifyDriverStationNewData(void);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -78,6 +78,10 @@ void HALSIM_CancelEncoderSamplesToAverageCallback(int32_t index, int32_t uid);
int32_t HALSIM_GetEncoderSamplesToAverage(int32_t index);
void HALSIM_SetEncoderSamplesToAverage(int32_t index, int32_t samplesToAverage);
void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -0,0 +1,39 @@
/*----------------------------------------------------------------------------*/
/* 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
#include "HAL/HAL.h"
#include "NotifyListener.h"
#ifdef __cplusplus
extern "C" {
#endif
void HALSIM_ResetI2CData(int32_t index);
int32_t HALSIM_RegisterI2CInitializedCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelI2CInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetI2CInitialized(int32_t index);
void HALSIM_SetI2CInitialized(int32_t index, HAL_Bool initialized);
int32_t HALSIM_RegisterI2CReadCallback(int32_t index,
HAL_BufferCallback callback,
void* param);
void HALSIM_CancelI2CReadCallback(int32_t index, int32_t uid);
int32_t HALSIM_RegisterI2CWriteCallback(int32_t index,
HAL_ConstBufferCallback callback,
void* param);
void HALSIM_CancelI2CWriteCallback(int32_t index, int32_t uid);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -11,4 +11,4 @@ extern "C" {
void HALSIM_WaitForProgramStart(void);
void HALSIM_SetProgramStarted(void);
void HALSIM_RestartTiming(void);
}
} // extern "C"

View File

@@ -12,15 +12,25 @@
typedef void (*HAL_NotifyCallback)(const char* name, void* param,
const struct HAL_Value* value);
typedef void (*HAL_BufferCallback)(const char* name, void* param,
unsigned char* buffer, unsigned int count);
typedef void (*HAL_ConstBufferCallback)(const char* name, void* param,
const unsigned char* buffer,
unsigned int count);
namespace hal {
struct NotifyListener {
NotifyListener() = default;
NotifyListener(void* param_, HAL_NotifyCallback callback_)
template <typename CallbackFunction>
struct HalCallbackListener {
HalCallbackListener() = default;
HalCallbackListener(void* param_, CallbackFunction callback_)
: callback(callback_), param(param_) {}
explicit operator bool() const { return callback != nullptr; }
HAL_NotifyCallback callback;
CallbackFunction callback;
void* param;
};
} // namespace hal

View File

@@ -8,7 +8,6 @@
#pragma once
#include <memory>
#include <mutex>
#include <queue>
#include <vector>
@@ -17,52 +16,123 @@
namespace hal {
// Vector which provides an integrated freelist for removal and reuse of
// individual elements.
class NotifyListenerVector {
template <typename ListenerType>
class HalCallbackListenerVectorImpl {
struct private_init {};
public:
typedef typename std::vector<NotifyListener>::size_type size_type;
typedef typename std::vector<HalCallbackListener<ListenerType>>::size_type
size_type;
// Constructor for creating copies of the vector
NotifyListenerVector(const NotifyListenerVector*, const private_init&);
HalCallbackListenerVectorImpl(const HalCallbackListenerVectorImpl* copyFrom,
const private_init&);
// Delete all default constructors so they cannot be used
NotifyListenerVector& operator=(const NotifyListenerVector&) = delete;
NotifyListenerVector() = delete;
NotifyListenerVector(const NotifyListenerVector&) = delete;
HalCallbackListenerVectorImpl& operator=(
const HalCallbackListenerVectorImpl&) = delete;
HalCallbackListenerVectorImpl() = delete;
HalCallbackListenerVectorImpl(const HalCallbackListenerVectorImpl&) = delete;
// Create a new vector with a single callback inside of it
NotifyListenerVector(void* param, HAL_NotifyCallback callback,
unsigned int* newUid);
HalCallbackListenerVectorImpl(void* param, ListenerType callback,
unsigned int* newUid) {
*newUid = emplace_back_impl(param, callback);
}
size_type size() const { return m_vector.size(); }
NotifyListener& operator[](size_type i) { return m_vector[i]; }
const NotifyListener& operator[](size_type i) const { return m_vector[i]; }
HalCallbackListener<ListenerType>& operator[](size_type i) {
return m_vector[i];
}
const HalCallbackListener<ListenerType>& operator[](size_type i) const {
return m_vector[i];
}
// Add a new NotifyListener to a copy of the vector. If there are elements on
// the freelist,
// reuses the last one; otherwise adds to the end of the vector.
// Returns the resulting element index (+1).
std::shared_ptr<NotifyListenerVector> emplace_back(
void* param, HAL_NotifyCallback callback, unsigned int* newUid);
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> emplace_back(
void* param, ListenerType callback, unsigned int* newUid);
// Removes the identified element by replacing it with a default-constructed
// one. The element is added to the freelist for later reuse. Returns a copy
std::shared_ptr<NotifyListenerVector> erase(unsigned int uid);
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> erase(
unsigned int uid);
private:
std::vector<NotifyListener> m_vector;
std::vector<HalCallbackListener<ListenerType>> m_vector;
std::vector<unsigned int> m_free;
// Add a new NotifyListener to the vector. If there are elements on the
// freelist,
// reuses the last one; otherwise adds to the end of the vector.
// Returns the resulting element index (+1).
unsigned int emplace_back_impl(void* param, HAL_NotifyCallback callback);
unsigned int emplace_back_impl(void* param, ListenerType callback);
// Removes the identified element by replacing it with a default-constructed
// one. The element is added to the freelist for later reuse.
void erase_impl(unsigned int uid);
};
template <typename ListenerType>
HalCallbackListenerVectorImpl<ListenerType>::HalCallbackListenerVectorImpl(
const HalCallbackListenerVectorImpl<ListenerType>* copyFrom,
const private_init&)
: m_vector(copyFrom->m_vector), m_free(copyFrom->m_free) {}
template <typename ListenerType>
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
HalCallbackListenerVectorImpl<ListenerType>::emplace_back(
void* param, ListenerType callback, unsigned int* newUid) {
auto newVector =
std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
this, private_init());
newVector->m_vector = m_vector;
newVector->m_free = m_free;
*newUid = newVector->emplace_back_impl(param, callback);
return newVector;
}
template <typename ListenerType>
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
HalCallbackListenerVectorImpl<ListenerType>::erase(unsigned int uid) {
auto newVector =
std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
this, private_init());
newVector->m_vector = m_vector;
newVector->m_free = m_free;
newVector->erase_impl(uid);
return newVector;
}
template <typename ListenerType>
unsigned int HalCallbackListenerVectorImpl<ListenerType>::emplace_back_impl(
void* param, ListenerType callback) {
unsigned int uid;
if (m_free.empty()) {
uid = m_vector.size();
m_vector.emplace_back(param, callback);
} else {
uid = m_free.back();
m_free.pop_back();
m_vector[uid] = HalCallbackListener<ListenerType>(param, callback);
}
return uid + 1;
}
template <typename ListenerType>
void HalCallbackListenerVectorImpl<ListenerType>::erase_impl(unsigned int uid) {
--uid;
if (uid >= m_vector.size() || !m_vector[uid]) return;
m_free.push_back(uid);
m_vector[uid] = HalCallbackListener<ListenerType>();
}
typedef HalCallbackListenerVectorImpl<HAL_NotifyCallback> NotifyListenerVector;
typedef HalCallbackListenerVectorImpl<HAL_BufferCallback> BufferListenerVector;
typedef HalCallbackListenerVectorImpl<HAL_ConstBufferCallback>
ConstBufferListenerVector;
} // namespace hal

View File

@@ -74,6 +74,16 @@ void HALSIM_CancelPCMCompressorCurrentCallback(int32_t index, int32_t uid);
double HALSIM_GetPCMCompressorCurrent(int32_t index);
void HALSIM_SetPCMCompressorCurrent(int32_t index, double compressorCurrent);
void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -46,6 +46,11 @@ void HALSIM_CancelPDPCurrentCallback(int32_t index, int32_t channel,
double HALSIM_GetPDPCurrent(int32_t index, int32_t channel);
void HALSIM_SetPDPCurrent(int32_t index, int32_t channel, double current);
void HALSIM_RegisterPDPAllNonCurrentCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -60,6 +60,9 @@ void HALSIM_CancelPWMZeroLatchCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetPWMZeroLatch(int32_t index);
void HALSIM_SetPWMZeroLatch(int32_t index, HAL_Bool zeroLatch);
void HALSIM_RegisterPWMAllCallbacks(int32_t index, HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -47,6 +47,10 @@ void HALSIM_CancelRelayReverseCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetRelayReverse(int32_t index);
void HALSIM_SetRelayReverse(int32_t index, HAL_Bool reverse);
void HALSIM_RegisterRelayAllCallcbaks(int32_t index,
HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -133,6 +133,10 @@ void HALSIM_CancelRoboRioUserFaults3V3Callback(int32_t index, int32_t uid);
int32_t HALSIM_GetRoboRioUserFaults3V3(int32_t index);
void HALSIM_SetRoboRioUserFaults3V3(int32_t index, int32_t userFaults3V3);
void HALSIM_RegisterRoboRioAllCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -53,6 +53,11 @@ void HALSIM_CancelSPIAccelerometerZCallback(int32_t index, int32_t uid);
double HALSIM_GetSPIAccelerometerZ(int32_t index);
void HALSIM_SetSPIAccelerometerZ(int32_t index, double z);
void HALSIM_RegisterSPIAccelerometerAllCallbcaks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
}
} // extern "C"
#endif

View File

@@ -0,0 +1,52 @@
/*----------------------------------------------------------------------------*/
/* 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
#include "HAL/HAL.h"
#include "NotifyListener.h"
#ifdef __cplusplus
extern "C" {
#endif
void HALSIM_ResetSPIData(int32_t index);
int32_t HALSIM_RegisterSPIInitializedCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelSPIInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetSPIInitialized(int32_t index);
void HALSIM_SetSPIInitialized(int32_t index, HAL_Bool initialized);
int32_t HALSIM_RegisterSPIReadCallback(int32_t index,
HAL_BufferCallback callback,
void* param);
void HALSIM_CancelSPIReadCallback(int32_t index, int32_t uid);
int32_t HALSIM_RegisterSPIWriteCallback(int32_t index,
HAL_ConstBufferCallback callback,
void* param);
void HALSIM_CancelSPIWriteCallback(int32_t index, int32_t uid);
int32_t HALSIM_RegisterSPIResetAccumulatorCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelSPIResetAccumulatorCallback(int32_t index, int32_t uid);
int32_t HALSIM_RegisterSPISetAccumulatorCallback(int32_t index,
HAL_BufferCallback callback,
void* param);
void HALSIM_CancelSPISetAccumulatorCallback(int32_t index, int32_t uid);
void HALSIM_SetSPISetAccumulatorValue(int32_t index, int64_t value);
int64_t HALSIM_GetSPIGetAccumulatorValue(int32_t index);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -1,243 +0,0 @@
/**
* @file ctre_frames.h
* CAN Encoder/Decoder Structures for CTRE devices.
*/
#ifndef CTRE_FRAMES_H
#define CTRE_FRAMES_H
/** control */
typedef struct _TALON_Control_1_General_10ms_t {
unsigned TokenH:8;
unsigned TokenL:8;
unsigned DemandH:8;
unsigned DemandM:8;
unsigned DemandL:8;
unsigned ProfileSlotSelect:1;
unsigned FeedbackDeviceSelect:4;
unsigned OverrideLimitSwitchEn:3;
unsigned RevFeedbackSensor:1;
unsigned RevMotDuringCloseLoopEn:1;
unsigned OverrideBrakeType:2;
unsigned ModeSelect:4;
unsigned RampThrottle:8;
} TALON_Control_1_General_10ms_t ;
/* TALON_Control_2_Rates_OneShot_t removed since it has been deprecated */
typedef struct _TALON_Control_3_ClearFlags_OneShot_t {
unsigned ZeroFeedbackSensor:1;
unsigned ClearStickyFaults:1;
} TALON_Control_3_ClearFlags_OneShot_t ;
typedef struct _TALON_Control_5_General_10ms_t {
unsigned ThrottleBump_h3:3;
unsigned ReservedZero:5;
unsigned ThrottleBump_l8:8;
unsigned DemandH:8;
unsigned DemandM:8;
unsigned DemandL:8;
unsigned ProfileSlotSelect:1;
unsigned FeedbackDeviceSelect:4;
unsigned OverrideLimitSwitchEn:3;
unsigned RevFeedbackSensor:1;
unsigned RevMotDuringCloseLoopEn:1;
unsigned OverrideBrakeType:2;
unsigned ModeSelect:4;
unsigned RampThrottle:8;
} TALON_Control_5_General_10ms_t ;
typedef struct _TALON_Control_6_MotProfAddTrajPoint_t {
unsigned huffCode:2; //!< Compression coding
unsigned NextPt_VelOnly:1;
unsigned NextPt_IsLast:1;
unsigned reserved0:2;
unsigned NextPt_ZeroPosition:1;
unsigned NextPt_ProfileSlotSelect:1;
unsigned Idx:4;
unsigned reserved1:4;
unsigned restOfFrame0:8;
unsigned restOfFrame1:8;
unsigned restOfFrame2:8;
unsigned restOfFrame3:8;
unsigned restOfFrame4:8;
unsigned restOfFrame5:8;
} TALON_Control_6_MotProfAddTrajPoint_t;
typedef struct _TALON_Control_6_MotProfAddTrajPoint_huff0_t {
unsigned huffCode_expect_0:2; //!< Compression coding
unsigned NextPt_VelOnly:1;
unsigned NextPt_IsLast:1;
unsigned reserved0:2;
unsigned NextPt_ZeroPosition:1;
unsigned NextPt_ProfileSlotSelect:1;
unsigned Idx:4;
unsigned reserved1:4;
unsigned NextPt_DurationMs:8;
unsigned NextPt_VelocityH:8;
unsigned NextPt_VelocityL:8;
unsigned NextPt_PositionH:8;
unsigned NextPt_PositionM:8;
unsigned NextPt_PositionL:8;
} TALON_Control_6_MotProfAddTrajPoint_huff0_t;
typedef struct _TALON_Control_6_MotProfAddTrajPoint_huff1_t {
unsigned huffCode_expect_1:2; //!< Compression coding
unsigned NextPt_VelOnly:1;
unsigned NextPt_IsLast:1;
unsigned reserved0:2;
unsigned NextPt_ZeroPosition:1;
unsigned NextPt_ProfileSlotSelect:1;
unsigned Idx:4;
unsigned reserved1:4;
unsigned NextPt_DurationMs:8;
unsigned NextPt_SameVelocityH:8;
unsigned NextPt_SameVelocityL:8;
unsigned NextPt_DeltaPositionH:8;
unsigned NextPt_DeltaPositionL:8;
unsigned NextPt_Count:8;
} TALON_Control_6_MotProfAddTrajPoint_huff1_t;
/** status */
typedef struct _TALON_Status_1_General_10ms_t {
unsigned CloseLoopErrH:8;
unsigned CloseLoopErrM:8;
unsigned CloseLoopErrL:8;
unsigned AppliedThrottle_h3:3;
unsigned Fault_RevSoftLim:1;
unsigned Fault_ForSoftLim:1;
unsigned TokLocked:1;
unsigned LimitSwitchClosedRev:1;
unsigned LimitSwitchClosedFor:1;
unsigned AppliedThrottle_l8:8;
unsigned ModeSelect_h1:1;
unsigned FeedbackDeviceSelect:4;
unsigned LimitSwitchEn:3;
unsigned Fault_HardwareFailure:1;
unsigned Fault_RevLim:1;
unsigned Fault_ForLim:1;
unsigned Fault_UnderVoltage:1;
unsigned Fault_OverTemp:1;
unsigned ModeSelect_b3:3;
unsigned TokenSeed:8;
} TALON_Status_1_General_10ms_t ;
typedef struct _TALON_Status_2_Feedback_20ms_t {
unsigned SensorPositionH:8;
unsigned SensorPositionM:8;
unsigned SensorPositionL:8;
unsigned SensorVelocityH:8;
unsigned SensorVelocityL:8;
unsigned Current_h8:8;
unsigned StckyFault_RevSoftLim:1;
unsigned StckyFault_ForSoftLim:1;
unsigned StckyFault_RevLim:1;
unsigned StckyFault_ForLim:1;
unsigned StckyFault_UnderVoltage:1;
unsigned StckyFault_OverTemp:1;
unsigned Current_l2:2;
unsigned reserved:3;
unsigned Cmd5Allowed:1;
unsigned VelDiv4:1;
unsigned PosDiv8:1;
unsigned ProfileSlotSelect:1;
unsigned BrakeIsEnabled:1;
} TALON_Status_2_Feedback_20ms_t ;
typedef struct _TALON_Status_3_Enc_100ms_t {
unsigned EncPositionH:8;
unsigned EncPositionM:8;
unsigned EncPositionL:8;
unsigned EncVelH:8;
unsigned EncVelL:8;
unsigned EncIndexRiseEventsH:8;
unsigned EncIndexRiseEventsL:8;
unsigned reserved:3;
unsigned VelDiv4:1;
unsigned PosDiv8:1;
unsigned QuadIdxpin:1;
unsigned QuadBpin:1;
unsigned QuadApin:1;
} TALON_Status_3_Enc_100ms_t ;
typedef struct _TALON_Status_4_AinTempVbat_100ms_t {
unsigned AnalogInWithOvH:8;
unsigned AnalogInWithOvM:8;
unsigned AnalogInWithOvL:8;
unsigned AnalogInVelH:8;
unsigned AnalogInVelL:8;
unsigned Temp:8;
unsigned BatteryV:8;
unsigned reserved:6;
unsigned VelDiv4:1;
unsigned PosDiv8:1;
} TALON_Status_4_AinTempVbat_100ms_t ;
typedef struct _TALON_Status_5_Startup_OneShot_t {
unsigned ResetCountH:8;
unsigned ResetCountL:8;
unsigned ResetFlagsH:8;
unsigned ResetFlagsL:8;
unsigned FirmVersH:8;
unsigned FirmVersL:8;
} TALON_Status_5_Startup_OneShot_t ;
typedef struct _TALON_Status_6_Eol_t {
unsigned currentAdcUncal_h2:2;
unsigned reserved1:5;
unsigned SpiCsPin_GadgeteerPin6:1;
unsigned currentAdcUncal_l8:8;
unsigned tempAdcUncal_h2:2;
unsigned reserved2:6;
unsigned tempAdcUncal_l8:8;
unsigned vbatAdcUncal_h2:2;
unsigned reserved3:6;
unsigned vbatAdcUncal_l8:8;
unsigned analogAdcUncal_h2:2;
unsigned reserved4:6;
unsigned analogAdcUncal_l8:8;
} TALON_Status_6_Eol_t ;
typedef struct _TALON_Status_7_Debug_200ms_t {
unsigned TokenizationFails_h8:8;
unsigned TokenizationFails_l8:8;
unsigned LastFailedToken_h8:8;
unsigned LastFailedToken_l8:8;
unsigned TokenizationSucceses_h8:8;
unsigned TokenizationSucceses_l8:8;
} TALON_Status_7_Debug_200ms_t ;
typedef struct _TALON_Status_8_PulseWid_100ms_t {
unsigned PulseWidPositionH:8;
unsigned PulseWidPositionM:8;
unsigned PulseWidPositionL:8;
unsigned reserved:6;
unsigned VelDiv4:1;
unsigned PosDiv8:1;
unsigned PeriodUsM8:8;
unsigned PeriodUsL8:8;
unsigned PulseWidVelH:8;
unsigned PulseWidVelL:8;
} TALON_Status_8_PulseWid_100ms_t ;
typedef struct _TALON_Status_9_MotProfBuffer_100ms_t {
unsigned ActTraj_IsValid:1; //!< '1' if other ActTraj_* signals are valid. '0' if there is no active trajectory pt.
unsigned ActTraj_ProfileSlotSelect:1;
unsigned ActTraj_VelOnly:1;
unsigned ActTraj_IsLast:1;
unsigned OutputType:2;
unsigned HasUnderrun:1;
unsigned IsUnderrun:1;
unsigned NextID:4;
unsigned reserved1:3;
unsigned BufferIsFull:1;
unsigned Count:8;
unsigned ActTraj_VelocityH:8;
unsigned ActTraj_VelocityL:8;
unsigned ActTraj_PositionH:8;
unsigned ActTraj_PositionM:8;
unsigned ActTraj_PositionL:8;
} TALON_Status_9_MotProfBuffer_100ms_t ;
typedef struct _TALON_Param_Request_t {
unsigned ParamEnum:8;
} TALON_Param_Request_t ;
typedef struct _TALON_Param_Response_t {
unsigned ParamEnum:8;
unsigned ParamValueL:8;
unsigned ParamValueML:8;
unsigned ParamValueMH:8;
unsigned ParamValueH:8;
} TALON_Param_Response_t ;
#endif /* CTRE_FRAMES_H */

View File

@@ -1,34 +0,0 @@
/*----------------------------------------------------------------------------*/
/* 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/cpp/priority_mutex.h"
#if defined(__linux__)
using namespace hal;
void priority_recursive_mutex::lock() { pthread_mutex_lock(&m_mutex); }
void priority_recursive_mutex::unlock() { pthread_mutex_unlock(&m_mutex); }
bool priority_recursive_mutex::try_lock() noexcept {
return !pthread_mutex_trylock(&m_mutex);
}
pthread_mutex_t* priority_recursive_mutex::native_handle() { return &m_mutex; }
void priority_mutex::lock() { pthread_mutex_lock(&m_mutex); }
void priority_mutex::unlock() { pthread_mutex_unlock(&m_mutex); }
bool priority_mutex::try_lock() noexcept {
return !pthread_mutex_trylock(&m_mutex);
}
pthread_mutex_t* priority_mutex::native_handle() { return &m_mutex; }
#endif

View File

@@ -8,19 +8,19 @@
#include "HAL/handles/HandlesInternal.h"
#include <algorithm>
#include <mutex>
#include <llvm/SmallVector.h>
#include <support/mutex.h>
namespace hal {
static llvm::SmallVector<HandleBase*, 32> globalHandles;
static std::mutex& GetGlobalHandleMutex() {
static std::mutex globalHandleMutex;
static wpi::mutex& GetGlobalHandleMutex() {
static wpi::mutex globalHandleMutex;
return globalHandleMutex;
}
HandleBase::HandleBase() {
std::lock_guard<std::mutex> lock(GetGlobalHandleMutex());
std::lock_guard<wpi::mutex> lock(GetGlobalHandleMutex());
auto index = std::find(globalHandles.begin(), globalHandles.end(), this);
if (index == globalHandles.end()) {
globalHandles.push_back(this);
@@ -30,7 +30,7 @@ HandleBase::HandleBase() {
}
HandleBase::~HandleBase() {
std::lock_guard<std::mutex> lock(GetGlobalHandleMutex());
std::lock_guard<wpi::mutex> lock(GetGlobalHandleMutex());
auto index = std::find(globalHandles.begin(), globalHandles.end(), this);
if (index != globalHandles.end()) {
*index = nullptr;
@@ -45,7 +45,7 @@ void HandleBase::ResetHandles() {
}
void HandleBase::ResetGlobalHandles() {
std::unique_lock<std::mutex> lock(GetGlobalHandleMutex());
std::unique_lock<wpi::mutex> lock(GetGlobalHandleMutex());
for (auto&& i : globalHandles) {
if (i != nullptr) {
lock.unlock();

View File

@@ -22,4 +22,4 @@ void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
double HAL_GetAccelerometerX(void) { return SimAccelerometerData[0].GetX(); }
double HAL_GetAccelerometerY(void) { return SimAccelerometerData[0].GetY(); }
double HAL_GetAccelerometerZ(void) { return SimAccelerometerData[0].GetZ(); }
}
} // extern "C"

View File

@@ -103,4 +103,4 @@ void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
*count = SimAnalogInData[port->channel].GetAccumulatorCount();
*value = SimAnalogInData[port->channel].GetAccumulatorValue();
}
}
} // extern "C"

View File

@@ -21,7 +21,7 @@ struct AnalogGyro {
HAL_AnalogInputHandle handle;
uint8_t index;
};
}
} // namespace
using namespace hal;
@@ -132,4 +132,4 @@ double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status) {
return 0;
}
}
} // extern "C"

View File

@@ -168,4 +168,4 @@ int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
return 0;
}
}
} // extern "C"

View File

@@ -14,4 +14,4 @@ namespace hal {
IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort, kNumAnalogInputs,
HAL_HandleEnum::AnalogInput>
analogInputHandles;
}
} // namespace hal

View File

@@ -19,7 +19,7 @@ namespace {
struct AnalogOutput {
uint8_t channel;
};
}
} // namespace
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
@@ -85,4 +85,4 @@ double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
return SimAnalogOutData[port->channel].GetVoltage();
}
}
} // extern "C"

View File

@@ -22,7 +22,7 @@ struct AnalogTrigger {
uint8_t index;
HAL_Bool trigState;
};
}
} // namespace
using namespace hal;

View File

@@ -25,4 +25,4 @@ void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
uint32_t* txFullCount, uint32_t* receiveErrorCount,
uint32_t* transmitErrorCount, int32_t* status) {}
}
} // extern "C"

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