mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-26 01:51:41 +00:00
Compare commits
76 Commits
v2018.1.1-
...
v2018.1.1-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86ac70a125 | ||
|
|
3c3a448d47 | ||
|
|
8744511f1d | ||
|
|
7729dd972f | ||
|
|
8b7aa61091 | ||
|
|
88a6b4ac38 | ||
|
|
217b1a2259 | ||
|
|
d2e7a90f41 | ||
|
|
8bd48d6c34 | ||
|
|
1fa0adb091 | ||
|
|
f615e68a43 | ||
|
|
aa4f0ef4f8 | ||
|
|
b42285fddd | ||
|
|
8106fbdbea | ||
|
|
942ba51765 | ||
|
|
33a08d5b34 | ||
|
|
4e3af0756d | ||
|
|
5078f6c92a | ||
|
|
899892c119 | ||
|
|
54326311ad | ||
|
|
fe53dd2f28 | ||
|
|
ab137abab5 | ||
|
|
001dedf3b2 | ||
|
|
f9bece2ffb | ||
|
|
3befc7015b | ||
|
|
de63e1c8a1 | ||
|
|
a76b1aa800 | ||
|
|
350b741adc | ||
|
|
64bfdc1a69 | ||
|
|
65cc85f68d | ||
|
|
6a00dc7976 | ||
|
|
e9e407a87d | ||
|
|
59c4984ed6 | ||
|
|
b428d1e4b3 | ||
|
|
0994364591 | ||
|
|
0b8d3f0260 | ||
|
|
52eba45c51 | ||
|
|
9090a82ef5 | ||
|
|
2a69a4c7dc | ||
|
|
9d2393f97e | ||
|
|
dae619b006 | ||
|
|
9c06d2878b | ||
|
|
e3a2abdf97 | ||
|
|
7867e906e9 | ||
|
|
65a044f633 | ||
|
|
cbd08a1e11 | ||
|
|
e308dd28f3 | ||
|
|
fa0b4428e9 | ||
|
|
26a36779a6 | ||
|
|
dfc0656e5c | ||
|
|
0f3f5218ad | ||
|
|
34c44b7ae9 | ||
|
|
7a250a1b93 | ||
|
|
a338ee8be0 | ||
|
|
c9d440f338 | ||
|
|
a00b2449db | ||
|
|
5c659fdcdf | ||
|
|
d36d72bd4f | ||
|
|
614093c0c4 | ||
|
|
12c4418bda | ||
|
|
0431cf97ff | ||
|
|
ba879f4663 | ||
|
|
96de0b5b11 | ||
|
|
85157a56c3 | ||
|
|
029246ed28 | ||
|
|
6377ab774d | ||
|
|
05e581f409 | ||
|
|
c73dd807e1 | ||
|
|
7a0dd9baa9 | ||
|
|
11f37683c3 | ||
|
|
5af0c9c101 | ||
|
|
259461aee9 | ||
|
|
d214b36786 | ||
|
|
4a07f0380f | ||
|
|
7f46b50b21 | ||
|
|
303c259b89 |
@@ -31,6 +31,7 @@ modifiableFileExclude {
|
||||
includeOtherLibs {
|
||||
^HAL/
|
||||
^llvm/
|
||||
^networktables/
|
||||
^opencv2/
|
||||
^support/
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.3.0'
|
||||
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.5.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ def windowsLinkerArgs = [ '/DEBUG:FULL' ]
|
||||
def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ]
|
||||
|
||||
def linuxCompilerArgs = ['-std=c++1y', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g',
|
||||
'-Wno-unused-parameter', '-fPIC', '-rdynamic', '-pthread']
|
||||
'-Wno-unused-parameter', '-Wno-error=deprecated-declarations', '-fPIC', '-rdynamic', '-pthread']
|
||||
def linuxLinkerArgs = ['-rdynamic', '-pthread']
|
||||
def linuxReleaseCompilerArgs = ['-O2']
|
||||
def linuxDebugCompilerArgs = ['-O0']
|
||||
|
||||
@@ -5,17 +5,6 @@ apply plugin: 'edu.wpi.first.NativeUtils'
|
||||
|
||||
apply from: '../config.gradle'
|
||||
|
||||
ext.addHalCompilerArguments = { binary->
|
||||
if (binary.targetPlatform.architecture.name == 'athena') {
|
||||
tasks.withType(CppCompile) {
|
||||
binary.cppCompiler.args "-DCONFIG_ATHENA"
|
||||
}
|
||||
}
|
||||
tasks.withType(CppCompile) {
|
||||
binary.cppCompiler.args "-DNAMESPACED_PRIORITY"
|
||||
}
|
||||
}
|
||||
|
||||
ext.addHalToLinker = { binary->
|
||||
if (binary.targetPlatform.architecture.name == 'athena') {
|
||||
binary.lib project: ':hal', library: 'halAthena', linkage: 'shared'
|
||||
@@ -172,7 +161,6 @@ model {
|
||||
}
|
||||
binaries {
|
||||
all {
|
||||
project.addHalCompilerArguments(it)
|
||||
project(':ni-libraries').addNiLibrariesToLinker(it)
|
||||
}
|
||||
withType(GoogleTestTestSuiteBinarySpec) {
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
using namespace hal;
|
||||
|
||||
// The 7-bit I2C address with a 0 "send" bit
|
||||
static const uint8_t kSendAddress = (0x1c << 1) | 0;
|
||||
static constexpr uint8_t kSendAddress = (0x1c << 1) | 0;
|
||||
|
||||
// The 7-bit I2C address with a 1 "receive" bit
|
||||
static const uint8_t kReceiveAddress = (0x1c << 1) | 1;
|
||||
static constexpr uint8_t kReceiveAddress = (0x1c << 1) | 1;
|
||||
|
||||
static const uint8_t kControlTxRx = 1;
|
||||
static const uint8_t kControlStart = 2;
|
||||
static const uint8_t kControlStop = 4;
|
||||
static constexpr uint8_t kControlTxRx = 1;
|
||||
static constexpr uint8_t kControlStart = 2;
|
||||
static constexpr uint8_t kControlStop = 4;
|
||||
|
||||
static std::unique_ptr<tAccel> accel;
|
||||
static HAL_AccelerometerRange accelerometerRange;
|
||||
@@ -77,6 +77,12 @@ enum Register {
|
||||
kReg_OffZ = 0x31
|
||||
};
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAccelerometer() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
namespace hal {
|
||||
|
||||
static void writeRegister(Register reg, uint8_t data);
|
||||
@@ -91,6 +97,8 @@ static void initializeAccelerometer() {
|
||||
if (!accel) {
|
||||
accel.reset(tAccel::create(&status));
|
||||
|
||||
accelerometerRange = HAL_AccelerometerRange::HAL_AccelerometerRange_k2G;
|
||||
|
||||
// Enable I2C
|
||||
accel->writeCNFG(1, &status);
|
||||
|
||||
@@ -219,7 +227,7 @@ void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
|
||||
*
|
||||
* This is a floating point value in units of 1 g-force
|
||||
*/
|
||||
double HAL_GetAccelerometerX() {
|
||||
double HAL_GetAccelerometerX(void) {
|
||||
initializeAccelerometer();
|
||||
|
||||
int32_t raw =
|
||||
@@ -232,7 +240,7 @@ double HAL_GetAccelerometerX() {
|
||||
*
|
||||
* This is a floating point value in units of 1 g-force
|
||||
*/
|
||||
double HAL_GetAccelerometerY() {
|
||||
double HAL_GetAccelerometerY(void) {
|
||||
initializeAccelerometer();
|
||||
|
||||
int32_t raw =
|
||||
@@ -245,7 +253,7 @@ double HAL_GetAccelerometerY() {
|
||||
*
|
||||
* This is a floating point value in units of 1 g-force
|
||||
*/
|
||||
double HAL_GetAccelerometerZ() {
|
||||
double HAL_GetAccelerometerZ(void) {
|
||||
initializeAccelerometer();
|
||||
|
||||
int32_t raw =
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogAccumulator() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
@@ -22,7 +28,7 @@ extern "C" {
|
||||
*/
|
||||
HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -55,7 +61,7 @@ void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -84,7 +90,7 @@ void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t center, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -104,7 +110,7 @@ void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t deadband, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -127,7 +133,7 @@ void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -151,7 +157,7 @@ int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -175,7 +181,7 @@ int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
|
||||
int64_t* value, int64_t* count, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
|
||||
@@ -34,8 +34,18 @@ static constexpr double kDefaultVoltsPerDegreePerSecond = 0.007;
|
||||
using namespace hal;
|
||||
|
||||
static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
|
||||
HAL_HandleEnum::AnalogGyro>
|
||||
analogGyroHandles;
|
||||
HAL_HandleEnum::AnalogGyro>* analogGyroHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogGyro() {
|
||||
static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
|
||||
HAL_HandleEnum::AnalogGyro>
|
||||
agHandles;
|
||||
analogGyroHandles = &agHandles;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
static void Wait(double seconds) {
|
||||
if (seconds < 0.0) return;
|
||||
@@ -56,13 +66,13 @@ HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
|
||||
// handle known to be correct, so no need to type check
|
||||
int16_t channel = getHandleIndex(analogHandle);
|
||||
|
||||
auto handle = analogGyroHandles.Allocate(channel, status);
|
||||
auto handle = analogGyroHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
// Initialize port structure
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) { // would only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -77,7 +87,7 @@ HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
|
||||
}
|
||||
|
||||
void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -100,13 +110,13 @@ void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
void HAL_FreeAnalogGyro(HAL_GyroHandle handle) {
|
||||
analogGyroHandles.Free(handle);
|
||||
analogGyroHandles->Free(handle);
|
||||
}
|
||||
|
||||
void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
|
||||
double voltsPerDegreePerSecond, double offset,
|
||||
int32_t center, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -121,7 +131,7 @@ void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
|
||||
void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
|
||||
double voltsPerDegreePerSecond,
|
||||
int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -131,7 +141,7 @@ void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
|
||||
}
|
||||
|
||||
void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -149,7 +159,7 @@ void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -176,7 +186,7 @@ void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
|
||||
void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
|
||||
int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -189,7 +199,7 @@ void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
|
||||
}
|
||||
|
||||
double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -211,7 +221,7 @@ double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -225,7 +235,7 @@ double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -234,7 +244,7 @@ double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
#include "HAL/handles/HandlesInternal.h"
|
||||
#include "PortsInternal.h"
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogInput() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
using namespace hal;
|
||||
|
||||
extern "C" {
|
||||
@@ -37,13 +43,13 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
HAL_AnalogInputHandle handle = analogInputHandles.Allocate(channel, status);
|
||||
HAL_AnalogInputHandle handle = analogInputHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
// Initialize port structure
|
||||
auto analog_port = analogInputHandles.Get(handle);
|
||||
auto analog_port = analogInputHandles->Get(handle);
|
||||
if (analog_port == nullptr) { // would only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -67,7 +73,7 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
|
||||
*/
|
||||
void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
|
||||
// no status, so no need to check for a proper free.
|
||||
analogInputHandles.Free(analogPortHandle);
|
||||
analogInputHandles->Free(analogPortHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +141,7 @@ double HAL_GetAnalogSampleRate(int32_t* status) {
|
||||
*/
|
||||
void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t bits, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -155,7 +161,7 @@ void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return kDefaultAverageBits;
|
||||
@@ -177,7 +183,7 @@ int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t bits, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -198,7 +204,7 @@ void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return kDefaultOversampleBits;
|
||||
@@ -219,7 +225,7 @@ int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -229,7 +235,7 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
readSelect.Channel = port->channel;
|
||||
readSelect.Averaged = false;
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
|
||||
std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
|
||||
analogInputSystem->writeReadSelect(readSelect, status);
|
||||
analogInputSystem->strobeLatchOutput(status);
|
||||
return static_cast<int16_t>(analogInputSystem->readOutput(status));
|
||||
@@ -251,7 +257,7 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -260,7 +266,7 @@ int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
readSelect.Channel = port->channel;
|
||||
readSelect.Averaged = true;
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
|
||||
std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
|
||||
analogInputSystem->writeReadSelect(readSelect, status);
|
||||
analogInputSystem->strobeLatchOutput(status);
|
||||
return static_cast<int32_t>(analogInputSystem->readOutput(status));
|
||||
@@ -351,7 +357,7 @@ int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -373,7 +379,7 @@ int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
|
||||
@@ -21,8 +21,8 @@ wpi::mutex analogRegisterWindowMutex;
|
||||
std::unique_ptr<tAI> analogInputSystem;
|
||||
std::unique_ptr<tAO> analogOutputSystem;
|
||||
|
||||
IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort, kNumAnalogInputs,
|
||||
HAL_HandleEnum::AnalogInput>
|
||||
IndexedHandleResource<HAL_AnalogInputHandle, ::hal::AnalogPort,
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
|
||||
analogInputHandles;
|
||||
|
||||
static int32_t analogNumChannelsToActivate = 0;
|
||||
@@ -31,12 +31,21 @@ static std::atomic<bool> analogSystemInitialized{false};
|
||||
|
||||
bool analogSampleRateSet = false;
|
||||
|
||||
namespace init {
|
||||
void InitializeAnalogInternal() {
|
||||
static IndexedHandleResource<HAL_AnalogInputHandle, ::hal::AnalogPort,
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
|
||||
alH;
|
||||
analogInputHandles = &alH;
|
||||
}
|
||||
} // namespace init
|
||||
|
||||
/**
|
||||
* Initialize the analog System.
|
||||
*/
|
||||
void initializeAnalog(int32_t* status) {
|
||||
if (analogSystemInitialized) return;
|
||||
std::lock_guard<wpi::mutex> sync(analogRegisterWindowMutex);
|
||||
std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
|
||||
if (analogSystemInitialized) return;
|
||||
analogInputSystem.reset(tAI::create(status));
|
||||
analogOutputSystem.reset(tAO::create(status));
|
||||
|
||||
@@ -24,7 +24,7 @@ constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock
|
||||
constexpr int32_t kDefaultOversampleBits = 0;
|
||||
constexpr int32_t kDefaultAverageBits = 7;
|
||||
constexpr double kDefaultSampleRate = 50000.0;
|
||||
static const uint32_t kAccumulatorChannels[] = {0, 1};
|
||||
static constexpr uint32_t kAccumulatorChannels[] = {0, 1};
|
||||
|
||||
extern std::unique_ptr<tAI> analogInputSystem;
|
||||
extern std::unique_ptr<tAO> analogOutputSystem;
|
||||
@@ -37,7 +37,7 @@ struct AnalogPort {
|
||||
};
|
||||
|
||||
extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
|
||||
analogInputHandles;
|
||||
|
||||
int32_t getAnalogNumActiveChannels(int32_t* status);
|
||||
|
||||
@@ -24,9 +24,20 @@ struct AnalogOutput {
|
||||
} // namespace
|
||||
|
||||
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
|
||||
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
|
||||
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>*
|
||||
analogOutputHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogOutput() {
|
||||
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
|
||||
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
|
||||
aoH;
|
||||
analogOutputHandles = &aoH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
@@ -44,12 +55,13 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
HAL_AnalogOutputHandle handle = analogOutputHandles.Allocate(channel, status);
|
||||
HAL_AnalogOutputHandle handle =
|
||||
analogOutputHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = analogOutputHandles.Get(handle);
|
||||
auto port = analogOutputHandles->Get(handle);
|
||||
if (port == nullptr) { // would only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -61,7 +73,7 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
|
||||
|
||||
void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
|
||||
// no status, so no need to check for a proper free.
|
||||
analogOutputHandles.Free(analogOutputHandle);
|
||||
analogOutputHandles->Free(analogOutputHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +89,7 @@ HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
|
||||
|
||||
void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
|
||||
double voltage, int32_t* status) {
|
||||
auto port = analogOutputHandles.Get(analogOutputHandle);
|
||||
auto port = analogOutputHandles->Get(analogOutputHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -95,7 +107,7 @@ void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
|
||||
|
||||
double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogOutputHandles.Get(analogOutputHandle);
|
||||
auto port = analogOutputHandles->Get(analogOutputHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
|
||||
@@ -27,25 +27,37 @@ struct AnalogTrigger {
|
||||
} // namespace
|
||||
|
||||
static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
|
||||
kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>
|
||||
kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>*
|
||||
analogTriggerHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogTrigger() {
|
||||
static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
|
||||
kNumAnalogTriggers,
|
||||
HAL_HandleEnum::AnalogTrigger>
|
||||
atH;
|
||||
analogTriggerHandles = &atH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
|
||||
HAL_AnalogInputHandle portHandle, int32_t* index, int32_t* status) {
|
||||
// ensure we are given a valid and active AnalogInput handle
|
||||
auto analog_port = analogInputHandles.Get(portHandle);
|
||||
auto analog_port = analogInputHandles->Get(portHandle);
|
||||
if (analog_port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
HAL_AnalogTriggerHandle handle = analogTriggerHandles.Allocate();
|
||||
HAL_AnalogTriggerHandle handle = analogTriggerHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto trigger = analogTriggerHandles.Get(handle);
|
||||
auto trigger = analogTriggerHandles->Get(handle);
|
||||
if (trigger == nullptr) { // would only occur on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -61,14 +73,14 @@ HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
|
||||
|
||||
void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
int32_t* status) {
|
||||
analogTriggerHandles.Free(analogTriggerHandle);
|
||||
analogTriggerHandles->Free(analogTriggerHandle);
|
||||
// caller owns the analog input handle.
|
||||
}
|
||||
|
||||
void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
int32_t lower, int32_t upper,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -87,7 +99,7 @@ void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
void HAL_SetAnalogTriggerLimitsVoltage(
|
||||
HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -111,7 +123,7 @@ void HAL_SetAnalogTriggerLimitsVoltage(
|
||||
*/
|
||||
void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
HAL_Bool useAveragedValue, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -132,7 +144,7 @@ void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
*/
|
||||
void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
HAL_Bool useFilteredValue, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -152,7 +164,7 @@ void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
*/
|
||||
HAL_Bool HAL_GetAnalogTriggerInWindow(
|
||||
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -169,7 +181,7 @@ HAL_Bool HAL_GetAnalogTriggerInWindow(
|
||||
*/
|
||||
HAL_Bool HAL_GetAnalogTriggerTriggerState(
|
||||
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -184,7 +196,7 @@ HAL_Bool HAL_GetAnalogTriggerTriggerState(
|
||||
HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
HAL_AnalogTriggerType type,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
#include <FRC_NetworkCommunication/CANSessionMux.h>
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCAN() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCompressor() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeConstants() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
int32_t HAL_GetSystemClockTicksPerMicrosecond(void) {
|
||||
|
||||
@@ -25,19 +25,29 @@ struct Counter {
|
||||
} // namespace
|
||||
|
||||
static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
|
||||
HAL_HandleEnum::Counter>
|
||||
counterHandles;
|
||||
HAL_HandleEnum::Counter>* counterHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCounter() {
|
||||
static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
|
||||
HAL_HandleEnum::Counter>
|
||||
ch;
|
||||
counterHandles = &ch;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
|
||||
int32_t* status) {
|
||||
auto handle = counterHandles.Allocate();
|
||||
auto handle = counterHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) { // out of resources
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto counter = counterHandles.Get(handle);
|
||||
auto counter = counterHandles->Get(handle);
|
||||
if (counter == nullptr) { // would only occur on thread issues
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -52,12 +62,12 @@ HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
|
||||
}
|
||||
|
||||
void HAL_FreeCounter(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
counterHandles.Free(counterHandle);
|
||||
counterHandles->Free(counterHandle);
|
||||
}
|
||||
|
||||
void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -73,7 +83,7 @@ void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -110,7 +120,7 @@ void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
|
||||
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
|
||||
HAL_Bool risingEdge, HAL_Bool fallingEdge,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -124,7 +134,7 @@ void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -144,7 +154,7 @@ void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -184,7 +194,7 @@ void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
|
||||
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
|
||||
HAL_Bool risingEdge, HAL_Bool fallingEdge,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -198,7 +208,7 @@ void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -216,7 +226,7 @@ void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -231,7 +241,7 @@ void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -245,7 +255,7 @@ void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
|
||||
HAL_Bool highSemiPeriod, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -264,7 +274,7 @@ void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
|
||||
double threshold, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -285,7 +295,7 @@ void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -301,7 +311,7 @@ int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
|
||||
int32_t samplesToAverage, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -318,7 +328,7 @@ void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
|
||||
* counter, just sets the current value to zero.
|
||||
*/
|
||||
void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -332,7 +342,7 @@ void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
* current value. Next time it is read, it might have a different value.
|
||||
*/
|
||||
int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -348,7 +358,7 @@ int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
* @returns The period of the last two pulses in units of seconds.
|
||||
*/
|
||||
double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
@@ -379,7 +389,7 @@ double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
*/
|
||||
void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -403,7 +413,7 @@ void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
|
||||
*/
|
||||
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
|
||||
HAL_Bool enabled, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -421,7 +431,7 @@ void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -435,7 +445,7 @@ HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
|
||||
*/
|
||||
HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -453,7 +463,7 @@ HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
|
||||
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
|
||||
HAL_Bool reverseDirection,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counterHandle);
|
||||
auto counter = counterHandles->Get(counterHandle);
|
||||
if (counter == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
|
||||
@@ -19,10 +19,25 @@ using namespace hal;
|
||||
// Create a mutex to protect changes to the digital output values
|
||||
static wpi::mutex digitalDIOMutex;
|
||||
|
||||
// Create a mutex to protect changes to the DO PWM config
|
||||
static wpi::mutex digitalPwmMutex;
|
||||
|
||||
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
|
||||
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>
|
||||
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>*
|
||||
digitalPWMHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeDIO() {
|
||||
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
|
||||
kNumDigitalPWMOutputs,
|
||||
HAL_HandleEnum::DigitalPWM>
|
||||
dpH;
|
||||
digitalPWMHandles = &dpH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
@@ -41,12 +56,12 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
|
||||
}
|
||||
|
||||
auto handle =
|
||||
digitalChannelHandles.Allocate(channel, HAL_HandleEnum::DIO, status);
|
||||
digitalChannelHandles->Allocate(channel, HAL_HandleEnum::DIO, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = digitalChannelHandles.Get(handle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -54,7 +69,7 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
|
||||
|
||||
port->channel = static_cast<uint8_t>(channel);
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
|
||||
tDIO::tOutputEnable outputEnable = digitalSystem->readOutputEnable(status);
|
||||
|
||||
@@ -110,12 +125,12 @@ HAL_Bool HAL_CheckDIOChannel(int32_t channel) {
|
||||
}
|
||||
|
||||
void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
// no status, so no need to check for a proper free.
|
||||
digitalChannelHandles.Free(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) return;
|
||||
int32_t status = 0;
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
|
||||
// Unset the SPI flag
|
||||
int32_t bitToUnset = 1 << remapSPIChannel(port->channel);
|
||||
@@ -139,13 +154,13 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
|
||||
* @return PWM Generator handle
|
||||
*/
|
||||
HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
|
||||
auto handle = digitalPWMHandles.Allocate();
|
||||
auto handle = digitalPWMHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
auto id = digitalPWMHandles.Get(handle);
|
||||
auto id = digitalPWMHandles->Get(handle);
|
||||
if (id == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -162,7 +177,7 @@ HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
|
||||
* allocateDigitalPWM()
|
||||
*/
|
||||
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
|
||||
digitalPWMHandles.Free(pwmGenerator);
|
||||
digitalPWMHandles->Free(pwmGenerator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,10 +194,8 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
|
||||
// TODO: Round in the linear rate domain.
|
||||
initializeDigital(status);
|
||||
if (*status != 0) return;
|
||||
uint8_t pwmPeriodPower = static_cast<uint8_t>(
|
||||
std::log(1.0 / (pwmSystem->readLoopTiming(status) * 0.25E-6 * rate)) /
|
||||
std::log(2.0) +
|
||||
0.5);
|
||||
uint16_t pwmPeriodPower = static_cast<uint16_t>(
|
||||
std::log(1.0 / (16 * 1.0E-6 * rate)) / std::log(2.0) + 0.5);
|
||||
digitalSystem->writePWMPeriodPower(pwmPeriodPower, status);
|
||||
}
|
||||
|
||||
@@ -194,7 +207,7 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
|
||||
*/
|
||||
void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
|
||||
double dutyCycle, int32_t* status) {
|
||||
auto port = digitalPWMHandles.Get(pwmGenerator);
|
||||
auto port = digitalPWMHandles->Get(pwmGenerator);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -205,7 +218,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
|
||||
double rawDutyCycle = 256.0 * dutyCycle;
|
||||
if (rawDutyCycle > 255.5) rawDutyCycle = 255.5;
|
||||
{
|
||||
std::lock_guard<wpi::mutex> sync(digitalPwmMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalPwmMutex);
|
||||
uint16_t pwmPeriodPower = digitalSystem->readPWMPeriodPower(status);
|
||||
if (pwmPeriodPower < 4) {
|
||||
// The resolution of the duty cycle drops close to the highest
|
||||
@@ -229,7 +242,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
|
||||
*/
|
||||
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
|
||||
int32_t channel, int32_t* status) {
|
||||
auto port = digitalPWMHandles.Get(pwmGenerator);
|
||||
auto port = digitalPWMHandles->Get(pwmGenerator);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -256,7 +269,7 @@ void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
|
||||
*/
|
||||
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -265,7 +278,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
|
||||
if (value != 0) value = 1;
|
||||
}
|
||||
{
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
tDIO::tDO currentDIO = digitalSystem->readDO(status);
|
||||
|
||||
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
|
||||
@@ -303,7 +316,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
|
||||
* @return The state of the specified channel
|
||||
*/
|
||||
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -331,7 +344,7 @@ HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
* @return The direction of the specified channel
|
||||
*/
|
||||
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -364,7 +377,7 @@ HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
*/
|
||||
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -392,7 +405,7 @@ void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
|
||||
* @return A pulse is in progress
|
||||
*/
|
||||
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -431,13 +444,13 @@ HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
|
||||
*/
|
||||
void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
|
||||
// Channels 10-15 are SPI channels, so subtract our MXP channels
|
||||
digitalSystem->writeFilterSelectHdr(port->channel - kNumDigitalMXPChannels,
|
||||
@@ -459,13 +472,13 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
|
||||
* where 0 means "none" and 1 - 3 means filter # filterIndex - 1.
|
||||
*/
|
||||
int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
|
||||
// Channels 10-15 are SPI channels, so subtract our MXP channels
|
||||
return digitalSystem->readFilterSelectHdr(
|
||||
@@ -492,7 +505,7 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
|
||||
initializeDigital(status);
|
||||
if (*status != 0) return;
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
digitalSystem->writeFilterPeriodHdr(filterIndex, value, status);
|
||||
if (*status == 0) {
|
||||
digitalSystem->writeFilterPeriodMXP(filterIndex, value, status);
|
||||
@@ -517,7 +530,7 @@ int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
|
||||
uint32_t hdrPeriod = 0;
|
||||
uint32_t mxpPeriod = 0;
|
||||
{
|
||||
std::lock_guard<wpi::mutex> sync(digitalDIOMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
|
||||
hdrPeriod = digitalSystem->readFilterPeriodHdr(filterIndex, status);
|
||||
if (*status == 0) {
|
||||
mxpPeriod = digitalSystem->readFilterPeriodMXP(filterIndex, status);
|
||||
|
||||
@@ -22,31 +22,36 @@
|
||||
|
||||
namespace hal {
|
||||
|
||||
// Create a mutex to protect changes to the DO PWM config
|
||||
wpi::mutex digitalPwmMutex;
|
||||
|
||||
std::unique_ptr<tDIO> digitalSystem;
|
||||
std::unique_ptr<tRelay> relaySystem;
|
||||
std::unique_ptr<tPWM> pwmSystem;
|
||||
std::unique_ptr<tSPI> spiSystem;
|
||||
|
||||
static std::atomic<bool> digitalSystemsInitialized{false};
|
||||
static wpi::mutex initializeMutex;
|
||||
|
||||
DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
|
||||
kNumDigitalChannels + kNumPWMHeaders>
|
||||
kNumDigitalChannels + kNumPWMHeaders>*
|
||||
digitalChannelHandles;
|
||||
|
||||
namespace init {
|
||||
void InitializeDigitalInternal() {
|
||||
static DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
|
||||
kNumDigitalChannels + kNumPWMHeaders>
|
||||
dcH;
|
||||
digitalChannelHandles = &dcH;
|
||||
}
|
||||
} // namespace init
|
||||
|
||||
/**
|
||||
* Initialize the digital system.
|
||||
*/
|
||||
void initializeDigital(int32_t* status) {
|
||||
static std::atomic_bool initialized{false};
|
||||
static wpi::mutex initializeMutex;
|
||||
// Initial check, as if it's true initialization has finished
|
||||
if (digitalSystemsInitialized) return;
|
||||
if (initialized) return;
|
||||
|
||||
std::lock_guard<wpi::mutex> lock(initializeMutex);
|
||||
// Second check in case another thread was waiting
|
||||
if (digitalSystemsInitialized) return;
|
||||
if (initialized) return;
|
||||
|
||||
digitalSystem.reset(tDIO::create(status));
|
||||
|
||||
@@ -99,7 +104,16 @@ void initializeDigital(int32_t* status) {
|
||||
// SPI setup
|
||||
spiSystem.reset(tSPI::create(status));
|
||||
|
||||
digitalSystemsInitialized = true;
|
||||
// Image 13 requires a SPI select and a strobe to enable SPI CS on MXP.
|
||||
// Switch to SPI 1, strobe the signal, and then switch back to previous.
|
||||
bool existingSelect = spiSystem->readAutoSPI1Select(status);
|
||||
spiSystem->writeAutoSPI1Select(true, status);
|
||||
spiSystem->strobeAutoForceOne(status);
|
||||
// Delay enough time to actually trigger strobe
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
spiSystem->writeAutoSPI1Select(existingSelect, status);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,9 +59,6 @@ constexpr double kDefaultPwmCenter = 1.5;
|
||||
constexpr int32_t kDefaultPwmStepsDown = 1000;
|
||||
constexpr int32_t kPwmDisabled = 0;
|
||||
|
||||
// Create a mutex to protect changes to the DO PWM config
|
||||
extern wpi::mutex digitalPwmMutex;
|
||||
|
||||
extern std::unique_ptr<tDIO> digitalSystem;
|
||||
extern std::unique_ptr<tRelay> relaySystem;
|
||||
extern std::unique_ptr<tPWM> pwmSystem;
|
||||
@@ -79,7 +76,7 @@ struct DigitalPort {
|
||||
};
|
||||
|
||||
extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
|
||||
kNumDigitalChannels + kNumPWMHeaders>
|
||||
kNumDigitalChannels + kNumPWMHeaders>*
|
||||
digitalChannelHandles;
|
||||
|
||||
void initializeDigital(int32_t* status);
|
||||
|
||||
@@ -223,8 +223,19 @@ double Encoder::DecodingScaleFactor() const {
|
||||
|
||||
static LimitedClassedHandleResource<HAL_EncoderHandle, Encoder,
|
||||
kNumEncoders + kNumCounters,
|
||||
HAL_HandleEnum::Encoder>
|
||||
encoderHandles;
|
||||
HAL_HandleEnum::Encoder>* encoderHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeEncoder() {
|
||||
static LimitedClassedHandleResource<HAL_EncoderHandle, Encoder,
|
||||
kNumEncoders + kNumCounters,
|
||||
HAL_HandleEnum::Encoder>
|
||||
eH;
|
||||
encoderHandles = &eH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
@@ -236,7 +247,7 @@ HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
digitalSourceHandleA, analogTriggerTypeA, digitalSourceHandleB,
|
||||
analogTriggerTypeB, reverseDirection, encodingType, status);
|
||||
if (*status != 0) return HAL_kInvalidHandle; // return in creation error
|
||||
auto handle = encoderHandles.Allocate(encoder);
|
||||
auto handle = encoderHandles->Allocate(encoder);
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -245,11 +256,11 @@ HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
}
|
||||
|
||||
void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
encoderHandles.Free(encoderHandle);
|
||||
encoderHandles->Free(encoderHandle);
|
||||
}
|
||||
|
||||
int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -258,7 +269,7 @@ int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
}
|
||||
|
||||
int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -268,7 +279,7 @@ int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
|
||||
int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -277,7 +288,7 @@ int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
|
||||
}
|
||||
|
||||
void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -286,7 +297,7 @@ void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
}
|
||||
|
||||
double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -296,7 +307,7 @@ double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
|
||||
void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -306,7 +317,7 @@ void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
|
||||
|
||||
HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -316,7 +327,7 @@ HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -326,7 +337,7 @@ HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -335,7 +346,7 @@ double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
|
||||
}
|
||||
|
||||
double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -345,7 +356,7 @@ double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
|
||||
void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -355,7 +366,7 @@ void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
|
||||
|
||||
void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
double distancePerPulse, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -366,7 +377,7 @@ void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
|
||||
HAL_Bool reverseDirection,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -376,7 +387,7 @@ void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
int32_t samplesToAverage, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -386,7 +397,7 @@ void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -396,7 +407,7 @@ int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -406,7 +417,7 @@ double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -416,7 +427,7 @@ double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
|
||||
HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_Encoder_k4X; // default to k4X
|
||||
@@ -428,7 +439,7 @@ void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_EncoderIndexingType type, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -438,7 +449,7 @@ void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
|
||||
@@ -24,11 +24,21 @@ struct Encoder {
|
||||
|
||||
} // namespace
|
||||
|
||||
static const double DECODING_SCALING_FACTOR = 0.25;
|
||||
static constexpr double DECODING_SCALING_FACTOR = 0.25;
|
||||
|
||||
static LimitedHandleResource<HAL_FPGAEncoderHandle, Encoder, kNumEncoders,
|
||||
HAL_HandleEnum::FPGAEncoder>
|
||||
fpgaEncoderHandles;
|
||||
HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeFPGAEncoder() {
|
||||
static LimitedHandleResource<HAL_FPGAEncoderHandle, Encoder, kNumEncoders,
|
||||
HAL_HandleEnum::FPGAEncoder>
|
||||
feH;
|
||||
fpgaEncoderHandles = &feH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -54,13 +64,13 @@ HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
auto handle = fpgaEncoderHandles.Allocate();
|
||||
auto handle = fpgaEncoderHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) { // out of resources
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
auto encoder = fpgaEncoderHandles.Get(handle);
|
||||
auto encoder = fpgaEncoderHandles->Get(handle);
|
||||
if (encoder == nullptr) { // will only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -87,7 +97,7 @@ HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
|
||||
|
||||
void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t* status) {
|
||||
fpgaEncoderHandles.Free(fpgaEncoderHandle);
|
||||
fpgaEncoderHandles->Free(fpgaEncoderHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +106,7 @@ void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -112,7 +122,7 @@ void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -132,7 +142,7 @@ int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
@@ -169,7 +179,7 @@ double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
double maxPeriod, int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -188,7 +198,7 @@ void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -202,7 +212,7 @@ HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -219,7 +229,7 @@ HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
HAL_Bool reverseDirection,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -236,7 +246,7 @@ void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
int32_t samplesToAverage,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -255,7 +265,7 @@ void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
*/
|
||||
int32_t HAL_GetFPGAEncoderSamplesToAverage(
|
||||
HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -272,7 +282,7 @@ void HAL_SetFPGAEncoderIndexSource(HAL_FPGAEncoderHandle fpgaEncoderHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool activeHigh, HAL_Bool edgeSensitive,
|
||||
int32_t* status) {
|
||||
auto encoder = fpgaEncoderHandles.Get(fpgaEncoderHandle);
|
||||
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
|
||||
@@ -28,10 +28,19 @@ struct HAL_JoystickAxesInt {
|
||||
};
|
||||
|
||||
static wpi::mutex msgMutex;
|
||||
static wpi::condition_variable newDSDataAvailableCond;
|
||||
static wpi::condition_variable* newDSDataAvailableCond;
|
||||
static wpi::mutex newDSDataAvailableMutex;
|
||||
static int newDSDataAvailableCounter{0};
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeFRCDriverStation() {
|
||||
static wpi::condition_variable nddaC;
|
||||
newDSDataAvailableCond = &nddaC;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
|
||||
@@ -341,12 +350,12 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
|
||||
int currentCount = newDSDataAvailableCounter;
|
||||
while (newDSDataAvailableCounter == currentCount) {
|
||||
if (timeout > 0) {
|
||||
auto timedOut = newDSDataAvailableCond.wait_until(lock, timeoutTime);
|
||||
auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
|
||||
if (timedOut == std::cv_status::timeout) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
newDSDataAvailableCond.wait(lock);
|
||||
newDSDataAvailableCond->wait(lock);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -362,7 +371,7 @@ static void newDataOccur(uint32_t refNum) {
|
||||
std::lock_guard<wpi::mutex> lock(newDSDataAvailableMutex);
|
||||
// Nofify all threads
|
||||
newDSDataAvailableCounter++;
|
||||
newDSDataAvailableCond.notify_all();
|
||||
newDSDataAvailableCond->notify_all();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
#include <FRC_NetworkCommunication/LoadOut.h>
|
||||
#include <llvm/raw_ostream.h>
|
||||
#include <support/mutex.h>
|
||||
#include <support/timestamp.h>
|
||||
|
||||
#include "HAL/ChipObject.h"
|
||||
#include "HAL/DriverStation.h"
|
||||
#include "HAL/Errors.h"
|
||||
#include "HAL/Notifier.h"
|
||||
#include "HAL/cpp/NotifierInternal.h"
|
||||
#include "HAL/handles/HandlesInternal.h"
|
||||
#include "HALInitializer.h"
|
||||
#include "ctre/ctre.h"
|
||||
#include "visa/visa.h"
|
||||
|
||||
@@ -37,6 +38,44 @@ static std::unique_ptr<tSysWatchdog> watchdog;
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeHAL() {
|
||||
InitializeHandlesInternal();
|
||||
InitializeAccelerometer();
|
||||
InitializeAnalogAccumulator();
|
||||
InitializeAnalogGyro();
|
||||
InitializeAnalogInput();
|
||||
InitializeAnalogInternal();
|
||||
InitializeAnalogOutput();
|
||||
InitializeAnalogTrigger();
|
||||
InitializeCAN();
|
||||
InitializeCompressor();
|
||||
InitializeConstants();
|
||||
InitializeCounter();
|
||||
InitializeDigitalInternal();
|
||||
InitializeDIO();
|
||||
InitializeEncoder();
|
||||
InitializeFPGAEncoder();
|
||||
InitializeFRCDriverStation();
|
||||
InitializeI2C();
|
||||
InitialzeInterrupts();
|
||||
InitializeNotifier();
|
||||
InitializeOSSerialPort();
|
||||
InitializePCMInternal();
|
||||
InitializePDP();
|
||||
InitializePorts();
|
||||
InitializePower();
|
||||
InitializePWM();
|
||||
InitializeRelay();
|
||||
InitializeSerialPort();
|
||||
InitializeSolenoid();
|
||||
InitializeSPI();
|
||||
InitializeThreads();
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_PortHandle HAL_GetPort(int32_t channel) {
|
||||
@@ -177,7 +216,7 @@ const char* HAL_GetErrorMessage(int32_t code) {
|
||||
/**
|
||||
* Returns the runtime type of this HAL
|
||||
*/
|
||||
HAL_RuntimeType HAL_GetRuntimeType() { return HAL_Athena; }
|
||||
HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Athena; }
|
||||
|
||||
/**
|
||||
* Return the FPGA Version number.
|
||||
@@ -219,8 +258,6 @@ uint64_t HAL_GetFPGATime(int32_t* status) {
|
||||
*status = NiFpga_Status_ResourceNotInitialized;
|
||||
return 0;
|
||||
}
|
||||
// Because of a bug in FPGA image 10, just return the lower 32 bits of time.
|
||||
return global->readLocalTime(status);
|
||||
|
||||
uint64_t upper1 = global->readLocalTimeUpper(status);
|
||||
uint32_t lower = global->readLocalTime(status);
|
||||
@@ -334,6 +371,8 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
|
||||
// Second check in case another thread was waiting
|
||||
if (initialized) return true;
|
||||
|
||||
hal::init::InitializeHAL();
|
||||
|
||||
setlinebuf(stdin);
|
||||
setlinebuf(stdout);
|
||||
llvm::outs().SetUnbuffered();
|
||||
@@ -354,9 +393,24 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_BaseInitialize(&status);
|
||||
if (status != 0) return false;
|
||||
|
||||
HAL_InitializeDriverStation();
|
||||
|
||||
// Set WPI_Now to use FPGA timestamp
|
||||
wpi::SetNowImpl([]() -> uint64_t {
|
||||
int32_t status = 0;
|
||||
uint64_t rv = HAL_GetFPGATime(&status);
|
||||
if (status != 0) {
|
||||
llvm::errs()
|
||||
<< "Call to HAL_GetFPGATime failed."
|
||||
<< "Initialization might have failed. Time will not be correct\n";
|
||||
llvm::errs().flush();
|
||||
return 0u;
|
||||
}
|
||||
return rv;
|
||||
});
|
||||
|
||||
initialized = true;
|
||||
return true;
|
||||
}
|
||||
@@ -373,8 +427,8 @@ int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
|
||||
|
||||
// TODO: HACKS
|
||||
// No need for header definitions, as we should not run from user code.
|
||||
void NumericArrayResize() {}
|
||||
void RTSetCleanupProc() {}
|
||||
void EDVR_CreateReference() {}
|
||||
void NumericArrayResize(void) {}
|
||||
void RTSetCleanupProc(void) {}
|
||||
void EDVR_CreateReference(void) {}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
45
hal/src/main/native/athena/HALInitializer.h
Normal file
45
hal/src/main/native/athena/HALInitializer.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
extern void InitializeAccelerometer();
|
||||
extern void InitializeAnalogAccumulator();
|
||||
extern void InitializeAnalogGyro();
|
||||
extern void InitializeAnalogInput();
|
||||
extern void InitializeAnalogInternal();
|
||||
extern void InitializeAnalogOutput();
|
||||
extern void InitializeAnalogTrigger();
|
||||
extern void InitializeCAN();
|
||||
extern void InitializeCompressor();
|
||||
extern void InitializeConstants();
|
||||
extern void InitializeCounter();
|
||||
extern void InitializeDigitalInternal();
|
||||
extern void InitializeDIO();
|
||||
extern void InitializeEncoder();
|
||||
extern void InitializeFPGAEncoder();
|
||||
extern void InitializeFRCDriverStation();
|
||||
extern void InitializeHAL();
|
||||
extern void InitializeI2C();
|
||||
extern void InitialzeInterrupts();
|
||||
extern void InitializeNotifier();
|
||||
extern void InitializeOSSerialPort();
|
||||
extern void InitializePCMInternal();
|
||||
extern void InitializePDP();
|
||||
extern void InitializePorts();
|
||||
extern void InitializePower();
|
||||
extern void InitializePWM();
|
||||
extern void InitializeRelay();
|
||||
extern void InitializeSerialPort();
|
||||
extern void InitializeSolenoid();
|
||||
extern void InitializeSPI();
|
||||
extern void InitializeThreads();
|
||||
extern void InitializeHandlesInternal();
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
@@ -24,13 +24,19 @@ using namespace hal;
|
||||
static wpi::mutex digitalI2COnBoardMutex;
|
||||
static wpi::mutex digitalI2CMXPMutex;
|
||||
|
||||
static uint8_t i2COnboardObjCount = 0;
|
||||
static uint8_t i2CMXPObjCount = 0;
|
||||
static int i2COnBoardHandle = -1;
|
||||
static int i2CMXPHandle = -1;
|
||||
static uint8_t i2COnboardObjCount{0};
|
||||
static uint8_t i2CMXPObjCount{0};
|
||||
static int i2COnBoardHandle{-1};
|
||||
static int i2CMXPHandle{-1};
|
||||
|
||||
static HAL_DigitalHandle i2CMXPDigitalHandle1 = HAL_kInvalidHandle;
|
||||
static HAL_DigitalHandle i2CMXPDigitalHandle2 = HAL_kInvalidHandle;
|
||||
static HAL_DigitalHandle i2CMXPDigitalHandle1{HAL_kInvalidHandle};
|
||||
static HAL_DigitalHandle i2CMXPDigitalHandle2{HAL_kInvalidHandle};
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeI2C() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -49,7 +55,7 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
|
||||
i2COnboardObjCount++;
|
||||
if (i2COnboardObjCount > 1) return;
|
||||
int handle = open("/dev/i2c-2", O_RDWR);
|
||||
@@ -59,7 +65,7 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
|
||||
}
|
||||
i2COnBoardHandle = handle;
|
||||
} else {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
|
||||
i2CMXPObjCount++;
|
||||
if (i2CMXPObjCount > 1) return;
|
||||
if ((i2CMXPDigitalHandle1 = HAL_InitializeDIOPort(
|
||||
@@ -117,10 +123,10 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
|
||||
rdwr.nmsgs = 2;
|
||||
|
||||
if (port == 0) {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
|
||||
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
|
||||
} else {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
|
||||
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
|
||||
}
|
||||
}
|
||||
@@ -154,10 +160,10 @@ int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
|
||||
rdwr.nmsgs = 1;
|
||||
|
||||
if (port == 0) {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
|
||||
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
|
||||
} else {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
|
||||
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
|
||||
}
|
||||
}
|
||||
@@ -193,10 +199,10 @@ int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
|
||||
rdwr.nmsgs = 1;
|
||||
|
||||
if (port == 0) {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
|
||||
return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
|
||||
} else {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
|
||||
return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
|
||||
}
|
||||
}
|
||||
@@ -208,12 +214,12 @@ void HAL_CloseI2C(HAL_I2CPort port) {
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2COnBoardMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
|
||||
if (i2COnboardObjCount-- == 0) {
|
||||
close(i2COnBoardHandle);
|
||||
}
|
||||
} else {
|
||||
std::lock_guard<wpi::mutex> sync(digitalI2CMXPMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
|
||||
if (i2CMXPObjCount-- == 0) {
|
||||
close(i2CMXPHandle);
|
||||
}
|
||||
|
||||
@@ -77,19 +77,29 @@ static void threadedInterruptHandler(uint32_t mask, void* param) {
|
||||
}
|
||||
|
||||
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
|
||||
HAL_HandleEnum::Interrupt>
|
||||
interruptHandles;
|
||||
HAL_HandleEnum::Interrupt>* interruptHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitialzeInterrupts() {
|
||||
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
|
||||
HAL_HandleEnum::Interrupt>
|
||||
iH;
|
||||
interruptHandles = &iH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
|
||||
int32_t* status) {
|
||||
HAL_InterruptHandle handle = interruptHandles.Allocate();
|
||||
HAL_InterruptHandle handle = interruptHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto anInterrupt = interruptHandles.Get(handle);
|
||||
auto anInterrupt = interruptHandles->Get(handle);
|
||||
uint32_t interruptIndex = static_cast<uint32_t>(getHandleIndex(handle));
|
||||
// Expects the calling leaf class to allocate an interrupt index.
|
||||
anInterrupt->anInterrupt.reset(tInterrupt::create(interruptIndex, status));
|
||||
@@ -100,7 +110,7 @@ HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
|
||||
}
|
||||
|
||||
void HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status) {
|
||||
interruptHandles.Free(interruptHandle);
|
||||
interruptHandles->Free(interruptHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +124,7 @@ int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
|
||||
double timeout, HAL_Bool ignorePrevious,
|
||||
int32_t* status) {
|
||||
uint32_t result;
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -140,7 +150,7 @@ int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
|
||||
*/
|
||||
void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -153,7 +163,7 @@ void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
*/
|
||||
void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -168,7 +178,7 @@ void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
*/
|
||||
double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -184,7 +194,7 @@ double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
*/
|
||||
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -197,7 +207,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -222,7 +232,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
|
||||
HAL_InterruptHandlerFunction handler,
|
||||
void* param, int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -248,7 +258,7 @@ void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interrupt_handle,
|
||||
void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
|
||||
HAL_Bool risingEdge, HAL_Bool fallingEdge,
|
||||
int32_t* status) {
|
||||
auto anInterrupt = interruptHandles.Get(interruptHandle);
|
||||
auto anInterrupt = interruptHandles->Get(interruptHandle);
|
||||
if (anInterrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
|
||||
@@ -11,123 +11,62 @@
|
||||
#include <cstdlib> // For std::atexit()
|
||||
#include <memory>
|
||||
|
||||
#include <support/SafeThread.h>
|
||||
#include <support/condition_variable.h>
|
||||
#include <support/mutex.h>
|
||||
|
||||
#include "HAL/ChipObject.h"
|
||||
#include "HAL/Errors.h"
|
||||
#include "HAL/HAL.h"
|
||||
#include "HAL/cpp/NotifierInternal.h"
|
||||
#include "HAL/cpp/make_unique.h"
|
||||
#include "HAL/handles/UnlimitedHandleResource.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
static const int32_t kTimerInterruptNumber = 28;
|
||||
static constexpr int32_t kTimerInterruptNumber = 28;
|
||||
|
||||
static wpi::mutex notifierInterruptMutex;
|
||||
static wpi::mutex notifierMutex;
|
||||
static std::unique_ptr<tAlarm> notifierAlarm;
|
||||
static std::unique_ptr<tInterruptManager> notifierManager;
|
||||
static uint64_t closestTrigger = UINT64_MAX;
|
||||
static uint64_t closestTrigger{UINT64_MAX};
|
||||
|
||||
namespace {
|
||||
|
||||
struct Notifier {
|
||||
std::shared_ptr<Notifier> prev, next;
|
||||
void* param;
|
||||
HAL_NotifierProcessFunction process;
|
||||
uint64_t triggerTime = UINT64_MAX;
|
||||
HAL_NotifierHandle handle;
|
||||
bool threaded;
|
||||
};
|
||||
|
||||
// Safe thread to allow callbacks to run on their own thread
|
||||
class NotifierThread : public wpi::SafeThread {
|
||||
public:
|
||||
void Main() {
|
||||
std::unique_lock<wpi::mutex> lock(m_mutex);
|
||||
while (m_active) {
|
||||
m_cond.wait(lock, [&] { return !m_active || m_notify; });
|
||||
if (!m_active) break;
|
||||
m_notify = false;
|
||||
uint64_t currentTime = m_currentTime;
|
||||
HAL_NotifierHandle handle = m_handle;
|
||||
HAL_NotifierProcessFunction process = m_process;
|
||||
lock.unlock(); // don't hold mutex during callback execution
|
||||
process(currentTime, handle);
|
||||
lock.lock();
|
||||
}
|
||||
}
|
||||
|
||||
bool m_notify = false;
|
||||
HAL_NotifierHandle m_handle = HAL_kInvalidHandle;
|
||||
HAL_NotifierProcessFunction m_process;
|
||||
uint64_t m_currentTime;
|
||||
};
|
||||
|
||||
class NotifierThreadOwner : public wpi::SafeThreadOwner<NotifierThread> {
|
||||
public:
|
||||
void SetFunc(HAL_NotifierProcessFunction process, void* param) {
|
||||
auto thr = GetThread();
|
||||
if (!thr) return;
|
||||
thr->m_process = process;
|
||||
m_param = param;
|
||||
}
|
||||
|
||||
void Notify(uint64_t currentTime, HAL_NotifierHandle handle) {
|
||||
auto thr = GetThread();
|
||||
if (!thr) return;
|
||||
thr->m_currentTime = currentTime;
|
||||
thr->m_handle = handle;
|
||||
thr->m_notify = true;
|
||||
thr->m_cond.notify_one();
|
||||
}
|
||||
|
||||
void* m_param;
|
||||
uint64_t triggeredTime = UINT64_MAX;
|
||||
bool active = true;
|
||||
wpi::mutex mutex;
|
||||
wpi::condition_variable cond;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static std::shared_ptr<Notifier> notifiers;
|
||||
static std::atomic_flag notifierAtexitRegistered = ATOMIC_FLAG_INIT;
|
||||
static std::atomic_flag notifierAtexitRegistered{ATOMIC_FLAG_INIT};
|
||||
static std::atomic_int notifierRefCount{0};
|
||||
|
||||
using namespace hal;
|
||||
|
||||
static UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
|
||||
HAL_HandleEnum::Notifier>
|
||||
notifierHandles;
|
||||
|
||||
// Internal version of updateAlarm used during the alarmCallback when we know
|
||||
// that the pointer is a valid pointer. This function is synchronized by the
|
||||
// caller locking notifierMutex.
|
||||
void updateNotifierAlarmInternal(std::shared_ptr<Notifier> notifierPointer,
|
||||
uint64_t triggerTime, int32_t* status) {
|
||||
auto notifier = notifierPointer;
|
||||
// no need for a null check, as this must always be a valid pointer.
|
||||
notifier->triggerTime = triggerTime;
|
||||
bool wasActive = (closestTrigger != UINT64_MAX);
|
||||
|
||||
if (!notifierInterruptMutex.try_lock() || notifierRefCount == 0 ||
|
||||
!notifierAlarm)
|
||||
return;
|
||||
|
||||
// Update alarm time if closer than current.
|
||||
if (triggerTime < closestTrigger) {
|
||||
closestTrigger = triggerTime;
|
||||
// Simply truncate the hardware trigger time to 32-bit.
|
||||
notifierAlarm->writeTriggerTime(static_cast<uint32_t>(triggerTime), status);
|
||||
class NotifierHandleContainer
|
||||
: public UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
|
||||
HAL_HandleEnum::Notifier> {
|
||||
public:
|
||||
~NotifierHandleContainer() {
|
||||
ForEach([](HAL_NotifierHandle handle, Notifier* notifier) {
|
||||
{
|
||||
std::lock_guard<wpi::mutex> lock(notifier->mutex);
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
notifier->triggeredTime = 0;
|
||||
notifier->active = false;
|
||||
}
|
||||
notifier->cond.notify_all(); // wake up any waiting threads
|
||||
});
|
||||
}
|
||||
// Enable the alarm. The hardware disables itself after each alarm.
|
||||
if (!wasActive) notifierAlarm->writeEnable(true, status);
|
||||
};
|
||||
|
||||
notifierInterruptMutex.unlock();
|
||||
}
|
||||
static NotifierHandleContainer* notifierHandles;
|
||||
|
||||
static void alarmCallback(uint32_t, void*) {
|
||||
std::unique_lock<wpi::mutex> sync(notifierMutex);
|
||||
|
||||
std::lock_guard<wpi::mutex> lock(notifierMutex);
|
||||
int32_t status = 0;
|
||||
uint64_t currentTime = 0;
|
||||
|
||||
@@ -135,22 +74,26 @@ static void alarmCallback(uint32_t, void*) {
|
||||
closestTrigger = UINT64_MAX;
|
||||
|
||||
// process all notifiers
|
||||
std::shared_ptr<Notifier> notifier = notifiers;
|
||||
while (notifier) {
|
||||
if (notifier->triggerTime != UINT64_MAX) {
|
||||
if (currentTime == 0) currentTime = HAL_GetFPGATime(&status);
|
||||
if (notifier->triggerTime < currentTime) {
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
auto process = notifier->process;
|
||||
auto handle = notifier->handle;
|
||||
sync.unlock();
|
||||
process(currentTime, handle);
|
||||
sync.lock();
|
||||
} else if (notifier->triggerTime < closestTrigger) {
|
||||
updateNotifierAlarmInternal(notifier, notifier->triggerTime, &status);
|
||||
}
|
||||
notifierHandles->ForEach([&](HAL_NotifierHandle handle, Notifier* notifier) {
|
||||
if (notifier->triggerTime == UINT64_MAX) return;
|
||||
if (currentTime == 0) currentTime = HAL_GetFPGATime(&status);
|
||||
std::unique_lock<wpi::mutex> lock(notifier->mutex);
|
||||
if (notifier->triggerTime < currentTime) {
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
notifier->triggeredTime = currentTime;
|
||||
lock.unlock();
|
||||
notifier->cond.notify_all();
|
||||
} else if (notifier->triggerTime < closestTrigger) {
|
||||
closestTrigger = notifier->triggerTime;
|
||||
}
|
||||
notifier = notifier->next;
|
||||
});
|
||||
|
||||
if (notifierAlarm && closestTrigger != UINT64_MAX) {
|
||||
// Simply truncate the hardware trigger time to 32-bit.
|
||||
notifierAlarm->writeTriggerTime(static_cast<uint32_t>(closestTrigger),
|
||||
&status);
|
||||
// Enable the alarm. The hardware disables itself after each alarm.
|
||||
notifierAlarm->writeEnable(true, &status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,30 +102,23 @@ static void cleanupNotifierAtExit() {
|
||||
notifierManager = nullptr;
|
||||
}
|
||||
|
||||
static void threadedNotifierHandler(uint64_t currentTimeInt,
|
||||
HAL_NotifierHandle handle) {
|
||||
// Grab notifier and get handler param
|
||||
auto notifier = notifierHandles.Get(handle);
|
||||
if (!notifier) return;
|
||||
auto notifierPointer = notifier->param;
|
||||
if (notifierPointer == nullptr) return;
|
||||
NotifierThreadOwner* owner =
|
||||
static_cast<NotifierThreadOwner*>(notifierPointer);
|
||||
owner->Notify(currentTimeInt, handle);
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeNotifier() {
|
||||
static NotifierHandleContainer nH;
|
||||
notifierHandles = &nH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
|
||||
HAL_NotifierProcessFunction process, void* param, int32_t* status) {
|
||||
if (!process) {
|
||||
*status = NULL_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) {
|
||||
if (!notifierAtexitRegistered.test_and_set())
|
||||
std::atexit(cleanupNotifierAtExit);
|
||||
|
||||
if (notifierRefCount.fetch_add(1) == 0) {
|
||||
std::lock_guard<wpi::mutex> sync(notifierInterruptMutex);
|
||||
std::lock_guard<wpi::mutex> lock(notifierMutex);
|
||||
// create manager and alarm if not already created
|
||||
if (!notifierManager) {
|
||||
notifierManager = std::make_unique<tInterruptManager>(
|
||||
@@ -193,107 +129,100 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
|
||||
if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status));
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(notifierMutex);
|
||||
std::shared_ptr<Notifier> notifier = std::make_shared<Notifier>();
|
||||
HAL_NotifierHandle handle = notifierHandles.Allocate(notifier);
|
||||
HAL_NotifierHandle handle = notifierHandles->Allocate(notifier);
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
// create notifier structure and add to list
|
||||
notifier->next = notifiers;
|
||||
if (notifier->next) notifier->next->prev = notifier;
|
||||
notifier->param = param;
|
||||
notifier->process = process;
|
||||
notifier->handle = handle;
|
||||
notifier->threaded = false;
|
||||
notifiers = notifier;
|
||||
return handle;
|
||||
}
|
||||
|
||||
HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
|
||||
void* param, int32_t* status) {
|
||||
NotifierThreadOwner* notify = new NotifierThreadOwner;
|
||||
notify->Start();
|
||||
notify->SetFunc(process, param);
|
||||
void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
|
||||
auto notifier = notifierHandles->Get(notifierHandle);
|
||||
if (!notifier) return;
|
||||
|
||||
auto notifierHandle = HAL_InitializeNotifierNonThreadedUnsafe(
|
||||
threadedNotifierHandler, notify, status);
|
||||
|
||||
if (notifierHandle == HAL_kInvalidHandle || *status != 0) {
|
||||
delete notify;
|
||||
return HAL_kInvalidHandle;
|
||||
{
|
||||
std::lock_guard<wpi::mutex> lock(notifier->mutex);
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
notifier->triggeredTime = 0;
|
||||
notifier->active = false;
|
||||
}
|
||||
|
||||
auto notifier = notifierHandles.Get(notifierHandle);
|
||||
if (!notifier) {
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
notifier->threaded = true;
|
||||
|
||||
return notifierHandle;
|
||||
notifier->cond.notify_all(); // wake up any waiting threads
|
||||
}
|
||||
|
||||
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
|
||||
auto notifier = notifierHandles->Free(notifierHandle);
|
||||
if (!notifier) return;
|
||||
|
||||
// Just in case HAL_StopNotifier() wasn't called...
|
||||
{
|
||||
std::lock_guard<wpi::mutex> sync(notifierMutex);
|
||||
auto notifier = notifierHandles.Get(notifierHandle);
|
||||
if (!notifier) return;
|
||||
|
||||
// remove from list
|
||||
if (notifier->prev) notifier->prev->next = notifier->next;
|
||||
if (notifier->next) notifier->next->prev = notifier->prev;
|
||||
if (notifiers == notifier) notifiers = notifier->next;
|
||||
notifierHandles.Free(notifierHandle);
|
||||
|
||||
if (notifier->threaded) {
|
||||
NotifierThreadOwner* owner =
|
||||
static_cast<NotifierThreadOwner*>(notifier->param);
|
||||
delete owner;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> lock(notifier->mutex);
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
notifier->triggeredTime = 0;
|
||||
notifier->active = false;
|
||||
}
|
||||
notifier->cond.notify_all();
|
||||
|
||||
if (notifierRefCount.fetch_sub(1) == 1) {
|
||||
std::lock_guard<wpi::mutex> sync(notifierInterruptMutex);
|
||||
// if this was the last notifier, clean up alarm and manager
|
||||
if (notifierAlarm) {
|
||||
notifierAlarm->writeEnable(false, status);
|
||||
notifierAlarm = nullptr;
|
||||
}
|
||||
if (notifierManager) {
|
||||
notifierManager->disable(status);
|
||||
notifierManager = nullptr;
|
||||
}
|
||||
// the notifier can call back into our callback, so don't hold the lock
|
||||
// here (the atomic fetch_sub will prevent multiple parallel entries
|
||||
// into this function)
|
||||
if (notifierAlarm) notifierAlarm->writeEnable(false, status);
|
||||
if (notifierManager) notifierManager->disable(status);
|
||||
|
||||
std::lock_guard<wpi::mutex> lock(notifierMutex);
|
||||
notifierAlarm = nullptr;
|
||||
notifierManager = nullptr;
|
||||
closestTrigger = UINT64_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status) {
|
||||
auto notifier = notifierHandles.Get(notifierHandle);
|
||||
if (!notifier) return nullptr;
|
||||
if (notifier->threaded) {
|
||||
// If threaded, return thread param rather then notifier param
|
||||
NotifierThreadOwner* owner =
|
||||
static_cast<NotifierThreadOwner*>(notifier->param);
|
||||
return owner->m_param;
|
||||
}
|
||||
return notifier->param;
|
||||
}
|
||||
|
||||
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
uint64_t triggerTime, int32_t* status) {
|
||||
std::lock_guard<wpi::mutex> sync(notifierMutex);
|
||||
|
||||
auto notifier = notifierHandles.Get(notifierHandle);
|
||||
auto notifier = notifierHandles->Get(notifierHandle);
|
||||
if (!notifier) return;
|
||||
updateNotifierAlarmInternal(notifier, triggerTime, status);
|
||||
|
||||
{
|
||||
std::lock_guard<wpi::mutex> lock(notifier->mutex);
|
||||
notifier->triggerTime = triggerTime;
|
||||
notifier->triggeredTime = UINT64_MAX;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> lock(notifierMutex);
|
||||
// Update alarm time if closer than current.
|
||||
if (triggerTime < closestTrigger) {
|
||||
bool wasActive = (closestTrigger != UINT64_MAX);
|
||||
closestTrigger = triggerTime;
|
||||
// Simply truncate the hardware trigger time to 32-bit.
|
||||
notifierAlarm->writeTriggerTime(static_cast<uint32_t>(closestTrigger),
|
||||
status);
|
||||
// Enable the alarm.
|
||||
if (!wasActive) notifierAlarm->writeEnable(true, status);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status) {
|
||||
std::lock_guard<wpi::mutex> sync(notifierMutex);
|
||||
auto notifier = notifierHandles.Get(notifierHandle);
|
||||
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
int32_t* status) {
|
||||
auto notifier = notifierHandles->Get(notifierHandle);
|
||||
if (!notifier) return;
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
|
||||
{
|
||||
std::lock_guard<wpi::mutex> lock(notifier->mutex);
|
||||
notifier->triggerTime = UINT64_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
int32_t* status) {
|
||||
auto notifier = notifierHandles->Get(notifierHandle);
|
||||
if (!notifier) return 0;
|
||||
std::unique_lock<wpi::mutex> lock(notifier->mutex);
|
||||
notifier->cond.wait(lock, [&] {
|
||||
return !notifier->active || notifier->triggeredTime != UINT64_MAX;
|
||||
});
|
||||
return notifier->active ? notifier->triggeredTime : 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -24,6 +24,17 @@ static std::chrono::milliseconds portTimeouts[4]{
|
||||
std::chrono::milliseconds(0), std::chrono::milliseconds(0),
|
||||
std::chrono::milliseconds(0), std::chrono::milliseconds(0)};
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeOSSerialPort() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
portHandles[i] = -1;
|
||||
portTimeouts[i] = std::chrono::milliseconds(0);
|
||||
}
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status) {
|
||||
|
||||
@@ -16,6 +16,14 @@ namespace hal {
|
||||
|
||||
std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
|
||||
|
||||
namespace init {
|
||||
void InitializePCMInternal() {
|
||||
for (int i = 0; i < kNumPCMModules; i++) {
|
||||
PCM_modules[i] = nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace init
|
||||
|
||||
void initializePCM(int32_t module, int32_t* status) {
|
||||
if (!HAL_CheckSolenoidModule(module)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
|
||||
@@ -31,6 +31,16 @@ static inline bool checkPDPInit(int32_t module, int32_t* status) {
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializePDP() {
|
||||
for (int i = 0; i < kNumPDPModules; i++) {
|
||||
pdp[i] = nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
void HAL_InitializePDP(int32_t module, int32_t* status) {
|
||||
|
||||
@@ -56,6 +56,12 @@ static inline int32_t GetFullRangeScaleFactor(DigitalPort* port) {
|
||||
return GetMaxPositivePwm(port) - GetMinNegativePwm(port);
|
||||
} ///< The scale for positions.
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializePWM() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
|
||||
@@ -79,12 +85,12 @@ HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
|
||||
}
|
||||
|
||||
auto handle =
|
||||
digitalChannelHandles.Allocate(channel, HAL_HandleEnum::PWM, status);
|
||||
digitalChannelHandles->Allocate(channel, HAL_HandleEnum::PWM, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = digitalChannelHandles.Get(handle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -101,7 +107,7 @@ HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
|
||||
return handle;
|
||||
}
|
||||
void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -115,7 +121,7 @@ void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
status);
|
||||
}
|
||||
|
||||
digitalChannelHandles.Free(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
digitalChannelHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckPWMChannel(int32_t channel) {
|
||||
@@ -125,7 +131,7 @@ HAL_Bool HAL_CheckPWMChannel(int32_t channel) {
|
||||
void HAL_SetPWMConfig(HAL_DigitalHandle pwmPortHandle, double max,
|
||||
double deadbandMax, double center, double deadbandMin,
|
||||
double min, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -159,7 +165,7 @@ void HAL_SetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t maxPwm,
|
||||
int32_t deadbandMaxPwm, int32_t centerPwm,
|
||||
int32_t deadbandMinPwm, int32_t minPwm,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -176,7 +182,7 @@ void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
|
||||
int32_t* deadbandMaxPwm, int32_t* centerPwm,
|
||||
int32_t* deadbandMinPwm, int32_t* minPwm,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -190,7 +196,7 @@ void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
|
||||
|
||||
void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
|
||||
HAL_Bool eliminateDeadband, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -200,7 +206,7 @@ void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
|
||||
|
||||
HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -218,7 +224,7 @@ HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
|
||||
*/
|
||||
void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -242,7 +248,7 @@ void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
|
||||
*/
|
||||
void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -297,7 +303,7 @@ void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
|
||||
*/
|
||||
void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double pos,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -339,7 +345,7 @@ void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
* @return The raw PWM value.
|
||||
*/
|
||||
int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -359,7 +365,7 @@ int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
* @return The scaled PWM value.
|
||||
*/
|
||||
double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -397,7 +403,7 @@ double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
* @return The scaled PWM value.
|
||||
*/
|
||||
double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -422,7 +428,7 @@ double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
}
|
||||
|
||||
void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -440,7 +446,7 @@ void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
|
||||
*/
|
||||
void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -473,9 +479,6 @@ int32_t HAL_GetPWMLoopTiming(int32_t* status) {
|
||||
uint64_t HAL_GetPWMCycleStartTime(int32_t* status) {
|
||||
initializeDigital(status);
|
||||
if (*status != 0) return 0;
|
||||
// Because of a bug in FPGA image 10, just return the lower 32 bits of cycle
|
||||
// time.
|
||||
return pwmSystem->readCycleStartTime(status);
|
||||
|
||||
uint64_t upper1 = pwmSystem->readCycleStartTimeUpper(status);
|
||||
uint32_t lower = pwmSystem->readCycleStartTime(status);
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializePorts() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
int32_t HAL_GetNumAccumulators(void) { return kNumAccumulators; }
|
||||
|
||||
@@ -15,7 +15,7 @@ using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
|
||||
static std::unique_ptr<tPower> power;
|
||||
static std::unique_ptr<tPower> power{nullptr};
|
||||
|
||||
static void initializePower(int32_t* status) {
|
||||
if (power == nullptr) {
|
||||
@@ -25,6 +25,12 @@ static void initializePower(int32_t* status) {
|
||||
|
||||
} // namespace hal
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializePower() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,12 +23,22 @@ struct Relay {
|
||||
} // namespace
|
||||
|
||||
static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
|
||||
HAL_HandleEnum::Relay>
|
||||
relayHandles;
|
||||
HAL_HandleEnum::Relay>* relayHandles;
|
||||
|
||||
// Create a mutex to protect changes to the relay values
|
||||
static wpi::mutex digitalRelayMutex;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeRelay() {
|
||||
static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
|
||||
HAL_HandleEnum::Relay>
|
||||
rH;
|
||||
relayHandles = &rH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
|
||||
@@ -45,12 +55,12 @@ HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
|
||||
|
||||
if (!fwd) channel += kNumRelayHeaders; // add 4 to reverse channels
|
||||
|
||||
auto handle = relayHandles.Allocate(channel, status);
|
||||
auto handle = relayHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = relayHandles.Get(handle);
|
||||
auto port = relayHandles->Get(handle);
|
||||
if (port == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -71,7 +81,7 @@ HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
|
||||
|
||||
void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle) {
|
||||
// no status, so no need to check for a proper free.
|
||||
relayHandles.Free(relayPortHandle);
|
||||
relayHandles->Free(relayPortHandle);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckRelayChannel(int32_t channel) {
|
||||
@@ -87,12 +97,12 @@ HAL_Bool HAL_CheckRelayChannel(int32_t channel) {
|
||||
*/
|
||||
void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
|
||||
int32_t* status) {
|
||||
auto port = relayHandles.Get(relayPortHandle);
|
||||
auto port = relayHandles->Get(relayPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(digitalRelayMutex);
|
||||
std::lock_guard<wpi::mutex> lock(digitalRelayMutex);
|
||||
uint8_t relays = 0;
|
||||
if (port->fwd) {
|
||||
relays = relaySystem->readValue_Forward(status);
|
||||
@@ -119,7 +129,7 @@ void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
|
||||
* Get the current state of the relay channel
|
||||
*/
|
||||
HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status) {
|
||||
auto port = relayHandles.Get(relayPortHandle);
|
||||
auto port = relayHandles->Get(relayPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
#include <llvm/raw_ostream.h>
|
||||
#include <support/mutex.h>
|
||||
@@ -28,11 +29,11 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
static int32_t m_spiCS0Handle = 0;
|
||||
static int32_t m_spiCS1Handle = 0;
|
||||
static int32_t m_spiCS2Handle = 0;
|
||||
static int32_t m_spiCS3Handle = 0;
|
||||
static int32_t m_spiMXPHandle = 0;
|
||||
static int32_t m_spiCS0Handle{0};
|
||||
static int32_t m_spiCS1Handle{0};
|
||||
static int32_t m_spiCS2Handle{0};
|
||||
static int32_t m_spiCS3Handle{0};
|
||||
static int32_t m_spiMXPHandle{0};
|
||||
|
||||
static constexpr int32_t kSpiMaxHandles = 5;
|
||||
|
||||
@@ -46,8 +47,6 @@ std::atomic<int32_t> spiPortCount{0};
|
||||
|
||||
static HAL_DigitalHandle digitalHandles[9]{HAL_kInvalidHandle};
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct SPIAccumulator {
|
||||
std::atomic<HAL_NotifierHandle> notifier{0};
|
||||
uint64_t triggerTime;
|
||||
@@ -73,6 +72,14 @@ struct SPIAccumulator {
|
||||
};
|
||||
std::unique_ptr<SPIAccumulator> spiAccumulators[5];
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeSPI() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void CommonSPIPortInit(int32_t* status) {
|
||||
// All false cases will set
|
||||
if (spiPortCount.fetch_add(1) == 0) {
|
||||
@@ -97,7 +104,7 @@ static void CommonSPIPortInit(int32_t* status) {
|
||||
}
|
||||
}
|
||||
|
||||
static void CommonSPIPortFree() {
|
||||
static void CommonSPIPortFree(void) {
|
||||
if (spiPortCount.fetch_sub(1) == 1) {
|
||||
// Clean up SPI Handles
|
||||
HAL_FreeDIOPort(digitalHandles[3]);
|
||||
@@ -272,7 +279,7 @@ int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
|
||||
xfer.rx_buf = (__u64)dataReceived;
|
||||
xfer.len = size;
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
|
||||
}
|
||||
|
||||
@@ -297,7 +304,7 @@ int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
|
||||
xfer.tx_buf = (__u64)dataToSend;
|
||||
xfer.len = sendSize;
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
|
||||
}
|
||||
|
||||
@@ -324,7 +331,7 @@ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
|
||||
xfer.rx_buf = (__u64)buffer;
|
||||
xfer.len = count;
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
|
||||
}
|
||||
|
||||
@@ -342,7 +349,7 @@ void HAL_CloseSPI(HAL_SPIPort port) {
|
||||
HAL_FreeSPIAccumulator(port, &status);
|
||||
|
||||
{
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
close(HAL_GetSPIHandle(port));
|
||||
}
|
||||
|
||||
@@ -384,7 +391,7 @@ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||
}
|
||||
|
||||
@@ -409,7 +416,7 @@ void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
|
||||
mode |= (clkIdleHigh ? 2 : 0);
|
||||
mode |= (sampleOnTrailing ? 1 : 0);
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
|
||||
}
|
||||
|
||||
@@ -424,7 +431,7 @@ void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
if (port < 4) {
|
||||
spiSystem->writeChipSelectActiveHigh_Hdr(
|
||||
spiSystem->readChipSelectActiveHigh_Hdr(status) | (1 << port), status);
|
||||
@@ -444,7 +451,7 @@ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
if (port < 4) {
|
||||
spiSystem->writeChipSelectActiveHigh_Hdr(
|
||||
spiSystem->readChipSelectActiveHigh_Hdr(status) & ~(1 << port), status);
|
||||
@@ -464,7 +471,7 @@ int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiHandleMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiHandleMutexes[port]);
|
||||
switch (port) {
|
||||
case 0:
|
||||
return m_spiCS0Handle;
|
||||
@@ -493,7 +500,7 @@ void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiHandleMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiHandleMutexes[port]);
|
||||
switch (port) {
|
||||
case 0:
|
||||
m_spiCS0Handle = handle;
|
||||
@@ -515,13 +522,7 @@ void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
|
||||
}
|
||||
}
|
||||
|
||||
static void spiAccumulatorProcess(uint64_t currentTime,
|
||||
HAL_NotifierHandle handle) {
|
||||
int32_t status = 0;
|
||||
auto param = HAL_GetNotifierParam(handle, &status);
|
||||
if (param == nullptr) return;
|
||||
SPIAccumulator* accum = static_cast<SPIAccumulator*>(param);
|
||||
|
||||
static void spiAccumulatorProcess(uint64_t currentTime, SPIAccumulator* accum) {
|
||||
// perform SPI transaction
|
||||
uint8_t resp_b[4];
|
||||
HAL_TransactionSPI(accum->port, accum->cmd, resp_b, accum->xferSize);
|
||||
@@ -564,7 +565,7 @@ static void spiAccumulatorProcess(uint64_t currentTime,
|
||||
// handle timer slip
|
||||
if (accum->triggerTime < currentTime)
|
||||
accum->triggerTime = currentTime + accum->period;
|
||||
status = 0;
|
||||
int32_t status = 0;
|
||||
HAL_UpdateNotifierAlarm(accum->notifier, accum->triggerTime, &status);
|
||||
}
|
||||
|
||||
@@ -594,7 +595,7 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
if (!spiAccumulators[port])
|
||||
spiAccumulators[port] = std::make_unique<SPIAccumulator>();
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
@@ -623,10 +624,18 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd,
|
||||
accum->bigEndian = bigEndian;
|
||||
accum->port = port;
|
||||
if (!accum->notifier) {
|
||||
accum->notifier =
|
||||
HAL_InitializeNotifier(spiAccumulatorProcess, accum, status);
|
||||
accum->notifier = HAL_InitializeNotifier(status);
|
||||
accum->triggerTime = HAL_GetFPGATime(status) + period;
|
||||
if (*status != 0) return;
|
||||
std::thread thr([=] {
|
||||
int32_t status2 = 0;
|
||||
while (status2 == 0) {
|
||||
uint64_t curTime = HAL_WaitForNotifierAlarm(accum->notifier, &status2);
|
||||
if (curTime == 0 || status2 != 0) break;
|
||||
spiAccumulatorProcess(curTime, accum);
|
||||
}
|
||||
});
|
||||
thr.detach();
|
||||
HAL_UpdateNotifierAlarm(accum->notifier, accum->triggerTime, status);
|
||||
}
|
||||
}
|
||||
@@ -640,7 +649,7 @@ void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -660,7 +669,7 @@ void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiApiMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -687,7 +696,7 @@ void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center,
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -706,7 +715,7 @@ void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband,
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -724,7 +733,7 @@ int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -744,7 +753,7 @@ int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -767,7 +776,7 @@ int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
@@ -810,7 +819,7 @@ void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value,
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<wpi::mutex> sync(spiAccumulatorMutexes[port]);
|
||||
std::lock_guard<wpi::mutex> lock(spiAccumulatorMutexes[port]);
|
||||
SPIAccumulator* accum = spiAccumulators[port].get();
|
||||
if (!accum) {
|
||||
*status = NULL_PARAMETER;
|
||||
|
||||
@@ -12,9 +12,15 @@
|
||||
#include "HAL/cpp/SerialHelper.h"
|
||||
#include "visa/visa.h"
|
||||
|
||||
static int32_t resourceManagerHandle;
|
||||
static int32_t resourceManagerHandle{0};
|
||||
static HAL_SerialPort portHandles[4];
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeSerialPort() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) {
|
||||
|
||||
@@ -31,8 +31,19 @@ using namespace hal;
|
||||
|
||||
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
|
||||
kNumPCMModules * kNumSolenoidChannels,
|
||||
HAL_HandleEnum::Solenoid>
|
||||
solenoidHandles;
|
||||
HAL_HandleEnum::Solenoid>* solenoidHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeSolenoid() {
|
||||
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
|
||||
kNumPCMModules * kNumSolenoidChannels,
|
||||
HAL_HandleEnum::Solenoid>
|
||||
sH;
|
||||
solenoidHandles = &sH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -56,12 +67,12 @@ HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
auto handle =
|
||||
solenoidHandles.Allocate(module * kNumSolenoidChannels + channel, status);
|
||||
auto handle = solenoidHandles->Allocate(
|
||||
module * kNumSolenoidChannels + channel, status);
|
||||
if (*status != 0) {
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto solenoidPort = solenoidHandles.Get(handle);
|
||||
auto solenoidPort = solenoidHandles->Get(handle);
|
||||
if (solenoidPort == nullptr) { // would only occur on thread issues
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -73,7 +84,7 @@ HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
|
||||
}
|
||||
|
||||
void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
|
||||
solenoidHandles.Free(solenoidPortHandle);
|
||||
solenoidHandles->Free(solenoidPortHandle);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
|
||||
@@ -86,7 +97,7 @@ HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
|
||||
|
||||
HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = solenoidHandles.Get(solenoidPortHandle);
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -109,7 +120,7 @@ int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
|
||||
|
||||
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
|
||||
int32_t* status) {
|
||||
auto port = solenoidHandles.Get(solenoidPortHandle);
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -154,4 +165,25 @@ void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
|
||||
*status = PCM_modules[module]->ClearStickyFaults();
|
||||
}
|
||||
|
||||
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
|
||||
int32_t durMS, int32_t* status) {
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
*status =
|
||||
PCM_modules[port->module]->SetOneShotDurationMs(port->channel, durMS);
|
||||
}
|
||||
|
||||
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
*status = PCM_modules[port->module]->FireOneShotSolenoid(port->channel);
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
|
||||
#include "HAL/Errors.h"
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeThreads() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
|
||||
@@ -213,7 +213,9 @@ CTR_Code PCM::FireOneShotSolenoid(UINT8 idx)
|
||||
return CTR_OKAY;
|
||||
}
|
||||
/* Configure the pulse width of a solenoid channel for one-shot pulse.
|
||||
* Preprogrammed pulsewidth is 10ms resolute and can be between 20ms and 5.1s.
|
||||
* Preprogrammed pulsewidth is 10ms resolution and can be between 10ms and
|
||||
* 2.55s.
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid [0,7] to configure.
|
||||
* @Param - durMs - pulse width in ms.
|
||||
|
||||
@@ -54,7 +54,7 @@ const char* HAL_GetErrorMessage(int32_t code);
|
||||
int32_t HAL_GetFPGAVersion(int32_t* status);
|
||||
int64_t HAL_GetFPGARevision(int32_t* status);
|
||||
|
||||
HAL_RuntimeType HAL_GetRuntimeType();
|
||||
HAL_RuntimeType HAL_GetRuntimeType(void);
|
||||
HAL_Bool HAL_GetFPGAButton(int32_t* status);
|
||||
|
||||
HAL_Bool HAL_GetSystemActive(int32_t* status);
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*HAL_NotifierProcessFunction)(uint64_t currentTime,
|
||||
HAL_NotifierHandle handle);
|
||||
|
||||
HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
|
||||
void* param, int32_t* status);
|
||||
HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status);
|
||||
void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
uint64_t triggerTime, int32_t* status);
|
||||
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
int32_t* status);
|
||||
uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,9 @@ int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status);
|
||||
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status);
|
||||
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status);
|
||||
void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status);
|
||||
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
|
||||
int32_t durMS, int32_t* status);
|
||||
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -83,6 +83,14 @@ namespace nUsageReporting
|
||||
kResourceType_PCM, // 60
|
||||
kResourceType_PigeonIMU,
|
||||
kResourceType_NidecBrushless,
|
||||
kResourceType_CANifier,
|
||||
kResourceType_CTRE_future0,
|
||||
kResourceType_CTRE_future1,
|
||||
kResourceType_CTRE_future2,
|
||||
kResourceType_CTRE_future3,
|
||||
kResourceType_CTRE_future4,
|
||||
kResourceType_CTRE_future5,
|
||||
kResourceType_CTRE_future6, // 70
|
||||
} tResourceType;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -60,7 +60,7 @@ THandle DigitalHandleResource<THandle, TStruct, size>::Allocate(
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// check for allocation, otherwise allocate and return a valid handle
|
||||
if (m_structures[index] != nullptr) {
|
||||
*status = RESOURCE_IS_ALLOCATED;
|
||||
@@ -78,7 +78,7 @@ std::shared_ptr<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
|
||||
if (index < 0 || index >= size) {
|
||||
return nullptr;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// return structure. Null will propogate correctly, so no need to manually
|
||||
// check.
|
||||
return m_structures[index];
|
||||
@@ -91,14 +91,14 @@ void DigitalHandleResource<THandle, TStruct, size>::Free(
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
if (index < 0 || index >= size) return;
|
||||
// lock and deallocated handle
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
m_structures[index].reset();
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, int16_t size>
|
||||
void DigitalHandleResource<THandle, TStruct, size>::ResetHandles() {
|
||||
for (int i = 0; i < size; i++) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
|
||||
m_structures[i].reset();
|
||||
}
|
||||
HandleBase::ResetHandles();
|
||||
|
||||
@@ -77,7 +77,7 @@ static inline int16_t getHandleTypedIndex(HAL_Handle handle,
|
||||
HAL_HandleEnum enumType,
|
||||
int16_t version) {
|
||||
if (!isHandleType(handle, enumType)) return InvalidHandleIndex;
|
||||
#if !defined(CONFIG_ATHENA)
|
||||
#if !defined(__FRC_ROBORIO__)
|
||||
if (!isHandleCorrectVersion(handle, version)) return InvalidHandleIndex;
|
||||
#endif
|
||||
return getHandleIndex(handle);
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "HAL/Errors.h"
|
||||
#include "HAL/Types.h"
|
||||
#include "HAL/cpp/make_unique.h"
|
||||
#include "HAL/cpp/priority_mutex.h"
|
||||
#include "HAL/handles/HandlesInternal.h"
|
||||
|
||||
namespace hal {
|
||||
@@ -74,7 +73,7 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// check for allocation, otherwise allocate and return a valid handle
|
||||
if (m_structures[index] != nullptr) {
|
||||
*status = RESOURCE_IS_ALLOCATED;
|
||||
@@ -94,7 +93,7 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
|
||||
if (index < 0 || index >= size) {
|
||||
return nullptr;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// return structure. Null will propogate correctly, so no need to manually
|
||||
// check.
|
||||
return m_structures[index];
|
||||
@@ -108,7 +107,7 @@ void IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
if (index < 0 || index >= size) return;
|
||||
// lock and deallocated handle
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
m_structures[index].reset();
|
||||
}
|
||||
|
||||
@@ -117,7 +116,7 @@ template <typename THandle, typename TStruct, int16_t size,
|
||||
void IndexedClassedHandleResource<THandle, TStruct, size,
|
||||
enumValue>::ResetHandles() {
|
||||
for (int i = 0; i < size; i++) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
|
||||
m_structures[i].reset();
|
||||
}
|
||||
HandleBase::ResetHandles();
|
||||
|
||||
@@ -62,7 +62,7 @@ THandle IndexedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// check for allocation, otherwise allocate and return a valid handle
|
||||
if (m_structures[index] != nullptr) {
|
||||
*status = RESOURCE_IS_ALLOCATED;
|
||||
@@ -81,7 +81,7 @@ IndexedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
|
||||
if (index < 0 || index >= size) {
|
||||
return nullptr;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// return structure. Null will propogate correctly, so no need to manually
|
||||
// check.
|
||||
return m_structures[index];
|
||||
@@ -95,7 +95,7 @@ void IndexedHandleResource<THandle, TStruct, size, enumValue>::Free(
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
if (index < 0 || index >= size) return;
|
||||
// lock and deallocated handle
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
m_structures[index].reset();
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ template <typename THandle, typename TStruct, int16_t size,
|
||||
HAL_HandleEnum enumValue>
|
||||
void IndexedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
|
||||
for (int i = 0; i < size; i++) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
|
||||
m_structures[i].reset();
|
||||
}
|
||||
HandleBase::ResetHandles();
|
||||
|
||||
@@ -59,12 +59,12 @@ THandle
|
||||
LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
|
||||
std::shared_ptr<TStruct> toSet) {
|
||||
// globally lock to loop through indices
|
||||
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
|
||||
for (int16_t i = 0; i < size; i++) {
|
||||
if (m_structures[i] == nullptr) {
|
||||
// if a false index is found, grab its specific mutex
|
||||
// and allocate it.
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
|
||||
m_structures[i] = toSet;
|
||||
return static_cast<THandle>(createHandle(i, enumValue, m_version));
|
||||
}
|
||||
@@ -82,7 +82,7 @@ LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
|
||||
if (index < 0 || index >= size) {
|
||||
return nullptr;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// return structure. Null will propogate correctly, so no need to manually
|
||||
// check.
|
||||
return m_structures[index];
|
||||
@@ -96,8 +96,8 @@ void LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
if (index < 0 || index >= size) return;
|
||||
// lock and deallocated handle
|
||||
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
|
||||
m_structures[index].reset();
|
||||
}
|
||||
|
||||
@@ -106,9 +106,9 @@ template <typename THandle, typename TStruct, int16_t size,
|
||||
void LimitedClassedHandleResource<THandle, TStruct, size,
|
||||
enumValue>::ResetHandles() {
|
||||
{
|
||||
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
|
||||
for (int i = 0; i < size; i++) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
|
||||
m_structures[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ template <typename THandle, typename TStruct, int16_t size,
|
||||
HAL_HandleEnum enumValue>
|
||||
THandle LimitedHandleResource<THandle, TStruct, size, enumValue>::Allocate() {
|
||||
// globally lock to loop through indices
|
||||
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
|
||||
for (int16_t i = 0; i < size; i++) {
|
||||
if (m_structures[i] == nullptr) {
|
||||
// if a false index is found, grab its specific mutex
|
||||
// and allocate it.
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
|
||||
m_structures[i] = std::make_shared<TStruct>();
|
||||
return static_cast<THandle>(createHandle(i, enumValue, m_version));
|
||||
}
|
||||
@@ -77,7 +77,7 @@ LimitedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
|
||||
if (index < 0 || index >= size) {
|
||||
return nullptr;
|
||||
}
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
// return structure. Null will propogate correctly, so no need to manually
|
||||
// check.
|
||||
return m_structures[index];
|
||||
@@ -91,8 +91,8 @@ void LimitedHandleResource<THandle, TStruct, size, enumValue>::Free(
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
if (index < 0 || index >= size) return;
|
||||
// lock and deallocated handle
|
||||
std::lock_guard<wpi::mutex> sync(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
|
||||
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
|
||||
m_structures[index].reset();
|
||||
}
|
||||
|
||||
@@ -100,9 +100,9 @@ template <typename THandle, typename TStruct, int16_t size,
|
||||
HAL_HandleEnum enumValue>
|
||||
void LimitedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
|
||||
{
|
||||
std::lock_guard<wpi::mutex> lock(m_allocateMutex);
|
||||
std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
|
||||
for (int i = 0; i < size; i++) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutexes[i]);
|
||||
std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
|
||||
m_structures[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <support/mutex.h>
|
||||
@@ -44,9 +45,16 @@ class UnlimitedHandleResource : public HandleBase {
|
||||
|
||||
THandle Allocate(std::shared_ptr<TStruct> structure);
|
||||
std::shared_ptr<TStruct> Get(THandle handle);
|
||||
void Free(THandle handle);
|
||||
/* Returns structure previously at that handle (or nullptr if none) */
|
||||
std::shared_ptr<TStruct> Free(THandle handle);
|
||||
void ResetHandles() override;
|
||||
|
||||
/* Calls func(THandle, TStruct*) for each handle. Note this holds the
|
||||
* global lock for the entirety of execution.
|
||||
*/
|
||||
template <typename Functor>
|
||||
void ForEach(Functor func);
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<TStruct>> m_structures;
|
||||
wpi::mutex m_handleMutex;
|
||||
@@ -55,7 +63,7 @@ class UnlimitedHandleResource : public HandleBase {
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
THandle UnlimitedHandleResource<THandle, TStruct, enumValue>::Allocate(
|
||||
std::shared_ptr<TStruct> structure) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutex);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutex);
|
||||
size_t i;
|
||||
for (i = 0; i < m_structures.size(); i++) {
|
||||
if (m_structures[i] == nullptr) {
|
||||
@@ -74,19 +82,20 @@ template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
std::shared_ptr<TStruct>
|
||||
UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutex);
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutex);
|
||||
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
|
||||
return nullptr;
|
||||
return m_structures[index];
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
|
||||
THandle handle) {
|
||||
std::shared_ptr<TStruct>
|
||||
UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(THandle handle) {
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutex);
|
||||
if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
|
||||
m_structures[index].reset();
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutex);
|
||||
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
|
||||
return nullptr;
|
||||
return std::move(m_structures[index]);
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
@@ -99,4 +108,19 @@ void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
|
||||
}
|
||||
HandleBase::ResetHandles();
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
template <typename Functor>
|
||||
void UnlimitedHandleResource<THandle, TStruct, enumValue>::ForEach(
|
||||
Functor func) {
|
||||
std::lock_guard<wpi::mutex> lock(m_handleMutex);
|
||||
size_t i;
|
||||
for (i = 0; i < m_structures.size(); i++) {
|
||||
if (m_structures[i] != nullptr) {
|
||||
func(static_cast<THandle>(createHandle(i, enumValue, m_version)),
|
||||
m_structures[i].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace hal
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -63,3 +65,5 @@ void HALSIM_RegisterAccelerometerAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -45,3 +47,5 @@ void HALSIM_RegisterAnalogGyroAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -95,3 +97,5 @@ void HALSIM_RegisterAnalogInAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -38,3 +40,5 @@ void HALSIM_RegisterAnalogOutAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -62,3 +64,5 @@ void HALSIM_RegisterAnalogTriggerAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
78
hal/src/main/native/include/MockData/CanData.h
Normal file
78
hal/src/main/native/include/MockData/CanData.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "HAL_Value.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
typedef void (*HAL_CAN_SendMessageCallback)(const char* name, void* param,
|
||||
uint32_t messageID,
|
||||
const uint8_t* data,
|
||||
uint8_t dataSize, int32_t periodMs,
|
||||
int32_t* status);
|
||||
|
||||
typedef void (*HAL_CAN_ReceiveMessageCallback)(
|
||||
const char* name, void* param, uint32_t* messageID, uint32_t messageIDMask,
|
||||
uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, int32_t* status);
|
||||
|
||||
typedef void (*HAL_CAN_OpenStreamSessionCallback)(
|
||||
const char* name, void* param, uint32_t* sessionHandle, uint32_t messageID,
|
||||
uint32_t messageIDMask, uint32_t maxMessages, int32_t* status);
|
||||
|
||||
typedef void (*HAL_CAN_CloseStreamSessionCallback)(const char* name,
|
||||
void* param,
|
||||
uint32_t sessionHandle);
|
||||
|
||||
typedef void (*HAL_CAN_ReadStreamSessionCallback)(
|
||||
const char* name, void* param, uint32_t sessionHandle,
|
||||
struct HAL_CANStreamMessage* messages, uint32_t messagesToRead,
|
||||
uint32_t* messagesRead, int32_t* status);
|
||||
|
||||
typedef void (*HAL_CAN_GetCANStatusCallback)(
|
||||
const char* name, void* param, float* percentBusUtilization,
|
||||
uint32_t* busOffCount, uint32_t* txFullCount, uint32_t* receiveErrorCount,
|
||||
uint32_t* transmitErrorCount, int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void HALSIM_ResetCanData(void);
|
||||
|
||||
int32_t HALSIM_RegisterCanSendMessageCallback(
|
||||
HAL_CAN_SendMessageCallback callback, void* param);
|
||||
void HALSIM_CancelCanSendMessageCallback(int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterCanReceiveMessageCallback(
|
||||
HAL_CAN_ReceiveMessageCallback callback, void* param);
|
||||
void HALSIM_CancelCanReceiveMessageCallback(int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterCanOpenStreamCallback(
|
||||
HAL_CAN_OpenStreamSessionCallback callback, void* param);
|
||||
void HALSIM_CancelCanOpenStreamCallback(int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterCanCloseStreamCallback(
|
||||
HAL_CAN_CloseStreamSessionCallback callback, void* param);
|
||||
void HALSIM_CancelCanCloseStreamCallback(int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterCanReadStreamCallback(
|
||||
HAL_CAN_ReadStreamSessionCallback callback, void* param);
|
||||
void HALSIM_CancelCanReadStreamCallback(int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterCanGetCANStatusCallback(
|
||||
HAL_CAN_GetCANStatusCallback callback, void* param);
|
||||
void HALSIM_CancelCanGetCANStatusCallback(int32_t uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -59,3 +61,5 @@ void HALSIM_RegisterDIOAllCallbacks(int32_t index, HAL_NotifyCallback callback,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -45,3 +47,5 @@ void HALSIM_RegisterDigitalPWMAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/DriverStation.h"
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
@@ -20,52 +22,52 @@ int32_t HALSIM_RegisterDriverStationEnabledCallback(HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationEnabledCallback(int32_t uid);
|
||||
HAL_Bool HALSIM_GetDriverStationEnabled();
|
||||
HAL_Bool HALSIM_GetDriverStationEnabled(void);
|
||||
void HALSIM_SetDriverStationEnabled(HAL_Bool enabled);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationAutonomousCallback(
|
||||
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationAutonomousCallback(int32_t uid);
|
||||
HAL_Bool HALSIM_GetDriverStationAutonomous();
|
||||
HAL_Bool HALSIM_GetDriverStationAutonomous(void);
|
||||
void HALSIM_SetDriverStationAutonomous(HAL_Bool autonomous);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationTestCallback(HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationTestCallback(int32_t uid);
|
||||
HAL_Bool HALSIM_GetDriverStationTest();
|
||||
HAL_Bool HALSIM_GetDriverStationTest(void);
|
||||
void HALSIM_SetDriverStationTest(HAL_Bool test);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationEStopCallback(HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationEStopCallback(int32_t uid);
|
||||
HAL_Bool HALSIM_GetDriverStationEStop();
|
||||
HAL_Bool HALSIM_GetDriverStationEStop(void);
|
||||
void HALSIM_SetDriverStationEStop(HAL_Bool eStop);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationFmsAttachedCallback(
|
||||
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationFmsAttachedCallback(int32_t uid);
|
||||
HAL_Bool HALSIM_GetDriverStationFmsAttached();
|
||||
HAL_Bool HALSIM_GetDriverStationFmsAttached(void);
|
||||
void HALSIM_SetDriverStationFmsAttached(HAL_Bool fmsAttached);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationDsAttachedCallback(
|
||||
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationDsAttachedCallback(int32_t uid);
|
||||
HAL_Bool HALSIM_GetDriverStationDsAttached();
|
||||
HAL_Bool HALSIM_GetDriverStationDsAttached(void);
|
||||
void HALSIM_SetDriverStationDsAttached(HAL_Bool dsAttached);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationAllianceStationIdCallback(
|
||||
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationAllianceStationIdCallback(int32_t uid);
|
||||
HAL_AllianceStationID HALSIM_GetDriverStationAllianceStationId();
|
||||
HAL_AllianceStationID HALSIM_GetDriverStationAllianceStationId(void);
|
||||
void HALSIM_SetDriverStationAllianceStationId(
|
||||
HAL_AllianceStationID allianceStationId);
|
||||
|
||||
int32_t HALSIM_RegisterDriverStationMatchTimeCallback(
|
||||
HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
|
||||
void HALSIM_CancelDriverStationMatchTimeCallback(int32_t uid);
|
||||
double HALSIM_GetDriverStationMatchTime();
|
||||
double HALSIM_GetDriverStationMatchTime(void);
|
||||
void HALSIM_SetDriverStationMatchTime(double matchTime);
|
||||
|
||||
void HALSIM_SetJoystickAxes(int32_t joystickNum, const HAL_JoystickAxes* axes);
|
||||
@@ -86,6 +88,12 @@ void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
|
||||
|
||||
void HALSIM_NotifyDriverStationNewData(void);
|
||||
|
||||
void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -85,3 +87,5 @@ void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/Types.h"
|
||||
|
||||
/** HAL data types. */
|
||||
@@ -65,3 +67,5 @@ inline HAL_Value MakeDouble(double v) {
|
||||
value.data.v_double = v;
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -37,3 +39,5 @@ void HALSIM_CancelI2CWriteCallback(int32_t index, int32_t uid);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
extern "C" {
|
||||
void HALSIM_WaitForProgramStart(void);
|
||||
void HALSIM_SetProgramStarted(void);
|
||||
void HALSIM_RestartTiming(void);
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,10 +7,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "MockData/NotifyListenerVector.h"
|
||||
|
||||
template <typename VectorType, typename CallbackType>
|
||||
std::shared_ptr<VectorType> RegisterCallbackImpl(
|
||||
std::shared_ptr<VectorType> currentVector, const char* name,
|
||||
CallbackType callback, void* param, int32_t* newUid) {
|
||||
std::shared_ptr<VectorType> newCallbacks;
|
||||
if (currentVector == nullptr) {
|
||||
newCallbacks = std::make_shared<VectorType>(
|
||||
param, callback, reinterpret_cast<unsigned int*>(newUid));
|
||||
} else {
|
||||
newCallbacks = currentVector->emplace_back(
|
||||
param, callback, reinterpret_cast<unsigned int*>(newUid));
|
||||
}
|
||||
return newCallbacks;
|
||||
}
|
||||
|
||||
template <typename VectorType, typename CallbackType>
|
||||
std::shared_ptr<VectorType> CancelCallbackImpl(
|
||||
std::shared_ptr<VectorType> currentVector, int32_t uid) {
|
||||
// Create a copy of the callbacks to erase from
|
||||
auto newCallbacks = currentVector->erase(uid);
|
||||
return newCallbacks;
|
||||
}
|
||||
|
||||
std::shared_ptr<hal::NotifyListenerVector> RegisterCallback(
|
||||
std::shared_ptr<hal::NotifyListenerVector> currentVector, const char* name,
|
||||
HAL_NotifyCallback callback, void* param, int32_t* newUid);
|
||||
@@ -42,3 +67,5 @@ std::shared_ptr<hal::ConstBufferListenerVector> CancelCallback(
|
||||
void InvokeCallback(
|
||||
std::shared_ptr<hal::ConstBufferListenerVector> currentVector,
|
||||
const char* name, const uint8_t* buffer, int32_t count);
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL_Value.h"
|
||||
|
||||
typedef void (*HAL_NotifyCallback)(const char* name, void* param,
|
||||
@@ -34,3 +36,5 @@ struct HalCallbackListener {
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
@@ -136,3 +138,5 @@ typedef HalCallbackListenerVectorImpl<HAL_ConstBufferCallback>
|
||||
ConstBufferListenerVector;
|
||||
|
||||
} // namespace hal
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -87,3 +89,5 @@ void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -54,3 +56,5 @@ void HALSIM_RegisterPDPAllNonCurrentCallbacks(int32_t index, int32_t channel,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -66,3 +68,5 @@ void HALSIM_RegisterPWMAllCallbacks(int32_t index, HAL_NotifyCallback callback,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -54,3 +56,5 @@ void HALSIM_RegisterRelayAllCallcbaks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -140,3 +142,5 @@ void HALSIM_RegisterRoboRioAllCallbacks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -61,3 +63,5 @@ void HALSIM_RegisterSPIAccelerometerAllCallbcaks(int32_t index,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRC_ROBORIO__
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
@@ -50,3 +52,5 @@ int64_t HALSIM_GetSPIGetAccumulatorValue(int32_t index);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@ fpga_clock::time_point fpga_clock::now() noexcept {
|
||||
if (status != 0) {
|
||||
llvm::errs()
|
||||
<< "Call to HAL_GetFPGATime failed."
|
||||
<< "Initialization might have failed. Time will not be correct";
|
||||
<< "Initialization might have failed. Time will not be correct\n";
|
||||
llvm::errs().flush();
|
||||
return epoch();
|
||||
}
|
||||
|
||||
@@ -13,40 +13,39 @@
|
||||
#include <support/mutex.h>
|
||||
|
||||
namespace hal {
|
||||
static llvm::SmallVector<HandleBase*, 32> globalHandles;
|
||||
static wpi::mutex& GetGlobalHandleMutex() {
|
||||
static wpi::mutex globalHandleMutex;
|
||||
return globalHandleMutex;
|
||||
static llvm::SmallVector<HandleBase*, 32>* globalHandles;
|
||||
static wpi::mutex globalHandleMutex;
|
||||
namespace init {
|
||||
void InitializeHandlesInternal() {
|
||||
static llvm::SmallVector<HandleBase*, 32> gH;
|
||||
globalHandles = &gH;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
HandleBase::HandleBase() {
|
||||
std::lock_guard<wpi::mutex> lock(GetGlobalHandleMutex());
|
||||
auto index = std::find(globalHandles.begin(), globalHandles.end(), this);
|
||||
if (index == globalHandles.end()) {
|
||||
globalHandles.push_back(this);
|
||||
std::lock_guard<wpi::mutex> lock(globalHandleMutex);
|
||||
auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
|
||||
if (index == globalHandles->end()) {
|
||||
globalHandles->push_back(this);
|
||||
} else {
|
||||
*index = this;
|
||||
}
|
||||
}
|
||||
|
||||
HandleBase::~HandleBase() {
|
||||
std::lock_guard<wpi::mutex> lock(GetGlobalHandleMutex());
|
||||
auto index = std::find(globalHandles.begin(), globalHandles.end(), this);
|
||||
if (index != globalHandles.end()) {
|
||||
std::lock_guard<wpi::mutex> lock(globalHandleMutex);
|
||||
auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
|
||||
if (index != globalHandles->end()) {
|
||||
*index = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleBase::ResetHandles() {
|
||||
m_version++;
|
||||
if (m_version > 255) {
|
||||
m_version = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleBase::ResetGlobalHandles() {
|
||||
std::unique_lock<wpi::mutex> lock(GetGlobalHandleMutex());
|
||||
for (auto&& i : globalHandles) {
|
||||
std::unique_lock<wpi::mutex> lock(globalHandleMutex);
|
||||
for (auto&& i : *globalHandles) {
|
||||
if (i != nullptr) {
|
||||
lock.unlock();
|
||||
i->ResetHandles();
|
||||
@@ -54,7 +53,6 @@ void HandleBase::ResetGlobalHandles() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module) {
|
||||
// set last 8 bits, then shift to first 8 bits
|
||||
HAL_PortHandle handle = static_cast<HAL_PortHandle>(HAL_HandleEnum::Port);
|
||||
@@ -67,7 +65,6 @@ HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module) {
|
||||
handle += channel;
|
||||
return handle;
|
||||
}
|
||||
|
||||
HAL_PortHandle createPortHandleForSPI(uint8_t channel) {
|
||||
// set last 8 bits, then shift to first 8 bits
|
||||
HAL_PortHandle handle = static_cast<HAL_PortHandle>(HAL_HandleEnum::Port);
|
||||
@@ -82,7 +79,6 @@ HAL_PortHandle createPortHandleForSPI(uint8_t channel) {
|
||||
handle += channel;
|
||||
return handle;
|
||||
}
|
||||
|
||||
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
|
||||
int16_t version) {
|
||||
if (index < 0) return HAL_kInvalidHandle;
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAccelerometer() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
void HAL_SetAccelerometerActive(HAL_Bool active) {
|
||||
SimAccelerometerData[0].SetActive(active);
|
||||
|
||||
@@ -12,10 +12,16 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogAccumulator() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -27,7 +33,7 @@ HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -42,7 +48,7 @@ void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -54,7 +60,7 @@ void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t center, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -64,7 +70,7 @@ void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t deadband, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -74,7 +80,7 @@ void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -84,7 +90,7 @@ int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -94,7 +100,7 @@ int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
|
||||
int64_t* value, int64_t* count, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
|
||||
@@ -26,8 +26,18 @@ struct AnalogGyro {
|
||||
using namespace hal;
|
||||
|
||||
static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
|
||||
HAL_HandleEnum::AnalogGyro>
|
||||
analogGyroHandles;
|
||||
HAL_HandleEnum::AnalogGyro>* analogGyroHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogGyro() {
|
||||
static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
|
||||
HAL_HandleEnum::AnalogGyro>
|
||||
agH;
|
||||
analogGyroHandles = &agH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
|
||||
@@ -42,13 +52,13 @@ HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
|
||||
// handle known to be correct, so no need to type check
|
||||
int16_t channel = getHandleIndex(analogHandle);
|
||||
|
||||
auto handle = analogGyroHandles.Allocate(channel, status);
|
||||
auto handle = analogGyroHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
// Initialize port structure
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) { // would only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -67,8 +77,8 @@ void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
void HAL_FreeAnalogGyro(HAL_GyroHandle handle) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
analogGyroHandles.Free(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
analogGyroHandles->Free(handle);
|
||||
if (gyro == nullptr) return;
|
||||
SimAnalogGyroData[gyro->index].SetInitialized(false);
|
||||
}
|
||||
@@ -86,7 +96,7 @@ void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
|
||||
}
|
||||
|
||||
void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -106,7 +116,7 @@ void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
|
||||
}
|
||||
|
||||
double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -116,7 +126,7 @@ double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
|
||||
auto gyro = analogGyroHandles.Get(handle);
|
||||
auto gyro = analogGyroHandles->Get(handle);
|
||||
if (gyro == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogInput() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
|
||||
int32_t* status) {
|
||||
@@ -23,13 +29,13 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
HAL_AnalogInputHandle handle = analogInputHandles.Allocate(channel, status);
|
||||
HAL_AnalogInputHandle handle = analogInputHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
// Initialize port structure
|
||||
auto analog_port = analogInputHandles.Get(handle);
|
||||
auto analog_port = analogInputHandles->Get(handle);
|
||||
if (analog_port == nullptr) { // would only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -48,9 +54,9 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
|
||||
return handle;
|
||||
}
|
||||
void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
// no status, so no need to check for a proper free.
|
||||
analogInputHandles.Free(analogPortHandle);
|
||||
analogInputHandles->Free(analogPortHandle);
|
||||
if (port == nullptr) return;
|
||||
SimAnalogInData[port->channel].SetInitialized(false);
|
||||
SimAnalogInData[port->channel].SetAccumulatorInitialized(false);
|
||||
@@ -68,7 +74,7 @@ void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status) {
|
||||
double HAL_GetAnalogSampleRate(int32_t* status) { return kDefaultSampleRate; }
|
||||
void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t bits, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -78,7 +84,7 @@ void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -88,7 +94,7 @@ int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t bits, int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -98,7 +104,7 @@ void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -108,7 +114,7 @@ int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -140,7 +146,7 @@ int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
@@ -150,7 +156,7 @@ double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
}
|
||||
double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles.Get(analogPortHandle);
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
|
||||
namespace hal {
|
||||
IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort, kNumAnalogInputs,
|
||||
HAL_HandleEnum::AnalogInput>
|
||||
analogInputHandles;
|
||||
HAL_HandleEnum::AnalogInput>* analogInputHandles;
|
||||
} // namespace hal
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogInternal() {
|
||||
static IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
|
||||
aiH;
|
||||
analogInputHandles = &aiH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "HAL/Ports.h"
|
||||
#include "HAL/handles/IndexedHandleResource.h"
|
||||
#include "PortsInternal.h"
|
||||
|
||||
namespace hal {
|
||||
constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock
|
||||
constexpr int32_t kDefaultOversampleBits = 0;
|
||||
constexpr int32_t kDefaultAverageBits = 7;
|
||||
constexpr double kDefaultSampleRate = 50000.0;
|
||||
static const uint32_t kAccumulatorChannels[] = {0, 1};
|
||||
|
||||
struct AnalogPort {
|
||||
uint8_t channel;
|
||||
bool isAccumulator;
|
||||
};
|
||||
|
||||
extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
|
||||
analogInputHandles;
|
||||
|
||||
int32_t GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
|
||||
int32_t* status);
|
||||
} // namespace hal
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "HAL/Ports.h"
|
||||
#include "HAL/handles/IndexedHandleResource.h"
|
||||
#include "PortsInternal.h"
|
||||
|
||||
namespace hal {
|
||||
constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock
|
||||
constexpr int32_t kDefaultOversampleBits = 0;
|
||||
constexpr int32_t kDefaultAverageBits = 7;
|
||||
constexpr double kDefaultSampleRate = 50000.0;
|
||||
static constexpr uint32_t kAccumulatorChannels[] = {0, 1};
|
||||
|
||||
struct AnalogPort {
|
||||
uint8_t channel;
|
||||
bool isAccumulator;
|
||||
};
|
||||
|
||||
extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
|
||||
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
|
||||
analogInputHandles;
|
||||
|
||||
int32_t GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
|
||||
int32_t* status);
|
||||
} // namespace hal
|
||||
|
||||
@@ -22,9 +22,20 @@ struct AnalogOutput {
|
||||
} // namespace
|
||||
|
||||
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
|
||||
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
|
||||
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>*
|
||||
analogOutputHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogOutput() {
|
||||
static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
|
||||
kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
|
||||
aoH;
|
||||
analogOutputHandles = &aoH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
|
||||
int32_t* status) {
|
||||
@@ -34,12 +45,13 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
HAL_AnalogOutputHandle handle = analogOutputHandles.Allocate(channel, status);
|
||||
HAL_AnalogOutputHandle handle =
|
||||
analogOutputHandles->Allocate(channel, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = analogOutputHandles.Get(handle);
|
||||
auto port = analogOutputHandles->Get(handle);
|
||||
if (port == nullptr) { // would only error on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -54,9 +66,9 @@ HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
|
||||
|
||||
void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
|
||||
// no status, so no need to check for a proper free.
|
||||
auto port = analogOutputHandles.Get(analogOutputHandle);
|
||||
auto port = analogOutputHandles->Get(analogOutputHandle);
|
||||
if (port == nullptr) return;
|
||||
analogOutputHandles.Free(analogOutputHandle);
|
||||
analogOutputHandles->Free(analogOutputHandle);
|
||||
SimAnalogOutData[port->channel].SetInitialized(false);
|
||||
}
|
||||
|
||||
@@ -66,7 +78,7 @@ HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
|
||||
|
||||
void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
|
||||
double voltage, int32_t* status) {
|
||||
auto port = analogOutputHandles.Get(analogOutputHandle);
|
||||
auto port = analogOutputHandles->Get(analogOutputHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -77,7 +89,7 @@ void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
|
||||
|
||||
double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogOutputHandles.Get(analogOutputHandle);
|
||||
auto port = analogOutputHandles->Get(analogOutputHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
|
||||
@@ -27,23 +27,54 @@ struct AnalogTrigger {
|
||||
using namespace hal;
|
||||
|
||||
static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
|
||||
kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>
|
||||
kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>*
|
||||
analogTriggerHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAnalogTrigger() {
|
||||
static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
|
||||
kNumAnalogTriggers,
|
||||
HAL_HandleEnum::AnalogTrigger>
|
||||
atH;
|
||||
analogTriggerHandles = &atH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
int32_t hal::GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles->Get(handle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto analog_port = analogInputHandles->Get(trigger->analogHandle);
|
||||
if (analog_port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return analog_port->channel;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
|
||||
HAL_AnalogInputHandle portHandle, int32_t* index, int32_t* status) {
|
||||
// ensure we are given a valid and active AnalogInput handle
|
||||
auto analog_port = analogInputHandles.Get(portHandle);
|
||||
auto analog_port = analogInputHandles->Get(portHandle);
|
||||
if (analog_port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
HAL_AnalogTriggerHandle handle = analogTriggerHandles.Allocate();
|
||||
HAL_AnalogTriggerHandle handle = analogTriggerHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto trigger = analogTriggerHandles.Get(handle);
|
||||
auto trigger = analogTriggerHandles->Get(handle);
|
||||
if (trigger == nullptr) { // would only occur on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -61,8 +92,8 @@ HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
|
||||
|
||||
void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
analogTriggerHandles.Free(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
analogTriggerHandles->Free(analogTriggerHandle);
|
||||
if (trigger == nullptr) return;
|
||||
SimAnalogTriggerData[trigger->index].SetInitialized(false);
|
||||
// caller owns the analog input handle.
|
||||
@@ -78,27 +109,10 @@ static double GetAnalogValueToVoltage(
|
||||
return voltage;
|
||||
}
|
||||
|
||||
int32_t hal::GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(handle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto analog_port = analogInputHandles.Get(trigger->analogHandle);
|
||||
if (analog_port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return analog_port->channel;
|
||||
}
|
||||
|
||||
void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
int32_t lower, int32_t upper,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -120,7 +134,7 @@ void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
void HAL_SetAnalogTriggerLimitsVoltage(
|
||||
HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
|
||||
int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -134,7 +148,7 @@ void HAL_SetAnalogTriggerLimitsVoltage(
|
||||
}
|
||||
void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
HAL_Bool useAveragedValue, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -153,7 +167,7 @@ void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
}
|
||||
void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
HAL_Bool useFilteredValue, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -172,7 +186,7 @@ void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
}
|
||||
|
||||
static double GetTriggerValue(AnalogTrigger* trigger, int32_t* status) {
|
||||
auto analogIn = analogInputHandles.Get(trigger->analogHandle);
|
||||
auto analogIn = analogInputHandles->Get(trigger->analogHandle);
|
||||
if (analogIn == nullptr) {
|
||||
// Returning HAL Handle Error, but going to ignore lower down
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
@@ -184,7 +198,7 @@ static double GetTriggerValue(AnalogTrigger* trigger, int32_t* status) {
|
||||
|
||||
HAL_Bool HAL_GetAnalogTriggerInWindow(
|
||||
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -204,7 +218,7 @@ HAL_Bool HAL_GetAnalogTriggerInWindow(
|
||||
}
|
||||
HAL_Bool HAL_GetAnalogTriggerTriggerState(
|
||||
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
|
||||
auto trigger = analogTriggerHandles.Get(analogTriggerHandle);
|
||||
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
|
||||
if (trigger == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -242,3 +256,4 @@ HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
@@ -7,22 +7,49 @@
|
||||
|
||||
#include "HAL/CAN.h"
|
||||
|
||||
#include "MockData/CanDataInternal.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCAN() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,
|
||||
uint8_t dataSize, int32_t periodMs, int32_t* status) {}
|
||||
uint8_t dataSize, int32_t periodMs, int32_t* status) {
|
||||
SimCanData->SendMessage(messageID, data, dataSize, periodMs, status);
|
||||
}
|
||||
void HAL_CAN_ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
|
||||
uint8_t* data, uint8_t* dataSize,
|
||||
uint32_t* timeStamp, int32_t* status) {}
|
||||
uint32_t* timeStamp, int32_t* status) {
|
||||
SimCanData->ReceiveMessage(messageID, messageIDMask, data, dataSize,
|
||||
timeStamp, status);
|
||||
}
|
||||
void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
|
||||
uint32_t messageIDMask, uint32_t maxMessages,
|
||||
int32_t* status) {}
|
||||
void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {}
|
||||
int32_t* status) {
|
||||
SimCanData->OpenStreamSession(sessionHandle, messageID, messageIDMask,
|
||||
maxMessages, status);
|
||||
}
|
||||
void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {
|
||||
SimCanData->CloseStreamSession(sessionHandle);
|
||||
}
|
||||
void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
|
||||
struct HAL_CANStreamMessage* messages,
|
||||
uint32_t messagesToRead, uint32_t* messagesRead,
|
||||
int32_t* status) {}
|
||||
int32_t* status) {
|
||||
SimCanData->ReadStreamSession(sessionHandle, messages, messagesToRead,
|
||||
messagesRead, status);
|
||||
}
|
||||
void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
|
||||
uint32_t* txFullCount, uint32_t* receiveErrorCount,
|
||||
uint32_t* transmitErrorCount, int32_t* status) {}
|
||||
uint32_t* transmitErrorCount, int32_t* status) {
|
||||
SimCanData->GetCANStatus(percentBusUtilization, busOffCount, txFullCount,
|
||||
receiveErrorCount, transmitErrorCount, status);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -1,115 +1,121 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "HAL/Compressor.h"
|
||||
|
||||
#include "HAL/Errors.h"
|
||||
#include "HAL/handles/HandlesInternal.h"
|
||||
#include "MockData/PCMDataInternal.h"
|
||||
#include "PortsInternal.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
|
||||
// As compressors can have unlimited objects, just create a
|
||||
// handle with the module number as the index.
|
||||
|
||||
SimPCMData[module].SetCompressorInitialized(true);
|
||||
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
|
||||
HAL_HandleEnum::Compressor, 0);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
|
||||
return module < kNumPCMModules && module >= 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetCompressorOn();
|
||||
}
|
||||
|
||||
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
|
||||
HAL_Bool value, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
SimPCMData[index].SetClosedLoopEnabled(value);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressorClosedLoopControl(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetClosedLoopEnabled();
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetPressureSwitch();
|
||||
}
|
||||
|
||||
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetCompressorCurrent();
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorShortedStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorNotConnectedFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
} // extern "C"
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "HAL/Compressor.h"
|
||||
|
||||
#include "HAL/Errors.h"
|
||||
#include "HAL/handles/HandlesInternal.h"
|
||||
#include "MockData/PCMDataInternal.h"
|
||||
#include "PortsInternal.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCompressor() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
|
||||
// As compressors can have unlimited objects, just create a
|
||||
// handle with the module number as the index.
|
||||
|
||||
SimPCMData[module].SetCompressorInitialized(true);
|
||||
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
|
||||
HAL_HandleEnum::Compressor, 0);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
|
||||
return module < kNumPCMModules && module >= 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetCompressorOn();
|
||||
}
|
||||
|
||||
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
|
||||
HAL_Bool value, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
SimPCMData[index].SetClosedLoopEnabled(value);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressorClosedLoopControl(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetClosedLoopEnabled();
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetPressureSwitch();
|
||||
}
|
||||
|
||||
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SimPCMData[index].GetCompressorCurrent();
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorShortedStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorNotConnectedFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeConstants() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
int32_t HAL_GetSystemClockTicksPerMicrosecond(void) {
|
||||
return kSystemClockTicksPerMicrosecond;
|
||||
|
||||
@@ -16,8 +16,18 @@
|
||||
namespace hal {
|
||||
|
||||
LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
|
||||
HAL_HandleEnum::Counter>
|
||||
counterHandles;
|
||||
HAL_HandleEnum::Counter>* counterHandles;
|
||||
} // namespace hal
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCounter() {
|
||||
static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
|
||||
HAL_HandleEnum::Counter>
|
||||
cH;
|
||||
counterHandles = &cH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -18,7 +18,6 @@ struct Counter {
|
||||
};
|
||||
|
||||
extern LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
|
||||
HAL_HandleEnum::Counter>
|
||||
counterHandles;
|
||||
HAL_HandleEnum::Counter>* counterHandles;
|
||||
|
||||
} // namespace hal
|
||||
|
||||
@@ -19,9 +19,21 @@
|
||||
using namespace hal;
|
||||
|
||||
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
|
||||
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>
|
||||
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>*
|
||||
digitalPWMHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeDIO() {
|
||||
static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
|
||||
kNumDigitalPWMOutputs,
|
||||
HAL_HandleEnum::DigitalPWM>
|
||||
dpH;
|
||||
digitalPWMHandles = &dpH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
@@ -38,12 +50,12 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
|
||||
}
|
||||
|
||||
auto handle =
|
||||
digitalChannelHandles.Allocate(channel, HAL_HandleEnum::DIO, status);
|
||||
digitalChannelHandles->Allocate(channel, HAL_HandleEnum::DIO, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = digitalChannelHandles.Get(handle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -63,9 +75,9 @@ HAL_Bool HAL_CheckDIOChannel(int32_t channel) {
|
||||
}
|
||||
|
||||
void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
// no status, so no need to check for a proper free.
|
||||
digitalChannelHandles.Free(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) return;
|
||||
SimDIOData[port->channel].SetInitialized(true);
|
||||
}
|
||||
@@ -77,13 +89,13 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
|
||||
* @return PWM Generator handle
|
||||
*/
|
||||
HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
|
||||
auto handle = digitalPWMHandles.Allocate();
|
||||
auto handle = digitalPWMHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
auto id = digitalPWMHandles.Get(handle);
|
||||
auto id = digitalPWMHandles->Get(handle);
|
||||
if (id == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -102,8 +114,8 @@ HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
|
||||
* allocateDigitalPWM()
|
||||
*/
|
||||
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
|
||||
auto port = digitalPWMHandles.Get(pwmGenerator);
|
||||
digitalPWMHandles.Free(pwmGenerator);
|
||||
auto port = digitalPWMHandles->Get(pwmGenerator);
|
||||
digitalPWMHandles->Free(pwmGenerator);
|
||||
if (port == nullptr) return;
|
||||
int32_t id = *port;
|
||||
SimDigitalPWMData[id].SetInitialized(false);
|
||||
@@ -137,7 +149,7 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
|
||||
*/
|
||||
void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
|
||||
double dutyCycle, int32_t* status) {
|
||||
auto port = digitalPWMHandles.Get(pwmGenerator);
|
||||
auto port = digitalPWMHandles->Get(pwmGenerator);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -156,7 +168,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
|
||||
*/
|
||||
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
|
||||
int32_t channel, int32_t* status) {
|
||||
auto port = digitalPWMHandles.Get(pwmGenerator);
|
||||
auto port = digitalPWMHandles->Get(pwmGenerator);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -175,7 +187,7 @@ void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
|
||||
*/
|
||||
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -194,7 +206,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
|
||||
* @return The state of the specified channel
|
||||
*/
|
||||
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -213,7 +225,7 @@ HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
* @return The direction of the specified channel
|
||||
*/
|
||||
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -234,7 +246,7 @@ HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
*/
|
||||
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -248,7 +260,7 @@ void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
|
||||
* @return A pulse is in progress
|
||||
*/
|
||||
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
@@ -276,7 +288,7 @@ HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
|
||||
*/
|
||||
void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
|
||||
int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -294,7 +306,7 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
|
||||
* where 0 means "none" and 1 - 3 means filter # filterIndex - 1.
|
||||
*/
|
||||
int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
|
||||
auto port = digitalChannelHandles.Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
|
||||
@@ -15,12 +15,19 @@
|
||||
|
||||
namespace hal {
|
||||
|
||||
bool digitalSystemsInitialized = false;
|
||||
|
||||
DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
|
||||
kNumDigitalChannels + kNumPWMHeaders>
|
||||
kNumDigitalChannels + kNumPWMHeaders>*
|
||||
digitalChannelHandles;
|
||||
|
||||
namespace init {
|
||||
void InitializeDigitalInternal() {
|
||||
static DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
|
||||
kNumDigitalChannels + kNumPWMHeaders>
|
||||
dcH;
|
||||
digitalChannelHandles = &dcH;
|
||||
}
|
||||
} // namespace init
|
||||
|
||||
/**
|
||||
* Map DIO channel numbers from their physical number (10 to 26) to their
|
||||
* position in the bit field.
|
||||
@@ -69,7 +76,7 @@ bool remapDigitalSource(HAL_Handle digitalSourceHandle,
|
||||
}
|
||||
|
||||
int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status) {
|
||||
auto digital = digitalChannelHandles.Get(handle, HAL_HandleEnum::DIO);
|
||||
auto digital = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
|
||||
if (digital == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return -1;
|
||||
|
||||
@@ -67,7 +67,7 @@ struct DigitalPort {
|
||||
};
|
||||
|
||||
extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
|
||||
kNumDigitalChannels + kNumPWMHeaders>
|
||||
kNumDigitalChannels + kNumPWMHeaders>*
|
||||
digitalChannelHandles;
|
||||
|
||||
bool remapDigitalSource(HAL_Handle digitalSourceHandle,
|
||||
|
||||
@@ -23,10 +23,19 @@
|
||||
#include "MockData/MockHooks.h"
|
||||
|
||||
static wpi::mutex msgMutex;
|
||||
static wpi::condition_variable newDSDataAvailableCond;
|
||||
static wpi::condition_variable* newDSDataAvailableCond;
|
||||
static wpi::mutex newDSDataAvailableMutex;
|
||||
static int newDSDataAvailableCounter{0};
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeDriverStation() {
|
||||
static wpi::condition_variable nddaC;
|
||||
newDSDataAvailableCond = &nddaC;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
using namespace hal;
|
||||
|
||||
extern "C" {
|
||||
@@ -85,33 +94,33 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
|
||||
}
|
||||
|
||||
int32_t HAL_GetControlWord(HAL_ControlWord* controlWord) {
|
||||
controlWord->enabled = SimDriverStationData.GetEnabled();
|
||||
controlWord->autonomous = SimDriverStationData.GetAutonomous();
|
||||
controlWord->test = SimDriverStationData.GetTest();
|
||||
controlWord->eStop = SimDriverStationData.GetEStop();
|
||||
controlWord->fmsAttached = SimDriverStationData.GetFmsAttached();
|
||||
controlWord->dsAttached = SimDriverStationData.GetDsAttached();
|
||||
controlWord->enabled = SimDriverStationData->GetEnabled();
|
||||
controlWord->autonomous = SimDriverStationData->GetAutonomous();
|
||||
controlWord->test = SimDriverStationData->GetTest();
|
||||
controlWord->eStop = SimDriverStationData->GetEStop();
|
||||
controlWord->fmsAttached = SimDriverStationData->GetFmsAttached();
|
||||
controlWord->dsAttached = SimDriverStationData->GetDsAttached();
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
|
||||
*status = 0;
|
||||
return SimDriverStationData.GetAllianceStationId();
|
||||
return SimDriverStationData->GetAllianceStationId();
|
||||
}
|
||||
|
||||
int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes) {
|
||||
SimDriverStationData.GetJoystickAxes(joystickNum, axes);
|
||||
SimDriverStationData->GetJoystickAxes(joystickNum, axes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
|
||||
SimDriverStationData.GetJoystickPOVs(joystickNum, povs);
|
||||
SimDriverStationData->GetJoystickPOVs(joystickNum, povs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
|
||||
HAL_JoystickButtons* buttons) {
|
||||
SimDriverStationData.GetJoystickButtons(joystickNum, buttons);
|
||||
SimDriverStationData->GetJoystickButtons(joystickNum, buttons);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
@@ -127,25 +136,25 @@ int32_t HAL_GetJoystickButtons(int32_t joystickNum,
|
||||
*/
|
||||
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
|
||||
HAL_JoystickDescriptor* desc) {
|
||||
SimDriverStationData.GetJoystickDescriptor(joystickNum, desc);
|
||||
SimDriverStationData->GetJoystickDescriptor(joystickNum, desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum) {
|
||||
HAL_JoystickDescriptor desc;
|
||||
SimDriverStationData.GetJoystickDescriptor(joystickNum, &desc);
|
||||
SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
|
||||
return desc.isXbox;
|
||||
}
|
||||
|
||||
int32_t HAL_GetJoystickType(int32_t joystickNum) {
|
||||
HAL_JoystickDescriptor desc;
|
||||
SimDriverStationData.GetJoystickDescriptor(joystickNum, &desc);
|
||||
SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
|
||||
return desc.type;
|
||||
}
|
||||
|
||||
char* HAL_GetJoystickName(int32_t joystickNum) {
|
||||
HAL_JoystickDescriptor desc;
|
||||
SimDriverStationData.GetJoystickDescriptor(joystickNum, &desc);
|
||||
SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
|
||||
size_t len = std::strlen(desc.name);
|
||||
char* name = static_cast<char*>(std::malloc(len + 1));
|
||||
std::strncpy(name, desc.name, len);
|
||||
@@ -159,22 +168,22 @@ int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) { return 0; }
|
||||
|
||||
int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
|
||||
int32_t leftRumble, int32_t rightRumble) {
|
||||
SimDriverStationData.SetJoystickOutputs(joystickNum, outputs, leftRumble,
|
||||
rightRumble);
|
||||
SimDriverStationData->SetJoystickOutputs(joystickNum, outputs, leftRumble,
|
||||
rightRumble);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double HAL_GetMatchTime(int32_t* status) {
|
||||
return SimDriverStationData.GetMatchTime();
|
||||
return SimDriverStationData->GetMatchTime();
|
||||
}
|
||||
|
||||
int HAL_GetMatchInfo(HAL_MatchInfo* info) {
|
||||
SimDriverStationData.GetMatchInfo(info);
|
||||
SimDriverStationData->GetMatchInfo(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_FreeMatchInfo(HAL_MatchInfo* info) {
|
||||
SimDriverStationData.FreeMatchInfo(info);
|
||||
SimDriverStationData->FreeMatchInfo(info);
|
||||
}
|
||||
|
||||
void HAL_ObserveUserProgramStarting(void) { HALSIM_SetProgramStarted(); }
|
||||
@@ -199,7 +208,9 @@ void HAL_ObserveUserProgramTest(void) {
|
||||
static pthread_key_t lastCountKey;
|
||||
static pthread_once_t lastCountKeyOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void InitLastCountKey() { pthread_key_create(&lastCountKey, std::free); }
|
||||
static void InitLastCountKey(void) {
|
||||
pthread_key_create(&lastCountKey, std::free);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool HAL_IsNewControlData(void) {
|
||||
@@ -247,12 +258,12 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
|
||||
int currentCount = newDSDataAvailableCounter;
|
||||
while (newDSDataAvailableCounter == currentCount) {
|
||||
if (timeout > 0) {
|
||||
auto timedOut = newDSDataAvailableCond.wait_until(lock, timeoutTime);
|
||||
auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
|
||||
if (timedOut == std::cv_status::timeout) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
newDSDataAvailableCond.wait(lock);
|
||||
newDSDataAvailableCond->wait(lock);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -268,7 +279,7 @@ static int32_t newDataOccur(uint32_t refNum) {
|
||||
std::lock_guard<wpi::mutex> lock(newDSDataAvailableMutex);
|
||||
// Nofify all threads
|
||||
newDSDataAvailableCounter++;
|
||||
newDSDataAvailableCond.notify_all();
|
||||
newDSDataAvailableCond->notify_all();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -287,7 +298,7 @@ void HAL_InitializeDriverStation(void) {
|
||||
// Second check in case another thread was waiting
|
||||
if (initialized) return;
|
||||
|
||||
SimDriverStationData.ResetData();
|
||||
SimDriverStationData->ResetData();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,26 @@ struct Empty {};
|
||||
|
||||
static LimitedHandleResource<HAL_EncoderHandle, Encoder,
|
||||
kNumEncoders + kNumCounters,
|
||||
HAL_HandleEnum::Encoder>
|
||||
encoderHandles;
|
||||
HAL_HandleEnum::Encoder>* encoderHandles;
|
||||
|
||||
static LimitedHandleResource<HAL_FPGAEncoderHandle, Empty, kNumEncoders,
|
||||
HAL_HandleEnum::FPGAEncoder>
|
||||
fpgaEncoderHandles;
|
||||
HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeEncoder() {
|
||||
static LimitedHandleResource<HAL_FPGAEncoderHandle, Empty, kNumEncoders,
|
||||
HAL_HandleEnum::FPGAEncoder>
|
||||
feH;
|
||||
fpgaEncoderHandles = &feH;
|
||||
static LimitedHandleResource<HAL_EncoderHandle, Encoder,
|
||||
kNumEncoders + kNumCounters,
|
||||
HAL_HandleEnum::Encoder>
|
||||
eH;
|
||||
encoderHandles = &eH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
@@ -45,21 +59,21 @@ HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
HAL_Handle nativeHandle = HAL_kInvalidHandle;
|
||||
if (encodingType == HAL_EncoderEncodingType::HAL_Encoder_k4X) {
|
||||
// k4x, allocate encoder
|
||||
nativeHandle = fpgaEncoderHandles.Allocate();
|
||||
nativeHandle = fpgaEncoderHandles->Allocate();
|
||||
} else {
|
||||
// k2x or k1x, allocate counter
|
||||
nativeHandle = counterHandles.Allocate();
|
||||
nativeHandle = counterHandles->Allocate();
|
||||
}
|
||||
if (nativeHandle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto handle = encoderHandles.Allocate();
|
||||
auto handle = encoderHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto encoder = encoderHandles.Get(handle);
|
||||
auto encoder = encoderHandles->Get(handle);
|
||||
if (encoder == nullptr) { // would only occur on thread issue
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -75,13 +89,13 @@ HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
}
|
||||
|
||||
void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
encoderHandles.Free(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
encoderHandles->Free(encoderHandle);
|
||||
if (encoder == nullptr) return;
|
||||
if (isHandleType(encoder->nativeHandle, HAL_HandleEnum::FPGAEncoder)) {
|
||||
fpgaEncoderHandles.Free(encoder->nativeHandle);
|
||||
fpgaEncoderHandles->Free(encoder->nativeHandle);
|
||||
} else if (isHandleType(encoder->nativeHandle, HAL_HandleEnum::Counter)) {
|
||||
counterHandles.Free(encoder->nativeHandle);
|
||||
counterHandles->Free(encoder->nativeHandle);
|
||||
}
|
||||
SimEncoderData[encoder->index].SetInitialized(false);
|
||||
}
|
||||
@@ -113,7 +127,7 @@ static inline double DecodingScaleFactor(Encoder* encoder) {
|
||||
}
|
||||
|
||||
int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -122,7 +136,7 @@ int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
return SimEncoderData[encoder->index].GetCount();
|
||||
}
|
||||
int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -133,7 +147,7 @@ int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
}
|
||||
int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -142,7 +156,7 @@ int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
|
||||
return EncodingScaleFactor(encoder.get());
|
||||
}
|
||||
void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -153,7 +167,7 @@ void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
SimEncoderData[encoder->index].SetReset(true);
|
||||
}
|
||||
double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -163,7 +177,7 @@ double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
}
|
||||
void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -173,7 +187,7 @@ void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
|
||||
}
|
||||
HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -184,7 +198,7 @@ HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
|
||||
}
|
||||
HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -194,7 +208,7 @@ HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
|
||||
}
|
||||
double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -203,7 +217,7 @@ double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
|
||||
return SimEncoderData[encoder->index].GetCount() * encoder->distancePerPulse;
|
||||
}
|
||||
double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -213,7 +227,7 @@ double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
}
|
||||
void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -229,7 +243,7 @@ void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
|
||||
}
|
||||
void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
double distancePerPulse, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -244,7 +258,7 @@ void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
|
||||
HAL_Bool reverseDirection,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -254,7 +268,7 @@ void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
|
||||
}
|
||||
void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
int32_t samplesToAverage, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -264,7 +278,7 @@ void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
}
|
||||
int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -282,7 +296,7 @@ void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -293,7 +307,7 @@ int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
@@ -304,7 +318,7 @@ double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0.0;
|
||||
@@ -315,7 +329,7 @@ double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
|
||||
|
||||
HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
|
||||
HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoderHandle);
|
||||
auto encoder = encoderHandles->Get(encoderHandle);
|
||||
if (encoder == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_Encoder_k4X; // default to k4x
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
#define DLCLOSE dlclose
|
||||
#endif
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeExtensions() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
int HAL_LoadOneExtension(const char* library) {
|
||||
|
||||
@@ -14,11 +14,66 @@
|
||||
#include "HAL/Errors.h"
|
||||
#include "HAL/Extensions.h"
|
||||
#include "HAL/handles/HandlesInternal.h"
|
||||
#include "HALInitializer.h"
|
||||
#include "MockData/RoboRioDataInternal.h"
|
||||
#include "MockHooksInternal.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeHAL() {
|
||||
InitializeHandlesInternal();
|
||||
InitializeAccelerometerData();
|
||||
InitializeAnalogGyroData();
|
||||
InitializeAnalogInData();
|
||||
InitializeAnalogOutData();
|
||||
InitializeAnalogTriggerData();
|
||||
InitializeCanData();
|
||||
InitializeDigitalPWMData();
|
||||
InitializeDIOData();
|
||||
InitializeDriverStationData();
|
||||
InitializeEncoderData();
|
||||
InitializeI2CData();
|
||||
InitializePCMData();
|
||||
InitializePDPData();
|
||||
InitializePWMData();
|
||||
InitializeRelayData();
|
||||
InitializeRoboRioData();
|
||||
InitializeSPIAccelerometerData();
|
||||
InitializeSPIData();
|
||||
InitializeAccelerometer();
|
||||
InitializeAnalogAccumulator();
|
||||
InitializeAnalogGyro();
|
||||
InitializeAnalogInput();
|
||||
InitializeAnalogInternal();
|
||||
InitializeAnalogOutput();
|
||||
InitializeCAN();
|
||||
InitializeCompressor();
|
||||
InitializeConstants();
|
||||
InitializeCounter();
|
||||
InitializeDigitalInternal();
|
||||
InitializeDIO();
|
||||
InitializeDriverStation();
|
||||
InitializeExtensions();
|
||||
InitializeI2C();
|
||||
InitializeInterrupts();
|
||||
InitializeMockHooks();
|
||||
InitializeNotifier();
|
||||
InitializeOSSerialPort();
|
||||
InitializePDP();
|
||||
InitializePorts();
|
||||
InitializePower();
|
||||
InitializePWM();
|
||||
InitializeRelay();
|
||||
InitializeSerialPort();
|
||||
InitializeSolenoid();
|
||||
InitializeSPI();
|
||||
InitializeThreads();
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_PortHandle HAL_GetPort(int32_t channel) {
|
||||
@@ -149,7 +204,7 @@ const char* HAL_GetErrorMessage(int32_t code) {
|
||||
/**
|
||||
* Returns the runtime type of this HAL
|
||||
*/
|
||||
HAL_RuntimeType HAL_GetRuntimeType() { return HAL_Mock; }
|
||||
HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
|
||||
|
||||
/**
|
||||
* Return the FPGA Version number.
|
||||
@@ -206,6 +261,8 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
|
||||
// Second check in case another thread was waiting
|
||||
if (initialized) return true;
|
||||
|
||||
hal::init::InitializeHAL();
|
||||
|
||||
llvm::outs().SetUnbuffered();
|
||||
if (HAL_LoadExtensions() < 0) return false;
|
||||
hal::RestartTiming();
|
||||
|
||||
62
hal/src/main/native/sim/HALInitializer.h
Normal file
62
hal/src/main/native/sim/HALInitializer.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
extern void InitializeHandlesInternal();
|
||||
extern void InitializeAccelerometerData();
|
||||
extern void InitializeAnalogGyroData();
|
||||
extern void InitializeAnalogInData();
|
||||
extern void InitializeAnalogOutData();
|
||||
extern void InitializeAnalogTriggerData();
|
||||
extern void InitializeCanData();
|
||||
extern void InitializeDigitalPWMData();
|
||||
extern void InitializeDIOData();
|
||||
extern void InitializeDriverStationData();
|
||||
extern void InitializeEncoderData();
|
||||
extern void InitializeI2CData();
|
||||
extern void InitializePCMData();
|
||||
extern void InitializePDPData();
|
||||
extern void InitializePWMData();
|
||||
extern void InitializeRelayData();
|
||||
extern void InitializeRoboRioData();
|
||||
extern void InitializeSPIAccelerometerData();
|
||||
extern void InitializeSPIData();
|
||||
extern void InitializeAccelerometer();
|
||||
extern void InitializeAnalogAccumulator();
|
||||
extern void InitializeAnalogGyro();
|
||||
extern void InitializeAnalogInput();
|
||||
extern void InitializeAnalogInternal();
|
||||
extern void InitializeAnalogOutput();
|
||||
extern void InitializeCAN();
|
||||
extern void InitializeCompressor();
|
||||
extern void InitializeConstants();
|
||||
extern void InitializeCounter();
|
||||
extern void InitializeDigitalInternal();
|
||||
extern void InitializeDIO();
|
||||
extern void InitializeDriverStation();
|
||||
extern void InitializeExtensions();
|
||||
extern void InitializeHAL();
|
||||
extern void InitializeI2C();
|
||||
extern void InitializeInterrupts();
|
||||
extern void InitializeMockHooks();
|
||||
extern void InitializeNotifier();
|
||||
extern void InitializeOSSerialPort();
|
||||
extern void InitializePDP();
|
||||
extern void InitializePorts();
|
||||
extern void InitializePower();
|
||||
extern void InitializePWM();
|
||||
extern void InitializeRelay();
|
||||
extern void InitializeSerialPort();
|
||||
extern void InitializeSolenoid();
|
||||
extern void InitializeSPI();
|
||||
extern void InitializeThreads();
|
||||
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeI2C() {}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
|
||||
SimI2CData[port].SetInitialized(true);
|
||||
|
||||
@@ -60,23 +60,37 @@ struct SynchronousWaitData {
|
||||
} // namespace
|
||||
|
||||
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
|
||||
HAL_HandleEnum::Interrupt>
|
||||
interruptHandles;
|
||||
HAL_HandleEnum::Interrupt>* interruptHandles;
|
||||
|
||||
typedef HAL_Handle SynchronousWaitDataHandle;
|
||||
static UnlimitedHandleResource<SynchronousWaitDataHandle, SynchronousWaitData,
|
||||
HAL_HandleEnum::Vendor>
|
||||
HAL_HandleEnum::Vendor>*
|
||||
synchronousInterruptHandles;
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeInterrupts() {
|
||||
static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
|
||||
HAL_HandleEnum::Interrupt>
|
||||
iH;
|
||||
interruptHandles = &iH;
|
||||
static UnlimitedHandleResource<SynchronousWaitDataHandle, SynchronousWaitData,
|
||||
HAL_HandleEnum::Vendor>
|
||||
siH;
|
||||
synchronousInterruptHandles = &siH;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
|
||||
int32_t* status) {
|
||||
HAL_InterruptHandle handle = interruptHandles.Allocate();
|
||||
HAL_InterruptHandle handle = interruptHandles->Allocate();
|
||||
if (handle == HAL_kInvalidHandle) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
auto anInterrupt = interruptHandles.Get(handle);
|
||||
auto anInterrupt = interruptHandles->Get(handle);
|
||||
if (anInterrupt == nullptr) { // would only occur on thread issue.
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
@@ -91,8 +105,8 @@ HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
|
||||
}
|
||||
void HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status) {
|
||||
HAL_DisableInterrupts(interruptHandle, status);
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
interruptHandles.Free(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
interruptHandles->Free(interruptHandle);
|
||||
}
|
||||
|
||||
static void ProcessInterruptDigitalSynchronous(const char* name, void* param,
|
||||
@@ -102,9 +116,9 @@ static void ProcessInterruptDigitalSynchronous(const char* name, void* param,
|
||||
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
|
||||
SynchronousWaitDataHandle handle =
|
||||
static_cast<SynchronousWaitDataHandle>(handleTmp);
|
||||
auto interruptData = synchronousInterruptHandles.Get(handle);
|
||||
auto interruptData = synchronousInterruptHandles->Get(handle);
|
||||
if (interruptData == nullptr) return;
|
||||
auto interrupt = interruptHandles.Get(interruptData->interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptData->interruptHandle);
|
||||
if (interrupt == nullptr) return;
|
||||
// Have a valid interrupt
|
||||
if (value->type != HAL_Type::HAL_BOOLEAN) return;
|
||||
@@ -135,9 +149,9 @@ static void ProcessInterruptAnalogSynchronous(const char* name, void* param,
|
||||
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
|
||||
SynchronousWaitDataHandle handle =
|
||||
static_cast<SynchronousWaitDataHandle>(handleTmp);
|
||||
auto interruptData = synchronousInterruptHandles.Get(handle);
|
||||
auto interruptData = synchronousInterruptHandles->Get(handle);
|
||||
if (interruptData == nullptr) return;
|
||||
auto interrupt = interruptHandles.Get(interruptData->interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptData->interruptHandle);
|
||||
if (interrupt == nullptr) return;
|
||||
// Have a valid interrupt
|
||||
if (value->type != HAL_Type::HAL_DOUBLE) return;
|
||||
@@ -168,13 +182,13 @@ static int64_t WaitForInterruptDigital(HAL_InterruptHandle handle,
|
||||
bool ignorePrevious) {
|
||||
auto data = std::make_shared<SynchronousWaitData>();
|
||||
|
||||
auto dataHandle = synchronousInterruptHandles.Allocate(data);
|
||||
auto dataHandle = synchronousInterruptHandles->Allocate(data);
|
||||
if (dataHandle == HAL_kInvalidHandle) {
|
||||
// Error allocating data
|
||||
return WaitResult::Timeout;
|
||||
}
|
||||
|
||||
// auto data = synchronousInterruptHandles.Get(dataHandle);
|
||||
// auto data = synchronousInterruptHandles->Get(dataHandle);
|
||||
data->waitPredicate = false;
|
||||
data->interruptHandle = handle;
|
||||
|
||||
@@ -216,7 +230,7 @@ static int64_t WaitForInterruptDigital(HAL_InterruptHandle handle,
|
||||
|
||||
// Cancel our callback
|
||||
SimDIOData[digitalIndex].CancelValueCallback(uid);
|
||||
synchronousInterruptHandles.Free(dataHandle);
|
||||
synchronousInterruptHandles->Free(dataHandle);
|
||||
|
||||
// Check for what to return
|
||||
if (timedOut) return WaitResult::Timeout;
|
||||
@@ -236,7 +250,7 @@ static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
|
||||
bool ignorePrevious) {
|
||||
auto data = std::make_shared<SynchronousWaitData>();
|
||||
|
||||
auto dataHandle = synchronousInterruptHandles.Allocate(data);
|
||||
auto dataHandle = synchronousInterruptHandles->Allocate(data);
|
||||
if (dataHandle == HAL_kInvalidHandle) {
|
||||
// Error allocating data
|
||||
return WaitResult::Timeout;
|
||||
@@ -286,7 +300,7 @@ static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
|
||||
|
||||
// Cancel our callback
|
||||
SimAnalogInData[analogIndex].CancelVoltageCallback(uid);
|
||||
synchronousInterruptHandles.Free(dataHandle);
|
||||
synchronousInterruptHandles->Free(dataHandle);
|
||||
|
||||
// Check for what to return
|
||||
if (timedOut) return WaitResult::Timeout;
|
||||
@@ -304,7 +318,7 @@ static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
|
||||
int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
|
||||
double timeout, HAL_Bool ignorePrevious,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return WaitResult::Timeout;
|
||||
@@ -331,7 +345,7 @@ static void ProcessInterruptDigitalAsynchronous(const char* name, void* param,
|
||||
// convert to uintptr_t first, then to handle
|
||||
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
|
||||
HAL_InterruptHandle handle = static_cast<HAL_InterruptHandle>(handleTmp);
|
||||
auto interrupt = interruptHandles.Get(handle);
|
||||
auto interrupt = interruptHandles->Get(handle);
|
||||
if (interrupt == nullptr) return;
|
||||
// Have a valid interrupt
|
||||
if (value->type != HAL_Type::HAL_BOOLEAN) return;
|
||||
@@ -363,7 +377,7 @@ static void ProcessInterruptAnalogAsynchronous(const char* name, void* param,
|
||||
// convert to intptr_t first, then to handle
|
||||
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
|
||||
HAL_InterruptHandle handle = static_cast<HAL_InterruptHandle>(handleTmp);
|
||||
auto interrupt = interruptHandles.Get(handle);
|
||||
auto interrupt = interruptHandles->Get(handle);
|
||||
if (interrupt == nullptr) return;
|
||||
// Have a valid interrupt
|
||||
if (value->type != HAL_Type::HAL_DOUBLE) return;
|
||||
@@ -426,7 +440,7 @@ static void EnableInterruptsAnalog(HAL_InterruptHandle handle,
|
||||
|
||||
void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -452,7 +466,7 @@ void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
}
|
||||
void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -479,7 +493,7 @@ void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
}
|
||||
double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -489,7 +503,7 @@ double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
}
|
||||
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
@@ -501,7 +515,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -525,7 +539,7 @@ void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
|
||||
HAL_InterruptHandlerFunction handler,
|
||||
void* param, int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
@@ -544,7 +558,7 @@ void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interruptHandle,
|
||||
void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
|
||||
HAL_Bool risingEdge, HAL_Bool fallingEdge,
|
||||
int32_t* status) {
|
||||
auto interrupt = interruptHandles.Get(interruptHandle);
|
||||
auto interrupt = interruptHandles->Get(interruptHandle);
|
||||
if (interrupt == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
|
||||
@@ -7,11 +7,20 @@
|
||||
|
||||
#include "../PortsInternal.h"
|
||||
#include "AccelerometerDataInternal.h"
|
||||
#include "NotifyCallbackHelpers.h"
|
||||
#include "MockData/NotifyCallbackHelpers.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
AccelerometerData hal::SimAccelerometerData[1];
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeAccelerometerData() {
|
||||
static AccelerometerData sad[1];
|
||||
::hal::SimAccelerometerData = sad;
|
||||
}
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
AccelerometerData* hal::SimAccelerometerData;
|
||||
void AccelerometerData::ResetData() {
|
||||
m_active = false;
|
||||
m_activeCallbacks = nullptr;
|
||||
|
||||
@@ -69,5 +69,5 @@ class AccelerometerData {
|
||||
std::atomic<double> m_z{0.0};
|
||||
std::shared_ptr<NotifyListenerVector> m_zCallbacks = nullptr;
|
||||
};
|
||||
extern AccelerometerData SimAccelerometerData[];
|
||||
extern AccelerometerData* SimAccelerometerData;
|
||||
} // namespace hal
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user