diff --git a/hal/src/main/native/athena/Accelerometer.cpp b/hal/src/main/native/athena/Accelerometer.cpp index e87ec7f2b5..0a552eec44 100644 --- a/hal/src/main/native/athena/Accelerometer.cpp +++ b/hal/src/main/native/athena/Accelerometer.cpp @@ -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 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); diff --git a/hal/src/main/native/athena/AnalogAccumulator.cpp b/hal/src/main/native/athena/AnalogAccumulator.cpp index e887975a33..01a5b1974c 100644 --- a/hal/src/main/native/athena/AnalogAccumulator.cpp +++ b/hal/src/main/native/athena/AnalogAccumulator.cpp @@ -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; diff --git a/hal/src/main/native/athena/AnalogGyro.cpp b/hal/src/main/native/athena/AnalogGyro.cpp index ff57127918..9b10f0f542 100644 --- a/hal/src/main/native/athena/AnalogGyro.cpp +++ b/hal/src/main/native/athena/AnalogGyro.cpp @@ -34,8 +34,18 @@ static constexpr double kDefaultVoltsPerDegreePerSecond = 0.007; using namespace hal; static IndexedHandleResource - analogGyroHandles; + HAL_HandleEnum::AnalogGyro>* analogGyroHandles; + +namespace hal { +namespace init { +void InitializeAnalogGyro() { + static IndexedHandleResource + 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; diff --git a/hal/src/main/native/athena/AnalogInput.cpp b/hal/src/main/native/athena/AnalogInput.cpp index 3153c8fbef..09ede2862b 100644 --- a/hal/src/main/native/athena/AnalogInput.cpp +++ b/hal/src/main/native/athena/AnalogInput.cpp @@ -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; @@ -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; @@ -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; diff --git a/hal/src/main/native/athena/AnalogInternal.cpp b/hal/src/main/native/athena/AnalogInternal.cpp index 182dd96556..d725dedbfb 100644 --- a/hal/src/main/native/athena/AnalogInternal.cpp +++ b/hal/src/main/native/athena/AnalogInternal.cpp @@ -21,8 +21,8 @@ wpi::mutex analogRegisterWindowMutex; std::unique_ptr analogInputSystem; std::unique_ptr analogOutputSystem; -IndexedHandleResource +IndexedHandleResource* analogInputHandles; static int32_t analogNumChannelsToActivate = 0; @@ -31,6 +31,15 @@ static std::atomic analogSystemInitialized{false}; bool analogSampleRateSet = false; +namespace init { +void InitializeAnalogInternal() { + static IndexedHandleResource + alH; + analogInputHandles = &alH; +} +} // namespace init + /** * Initialize the analog System. */ diff --git a/hal/src/main/native/athena/AnalogInternal.h b/hal/src/main/native/athena/AnalogInternal.h index c9a3a90099..722b1e7f76 100644 --- a/hal/src/main/native/athena/AnalogInternal.h +++ b/hal/src/main/native/athena/AnalogInternal.h @@ -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 analogInputSystem; extern std::unique_ptr analogOutputSystem; @@ -37,7 +37,7 @@ struct AnalogPort { }; extern IndexedHandleResource + kNumAnalogInputs, HAL_HandleEnum::AnalogInput>* analogInputHandles; int32_t getAnalogNumActiveChannels(int32_t* status); diff --git a/hal/src/main/native/athena/AnalogOutput.cpp b/hal/src/main/native/athena/AnalogOutput.cpp index a8e5ba53a3..6f9dd20ba1 100644 --- a/hal/src/main/native/athena/AnalogOutput.cpp +++ b/hal/src/main/native/athena/AnalogOutput.cpp @@ -24,9 +24,20 @@ struct AnalogOutput { } // namespace static IndexedHandleResource + kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>* analogOutputHandles; +namespace hal { +namespace init { +void InitializeAnalogOutput() { + static IndexedHandleResource + 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; diff --git a/hal/src/main/native/athena/AnalogTrigger.cpp b/hal/src/main/native/athena/AnalogTrigger.cpp index 4c77f2d6f0..f65e903370 100644 --- a/hal/src/main/native/athena/AnalogTrigger.cpp +++ b/hal/src/main/native/athena/AnalogTrigger.cpp @@ -27,25 +27,37 @@ struct AnalogTrigger { } // namespace static LimitedHandleResource + kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>* analogTriggerHandles; +namespace hal { +namespace init { +void InitializeAnalogTrigger() { + static LimitedHandleResource + 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; diff --git a/hal/src/main/native/athena/CAN.cpp b/hal/src/main/native/athena/CAN.cpp index 3938c29824..3eb3b08290 100644 --- a/hal/src/main/native/athena/CAN.cpp +++ b/hal/src/main/native/athena/CAN.cpp @@ -9,6 +9,12 @@ #include +namespace hal { +namespace init { +void InitializeCAN() {} +} // namespace init +} // namespace hal + extern "C" { void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data, diff --git a/hal/src/main/native/athena/Compressor.cpp b/hal/src/main/native/athena/Compressor.cpp index 947ea5400f..10e7e9c7e9 100644 --- a/hal/src/main/native/athena/Compressor.cpp +++ b/hal/src/main/native/athena/Compressor.cpp @@ -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) { diff --git a/hal/src/main/native/athena/Constants.cpp b/hal/src/main/native/athena/Constants.cpp index 736369138e..995d8fd601 100644 --- a/hal/src/main/native/athena/Constants.cpp +++ b/hal/src/main/native/athena/Constants.cpp @@ -11,6 +11,12 @@ using namespace hal; +namespace hal { +namespace init { +void InitializeConstants() {} +} // namespace init +} // namespace hal + extern "C" { int32_t HAL_GetSystemClockTicksPerMicrosecond(void) { diff --git a/hal/src/main/native/athena/Counter.cpp b/hal/src/main/native/athena/Counter.cpp index 6565ad29de..c852c7991f 100644 --- a/hal/src/main/native/athena/Counter.cpp +++ b/hal/src/main/native/athena/Counter.cpp @@ -25,19 +25,29 @@ struct Counter { } // namespace static LimitedHandleResource - counterHandles; + HAL_HandleEnum::Counter>* counterHandles; + +namespace hal { +namespace init { +void InitializeCounter() { + static LimitedHandleResource + 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; diff --git a/hal/src/main/native/athena/DIO.cpp b/hal/src/main/native/athena/DIO.cpp index 758d44a1ee..a7deaa1e04 100644 --- a/hal/src/main/native/athena/DIO.cpp +++ b/hal/src/main/native/athena/DIO.cpp @@ -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 + kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>* digitalPWMHandles; +namespace hal { +namespace init { +void InitializeDIO() { + static LimitedHandleResource + 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; @@ -110,9 +125,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; int32_t status = 0; std::lock_guard lock(digitalDIOMutex); @@ -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); } /** @@ -192,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; @@ -227,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; @@ -254,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; @@ -301,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; @@ -329,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; @@ -362,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; @@ -390,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; @@ -429,7 +444,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; @@ -457,7 +472,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; diff --git a/hal/src/main/native/athena/DigitalInternal.cpp b/hal/src/main/native/athena/DigitalInternal.cpp index c1f3561982..3030d5a95f 100644 --- a/hal/src/main/native/athena/DigitalInternal.cpp +++ b/hal/src/main/native/athena/DigitalInternal.cpp @@ -22,31 +22,36 @@ namespace hal { -// Create a mutex to protect changes to the DO PWM config -wpi::mutex digitalPwmMutex; - std::unique_ptr digitalSystem; std::unique_ptr relaySystem; std::unique_ptr pwmSystem; std::unique_ptr spiSystem; -static std::atomic digitalSystemsInitialized{false}; -static wpi::mutex initializeMutex; - DigitalHandleResource + kNumDigitalChannels + kNumPWMHeaders>* digitalChannelHandles; +namespace init { +void InitializeDigitalInternal() { + static DigitalHandleResource + 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 lock(initializeMutex); // Second check in case another thread was waiting - if (digitalSystemsInitialized) return; + if (initialized) return; digitalSystem.reset(tDIO::create(status)); @@ -108,7 +113,7 @@ void initializeDigital(int32_t* status) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); spiSystem->writeAutoSPI1Select(existingSelect, status); - digitalSystemsInitialized = true; + initialized = true; } /** diff --git a/hal/src/main/native/athena/DigitalInternal.h b/hal/src/main/native/athena/DigitalInternal.h index 403b1f1ea2..b7259e23f8 100644 --- a/hal/src/main/native/athena/DigitalInternal.h +++ b/hal/src/main/native/athena/DigitalInternal.h @@ -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 digitalSystem; extern std::unique_ptr relaySystem; extern std::unique_ptr pwmSystem; @@ -79,7 +76,7 @@ struct DigitalPort { }; extern DigitalHandleResource + kNumDigitalChannels + kNumPWMHeaders>* digitalChannelHandles; void initializeDigital(int32_t* status); diff --git a/hal/src/main/native/athena/Encoder.cpp b/hal/src/main/native/athena/Encoder.cpp index 9aaef493fb..ebab0f67c8 100644 --- a/hal/src/main/native/athena/Encoder.cpp +++ b/hal/src/main/native/athena/Encoder.cpp @@ -223,8 +223,19 @@ double Encoder::DecodingScaleFactor() const { static LimitedClassedHandleResource - encoderHandles; + HAL_HandleEnum::Encoder>* encoderHandles; + +namespace hal { +namespace init { +void InitializeEncoder() { + static LimitedClassedHandleResource + 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; diff --git a/hal/src/main/native/athena/FPGAEncoder.cpp b/hal/src/main/native/athena/FPGAEncoder.cpp index c938850c38..f60e74864c 100644 --- a/hal/src/main/native/athena/FPGAEncoder.cpp +++ b/hal/src/main/native/athena/FPGAEncoder.cpp @@ -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 - fpgaEncoderHandles; + HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles; + +namespace hal { +namespace init { +void InitializeFPGAEncoder() { + static LimitedHandleResource + 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; diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp index 2f6c1bd66c..18d07915be 100644 --- a/hal/src/main/native/athena/FRCDriverStation.cpp +++ b/hal/src/main/native/athena/FRCDriverStation.cpp @@ -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 lock(newDSDataAvailableMutex); // Nofify all threads newDSDataAvailableCounter++; - newDSDataAvailableCond.notify_all(); + newDSDataAvailableCond->notify_all(); } /* diff --git a/hal/src/main/native/athena/HAL.cpp b/hal/src/main/native/athena/HAL.cpp index 51f1c8e986..334406d625 100644 --- a/hal/src/main/native/athena/HAL.cpp +++ b/hal/src/main/native/athena/HAL.cpp @@ -27,6 +27,7 @@ #include "HAL/Errors.h" #include "HAL/Notifier.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 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) { @@ -332,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(); diff --git a/hal/src/main/native/athena/HALInitializer.h b/hal/src/main/native/athena/HALInitializer.h new file mode 100644 index 0000000000..2025090ceb --- /dev/null +++ b/hal/src/main/native/athena/HALInitializer.h @@ -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 diff --git a/hal/src/main/native/athena/I2C.cpp b/hal/src/main/native/athena/I2C.cpp index 932ccb8890..3d43caf13c 100644 --- a/hal/src/main/native/athena/I2C.cpp +++ b/hal/src/main/native/athena/I2C.cpp @@ -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" { diff --git a/hal/src/main/native/athena/Interrupts.cpp b/hal/src/main/native/athena/Interrupts.cpp index 3dc3c3287c..73d991ff90 100644 --- a/hal/src/main/native/athena/Interrupts.cpp +++ b/hal/src/main/native/athena/Interrupts.cpp @@ -77,19 +77,29 @@ static void threadedInterruptHandler(uint32_t mask, void* param) { } static LimitedHandleResource - interruptHandles; + HAL_HandleEnum::Interrupt>* interruptHandles; + +namespace hal { +namespace init { +void InitialzeInterrupts() { + static LimitedHandleResource + 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(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; diff --git a/hal/src/main/native/athena/Notifier.cpp b/hal/src/main/native/athena/Notifier.cpp index 7a53e653e6..4fee680895 100644 --- a/hal/src/main/native/athena/Notifier.cpp +++ b/hal/src/main/native/athena/Notifier.cpp @@ -22,12 +22,12 @@ using namespace hal; -static const int32_t kTimerInterruptNumber = 28; +static constexpr int32_t kTimerInterruptNumber = 28; static wpi::mutex notifierMutex; static std::unique_ptr notifierAlarm; static std::unique_ptr notifierManager; -static uint64_t closestTrigger = UINT64_MAX; +static uint64_t closestTrigger{UINT64_MAX}; namespace { @@ -41,7 +41,7 @@ struct Notifier { } // namespace -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; @@ -63,7 +63,7 @@ class NotifierHandleContainer } }; -static NotifierHandleContainer notifierHandles; +static NotifierHandleContainer* notifierHandles; static void alarmCallback(uint32_t, void*) { std::lock_guard lock(notifierMutex); @@ -74,7 +74,7 @@ static void alarmCallback(uint32_t, void*) { closestTrigger = UINT64_MAX; // process all notifiers - notifierHandles.ForEach([&](HAL_NotifierHandle handle, Notifier* notifier) { + notifierHandles->ForEach([&](HAL_NotifierHandle handle, Notifier* notifier) { if (notifier->triggerTime == UINT64_MAX) return; if (currentTime == 0) currentTime = HAL_GetFPGATime(&status); std::unique_lock lock(notifier->mutex); @@ -102,6 +102,15 @@ static void cleanupNotifierAtExit() { notifierManager = nullptr; } +namespace hal { +namespace init { +void InitializeNotifier() { + static NotifierHandleContainer nH; + notifierHandles = &nH; +} +} // namespace init +} // namespace hal + extern "C" { HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) { @@ -121,7 +130,7 @@ HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) { } std::shared_ptr notifier = std::make_shared(); - HAL_NotifierHandle handle = notifierHandles.Allocate(notifier); + HAL_NotifierHandle handle = notifierHandles->Allocate(notifier); if (handle == HAL_kInvalidHandle) { *status = HAL_HANDLE_ERROR; return HAL_kInvalidHandle; @@ -130,7 +139,7 @@ HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) { } void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) { - auto notifier = notifierHandles.Get(notifierHandle); + auto notifier = notifierHandles->Get(notifierHandle); if (!notifier) return; { @@ -143,7 +152,7 @@ void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) { } void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) { - auto notifier = notifierHandles.Free(notifierHandle); + auto notifier = notifierHandles->Free(notifierHandle); if (!notifier) return; // Just in case HAL_StopNotifier() wasn't called... @@ -172,7 +181,7 @@ void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) { void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t triggerTime, int32_t* status) { - auto notifier = notifierHandles.Get(notifierHandle); + auto notifier = notifierHandles->Get(notifierHandle); if (!notifier) return; { @@ -196,7 +205,7 @@ void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle, void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status) { - auto notifier = notifierHandles.Get(notifierHandle); + auto notifier = notifierHandles->Get(notifierHandle); if (!notifier) return; { @@ -207,7 +216,7 @@ void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status) { - auto notifier = notifierHandles.Get(notifierHandle); + auto notifier = notifierHandles->Get(notifierHandle); if (!notifier) return 0; std::unique_lock lock(notifier->mutex); notifier->cond.wait(lock, [&] { diff --git a/hal/src/main/native/athena/OSSerialPort.cpp b/hal/src/main/native/athena/OSSerialPort.cpp index d939818b8a..fa153c9b82 100644 --- a/hal/src/main/native/athena/OSSerialPort.cpp +++ b/hal/src/main/native/athena/OSSerialPort.cpp @@ -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) { diff --git a/hal/src/main/native/athena/PCMInternal.cpp b/hal/src/main/native/athena/PCMInternal.cpp index 42a2756c3f..a39a97fb46 100644 --- a/hal/src/main/native/athena/PCMInternal.cpp +++ b/hal/src/main/native/athena/PCMInternal.cpp @@ -16,6 +16,14 @@ namespace hal { std::unique_ptr 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; diff --git a/hal/src/main/native/athena/PDP.cpp b/hal/src/main/native/athena/PDP.cpp index c720254005..c89c56702f 100644 --- a/hal/src/main/native/athena/PDP.cpp +++ b/hal/src/main/native/athena/PDP.cpp @@ -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) { diff --git a/hal/src/main/native/athena/PWM.cpp b/hal/src/main/native/athena/PWM.cpp index 09f1b86fd7..0337c7b0af 100644 --- a/hal/src/main/native/athena/PWM.cpp +++ b/hal/src/main/native/athena/PWM.cpp @@ -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; diff --git a/hal/src/main/native/athena/Ports.cpp b/hal/src/main/native/athena/Ports.cpp index a9b2abfa73..067a8b2da4 100644 --- a/hal/src/main/native/athena/Ports.cpp +++ b/hal/src/main/native/athena/Ports.cpp @@ -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; } diff --git a/hal/src/main/native/athena/Power.cpp b/hal/src/main/native/athena/Power.cpp index e44cf3acf6..98dd3f8781 100644 --- a/hal/src/main/native/athena/Power.cpp +++ b/hal/src/main/native/athena/Power.cpp @@ -15,7 +15,7 @@ using namespace hal; namespace hal { -static std::unique_ptr power; +static std::unique_ptr 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" { /** diff --git a/hal/src/main/native/athena/Relay.cpp b/hal/src/main/native/athena/Relay.cpp index 0e33f9d623..1e5b325b37 100644 --- a/hal/src/main/native/athena/Relay.cpp +++ b/hal/src/main/native/athena/Relay.cpp @@ -23,12 +23,22 @@ struct Relay { } // namespace static IndexedHandleResource - 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 + 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,7 +97,7 @@ 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; @@ -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; diff --git a/hal/src/main/native/athena/SPI.cpp b/hal/src/main/native/athena/SPI.cpp index f23b1e2018..d5fd2ec3bd 100644 --- a/hal/src/main/native/athena/SPI.cpp +++ b/hal/src/main/native/athena/SPI.cpp @@ -29,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; @@ -47,8 +47,6 @@ std::atomic spiPortCount{0}; static HAL_DigitalHandle digitalHandles[9]{HAL_kInvalidHandle}; -extern "C" { - struct SPIAccumulator { std::atomic notifier{0}; uint64_t triggerTime; @@ -74,6 +72,14 @@ struct SPIAccumulator { }; std::unique_ptr 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) { diff --git a/hal/src/main/native/athena/SerialPort.cpp b/hal/src/main/native/athena/SerialPort.cpp index 994495ed4e..6278dee183 100644 --- a/hal/src/main/native/athena/SerialPort.cpp +++ b/hal/src/main/native/athena/SerialPort.cpp @@ -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) { diff --git a/hal/src/main/native/athena/Solenoid.cpp b/hal/src/main/native/athena/Solenoid.cpp index d9a369e50d..acc1a838ef 100644 --- a/hal/src/main/native/athena/Solenoid.cpp +++ b/hal/src/main/native/athena/Solenoid.cpp @@ -31,8 +31,19 @@ using namespace hal; static IndexedHandleResource - solenoidHandles; + HAL_HandleEnum::Solenoid>* solenoidHandles; + +namespace hal { +namespace init { +void InitializeSolenoid() { + static IndexedHandleResource + 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; @@ -156,7 +167,7 @@ void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) { void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle, int32_t durMS, int32_t* status) { - auto port = solenoidHandles.Get(solenoidPortHandle); + auto port = solenoidHandles->Get(solenoidPortHandle); if (port == nullptr) { *status = HAL_HANDLE_ERROR; return; @@ -167,7 +178,7 @@ void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle, } void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) { - auto port = solenoidHandles.Get(solenoidPortHandle); + auto port = solenoidHandles->Get(solenoidPortHandle); if (port == nullptr) { *status = HAL_HANDLE_ERROR; return; diff --git a/hal/src/main/native/athena/Threads.cpp b/hal/src/main/native/athena/Threads.cpp index 6d972e9a98..0ca7e86bb0 100644 --- a/hal/src/main/native/athena/Threads.cpp +++ b/hal/src/main/native/athena/Threads.cpp @@ -12,6 +12,12 @@ #include "HAL/Errors.h" +namespace hal { +namespace init { +void InitializeThreads() {} +} // namespace init +} // namespace hal + extern "C" { /** diff --git a/hal/src/main/native/shared/handles/HandlesInternal.cpp b/hal/src/main/native/shared/handles/HandlesInternal.cpp index dd2b60c0c8..ddabb8d4b7 100644 --- a/hal/src/main/native/shared/handles/HandlesInternal.cpp +++ b/hal/src/main/native/shared/handles/HandlesInternal.cpp @@ -12,48 +12,41 @@ #include #include +#ifdef __FRC_ROBORIO__ namespace hal { -static llvm::SmallVector& GetGlobalHandles() { - static llvm::SmallVector globalHandles; - return globalHandles; +static llvm::SmallVector* globalHandles; +static wpi::mutex globalHandleMutex; +namespace init { +void InitializeHandlesInternal() { + static llvm::SmallVector gH; + globalHandles = &gH; } - -static wpi::mutex& GetGlobalHandleMutex() { - static wpi::mutex globalHandleMutex; - return globalHandleMutex; -} - +} // namespace init HandleBase::HandleBase() { - std::lock_guard lock(GetGlobalHandleMutex()); - auto& globalHandles = GetGlobalHandles(); - auto index = std::find(globalHandles.begin(), globalHandles.end(), this); - if (index == globalHandles.end()) { - globalHandles.push_back(this); + std::lock_guard 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 lock(GetGlobalHandleMutex()); - auto& globalHandles = GetGlobalHandles(); - auto index = std::find(globalHandles.begin(), globalHandles.end(), this); - if (index != globalHandles.end()) { + std::lock_guard 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 lock(GetGlobalHandleMutex()); - auto& globalHandles = GetGlobalHandles(); - for (auto&& i : globalHandles) { + std::unique_lock lock(globalHandleMutex); + for (auto&& i : *globalHandles) { if (i != nullptr) { lock.unlock(); i->ResetHandles(); @@ -61,7 +54,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_HandleEnum::Port); @@ -74,7 +66,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_HandleEnum::Port); @@ -89,7 +80,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; @@ -105,3 +95,90 @@ HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, return handle; } } // namespace hal +#else +namespace hal { +static llvm::SmallVector& GetGlobalHandles() { + static llvm::SmallVector globalHandles; + return globalHandles; +} +static wpi::mutex& GetGlobalHandleMutex() { + static wpi::mutex globalHandleMutex; + return globalHandleMutex; +} +HandleBase::HandleBase() { + std::lock_guard lock(GetGlobalHandleMutex()); + auto& globalHandles = GetGlobalHandles(); + 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 lock(GetGlobalHandleMutex()); + auto& globalHandles = GetGlobalHandles(); + 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 lock(GetGlobalHandleMutex()); + auto& globalHandles = GetGlobalHandles(); + for (auto&& i : globalHandles) { + if (i != nullptr) { + lock.unlock(); + i->ResetHandles(); + lock.lock(); + } + } +} +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_HandleEnum::Port); + handle = handle << 24; + // shift module and add to 3rd set of 8 bits + int32_t temp = module; + temp = (temp << 8) & 0xff00; + handle += temp; + // add channel to last 8 bits + 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_HandleEnum::Port); + handle = handle << 16; + // set second set up bits to 1 + int32_t temp = 1; + temp = (temp << 8) & 0xff00; + handle += temp; + // shift to last set of bits + handle = handle << 8; + // add channel to last 8 bits + handle += channel; + return handle; +} +HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, + int16_t version) { + if (index < 0) return HAL_kInvalidHandle; + uint8_t hType = static_cast(handleType); + if (hType == 0 || hType > 127) return HAL_kInvalidHandle; + // set last 8 bits, then shift to first 8 bits + HAL_Handle handle = hType; + handle = handle << 8; + handle += static_cast(version); + handle = handle << 16; + // add index to set last 16 bits + handle += index; + return handle; +} +} // namespace hal +#endif diff --git a/hal/src/main/native/sim/HALInitializer.h b/hal/src/main/native/sim/HALInitializer.h new file mode 100644 index 0000000000..5f43b359fb --- /dev/null +++ b/hal/src/main/native/sim/HALInitializer.h @@ -0,0 +1,15 @@ +/*----------------------------------------------------------------------------*/ +/* 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 InitializeHAL(); +extern void InitializeHandlesInternal(); +} // namespace init +} // namespace hal