2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2016-01-02 03:02:34 -08:00
|
|
|
|
2018-07-20 00:03:45 -07:00
|
|
|
#include "hal/HAL.h"
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2020-09-04 08:59:26 -07:00
|
|
|
#include <vector>
|
|
|
|
|
|
2018-09-03 16:08:07 -07:00
|
|
|
#include <wpi/mutex.h>
|
2018-04-29 23:33:19 -07:00
|
|
|
#include <wpi/raw_ostream.h>
|
2020-09-04 08:59:26 -07:00
|
|
|
#include <wpi/spinlock.h>
|
2017-10-27 02:46:56 -05:00
|
|
|
|
2020-06-28 20:45:40 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
|
#include <Windows.h>
|
|
|
|
|
#pragma comment(lib, "Winmm.lib")
|
|
|
|
|
#endif // _WIN32
|
|
|
|
|
|
2017-08-18 21:35:53 -07:00
|
|
|
#include "ErrorsInternal.h"
|
2017-12-10 19:38:53 -08:00
|
|
|
#include "HALInitializer.h"
|
2017-08-18 21:35:53 -07:00
|
|
|
#include "MockHooksInternal.h"
|
2018-07-20 00:03:45 -07:00
|
|
|
#include "hal/DriverStation.h"
|
|
|
|
|
#include "hal/Errors.h"
|
|
|
|
|
#include "hal/Extensions.h"
|
|
|
|
|
#include "hal/handles/HandlesInternal.h"
|
2020-06-27 22:11:24 -07:00
|
|
|
#include "hal/simulation/DriverStationData.h"
|
2020-11-30 23:55:36 -08:00
|
|
|
#include "hal/simulation/SimCallbackRegistry.h"
|
2018-07-20 00:03:45 -07:00
|
|
|
#include "mockdata/RoboRioDataInternal.h"
|
2015-12-30 19:06:47 -08:00
|
|
|
|
2016-06-05 15:23:58 -07:00
|
|
|
using namespace hal;
|
|
|
|
|
|
2020-11-30 23:55:36 -08:00
|
|
|
namespace {
|
|
|
|
|
class SimPeriodicCallbackRegistry : public impl::SimCallbackRegistryBase {
|
|
|
|
|
public:
|
|
|
|
|
int32_t Register(HALSIM_SimPeriodicCallback callback, void* param) {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
return DoRegister(reinterpret_cast<RawFunctor>(callback), param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()() const {
|
|
|
|
|
#ifdef _MSC_VER // work around VS2019 16.4.0 bug
|
|
|
|
|
std::scoped_lock<wpi::recursive_spinlock> lock(m_mutex);
|
|
|
|
|
#else
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
#endif
|
|
|
|
|
if (m_callbacks) {
|
2020-12-28 12:58:06 -08:00
|
|
|
for (auto&& cb : *m_callbacks) {
|
2020-11-30 23:55:36 -08:00
|
|
|
reinterpret_cast<HALSIM_SimPeriodicCallback>(cb.callback)(cb.param);
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2020-11-30 23:55:36 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2020-06-26 20:46:13 -07:00
|
|
|
static HAL_RuntimeType runtimeType{HAL_Mock};
|
2020-09-04 08:59:26 -07:00
|
|
|
static wpi::spinlock gOnShutdownMutex;
|
|
|
|
|
static std::vector<std::pair<void*, void (*)(void*)>> gOnShutdown;
|
2020-11-30 23:55:36 -08:00
|
|
|
static SimPeriodicCallbackRegistry gSimPeriodicBefore;
|
|
|
|
|
static SimPeriodicCallbackRegistry gSimPeriodicAfter;
|
2020-06-26 20:46:13 -07:00
|
|
|
|
2020-12-28 01:19:59 -08:00
|
|
|
namespace hal::init {
|
2017-12-10 19:38:53 -08:00
|
|
|
void InitializeHAL() {
|
|
|
|
|
InitializeAccelerometerData();
|
2019-11-17 15:05:56 -08:00
|
|
|
InitializeAddressableLEDData();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeAnalogGyroData();
|
|
|
|
|
InitializeAnalogInData();
|
|
|
|
|
InitializeAnalogOutData();
|
|
|
|
|
InitializeAnalogTriggerData();
|
|
|
|
|
InitializeCanData();
|
2018-05-21 16:09:38 -07:00
|
|
|
InitializeCANAPI();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeDigitalPWMData();
|
2019-11-01 23:41:30 -07:00
|
|
|
InitializeDutyCycleData();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeDIOData();
|
|
|
|
|
InitializeDriverStationData();
|
|
|
|
|
InitializeEncoderData();
|
|
|
|
|
InitializeI2CData();
|
|
|
|
|
InitializePCMData();
|
|
|
|
|
InitializePDPData();
|
|
|
|
|
InitializePWMData();
|
|
|
|
|
InitializeRelayData();
|
|
|
|
|
InitializeRoboRioData();
|
2019-09-28 11:34:46 -07:00
|
|
|
InitializeSimDeviceData();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeSPIAccelerometerData();
|
|
|
|
|
InitializeSPIData();
|
|
|
|
|
InitializeAccelerometer();
|
2019-11-17 15:05:56 -08:00
|
|
|
InitializeAddressableLED();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeAnalogAccumulator();
|
|
|
|
|
InitializeAnalogGyro();
|
|
|
|
|
InitializeAnalogInput();
|
|
|
|
|
InitializeAnalogInternal();
|
|
|
|
|
InitializeAnalogOutput();
|
2020-08-19 21:58:07 -07:00
|
|
|
InitializeAnalogTrigger();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeCAN();
|
|
|
|
|
InitializeCompressor();
|
|
|
|
|
InitializeConstants();
|
|
|
|
|
InitializeCounter();
|
|
|
|
|
InitializeDigitalInternal();
|
|
|
|
|
InitializeDIO();
|
2019-11-01 23:41:30 -07:00
|
|
|
InitializeDutyCycle();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeDriverStation();
|
2017-12-31 15:37:14 -05:00
|
|
|
InitializeEncoder();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeExtensions();
|
|
|
|
|
InitializeI2C();
|
|
|
|
|
InitializeInterrupts();
|
2019-09-28 15:43:24 -07:00
|
|
|
InitializeMain();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeMockHooks();
|
|
|
|
|
InitializeNotifier();
|
|
|
|
|
InitializePDP();
|
|
|
|
|
InitializePorts();
|
|
|
|
|
InitializePower();
|
|
|
|
|
InitializePWM();
|
|
|
|
|
InitializeRelay();
|
|
|
|
|
InitializeSerialPort();
|
2019-09-28 11:34:46 -07:00
|
|
|
InitializeSimDevice();
|
2017-12-10 19:38:53 -08:00
|
|
|
InitializeSolenoid();
|
|
|
|
|
InitializeSPI();
|
|
|
|
|
InitializeThreads();
|
|
|
|
|
}
|
2020-12-28 01:19:59 -08:00
|
|
|
} // namespace hal::init
|
2017-12-10 19:38:53 -08:00
|
|
|
|
2015-11-26 00:08:32 -08:00
|
|
|
extern "C" {
|
|
|
|
|
|
2016-08-12 13:45:28 -07:00
|
|
|
HAL_PortHandle HAL_GetPort(int32_t channel) {
|
2016-07-12 10:45:14 -07:00
|
|
|
// Dont allow a number that wouldn't fit in a uint8_t
|
2020-12-28 12:58:06 -08:00
|
|
|
if (channel < 0 || channel >= 255) {
|
|
|
|
|
return HAL_kInvalidHandle;
|
|
|
|
|
}
|
2016-08-12 13:45:28 -07:00
|
|
|
return createPortHandle(channel, 1);
|
2016-07-12 10:45:14 -07:00
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2016-08-12 13:45:28 -07:00
|
|
|
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
|
2016-07-12 10:45:14 -07:00
|
|
|
// Dont allow a number that wouldn't fit in a uint8_t
|
2020-12-28 12:58:06 -08:00
|
|
|
if (channel < 0 || channel >= 255) {
|
|
|
|
|
return HAL_kInvalidHandle;
|
|
|
|
|
}
|
|
|
|
|
if (module < 0 || module >= 255) {
|
|
|
|
|
return HAL_kInvalidHandle;
|
|
|
|
|
}
|
2016-08-12 13:45:28 -07:00
|
|
|
return createPortHandle(channel, module);
|
2014-05-02 17:54:01 -04:00
|
|
|
}
|
|
|
|
|
|
2016-07-09 00:24:26 -07:00
|
|
|
const char* HAL_GetErrorMessage(int32_t code) {
|
2016-05-20 17:30:37 -07:00
|
|
|
switch (code) {
|
|
|
|
|
case 0:
|
|
|
|
|
return "";
|
|
|
|
|
case CTR_RxTimeout:
|
|
|
|
|
return CTR_RxTimeout_MESSAGE;
|
|
|
|
|
case CTR_TxTimeout:
|
|
|
|
|
return CTR_TxTimeout_MESSAGE;
|
|
|
|
|
case CTR_InvalidParamValue:
|
|
|
|
|
return CTR_InvalidParamValue_MESSAGE;
|
|
|
|
|
case CTR_UnexpectedArbId:
|
|
|
|
|
return CTR_UnexpectedArbId_MESSAGE;
|
|
|
|
|
case CTR_TxFailed:
|
|
|
|
|
return CTR_TxFailed_MESSAGE;
|
|
|
|
|
case CTR_SigNotUpdated:
|
|
|
|
|
return CTR_SigNotUpdated_MESSAGE;
|
|
|
|
|
case NiFpga_Status_FifoTimeout:
|
|
|
|
|
return NiFpga_Status_FifoTimeout_MESSAGE;
|
|
|
|
|
case NiFpga_Status_TransferAborted:
|
|
|
|
|
return NiFpga_Status_TransferAborted_MESSAGE;
|
|
|
|
|
case NiFpga_Status_MemoryFull:
|
|
|
|
|
return NiFpga_Status_MemoryFull_MESSAGE;
|
|
|
|
|
case NiFpga_Status_SoftwareFault:
|
|
|
|
|
return NiFpga_Status_SoftwareFault_MESSAGE;
|
|
|
|
|
case NiFpga_Status_InvalidParameter:
|
|
|
|
|
return NiFpga_Status_InvalidParameter_MESSAGE;
|
|
|
|
|
case NiFpga_Status_ResourceNotFound:
|
|
|
|
|
return NiFpga_Status_ResourceNotFound_MESSAGE;
|
|
|
|
|
case NiFpga_Status_ResourceNotInitialized:
|
|
|
|
|
return NiFpga_Status_ResourceNotInitialized_MESSAGE;
|
|
|
|
|
case NiFpga_Status_HardwareFault:
|
|
|
|
|
return NiFpga_Status_HardwareFault_MESSAGE;
|
|
|
|
|
case NiFpga_Status_IrqTimeout:
|
|
|
|
|
return NiFpga_Status_IrqTimeout_MESSAGE;
|
|
|
|
|
case SAMPLE_RATE_TOO_HIGH:
|
|
|
|
|
return SAMPLE_RATE_TOO_HIGH_MESSAGE;
|
|
|
|
|
case VOLTAGE_OUT_OF_RANGE:
|
|
|
|
|
return VOLTAGE_OUT_OF_RANGE_MESSAGE;
|
|
|
|
|
case LOOP_TIMING_ERROR:
|
|
|
|
|
return LOOP_TIMING_ERROR_MESSAGE;
|
|
|
|
|
case SPI_WRITE_NO_MOSI:
|
|
|
|
|
return SPI_WRITE_NO_MOSI_MESSAGE;
|
|
|
|
|
case SPI_READ_NO_MISO:
|
|
|
|
|
return SPI_READ_NO_MISO_MESSAGE;
|
|
|
|
|
case SPI_READ_NO_DATA:
|
|
|
|
|
return SPI_READ_NO_DATA_MESSAGE;
|
|
|
|
|
case INCOMPATIBLE_STATE:
|
|
|
|
|
return INCOMPATIBLE_STATE_MESSAGE;
|
|
|
|
|
case NO_AVAILABLE_RESOURCES:
|
|
|
|
|
return NO_AVAILABLE_RESOURCES_MESSAGE;
|
|
|
|
|
case RESOURCE_IS_ALLOCATED:
|
|
|
|
|
return RESOURCE_IS_ALLOCATED_MESSAGE;
|
2016-07-13 20:29:28 -07:00
|
|
|
case RESOURCE_OUT_OF_RANGE:
|
|
|
|
|
return RESOURCE_OUT_OF_RANGE_MESSAGE;
|
|
|
|
|
case HAL_INVALID_ACCUMULATOR_CHANNEL:
|
|
|
|
|
return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE;
|
2016-07-03 17:27:06 -07:00
|
|
|
case HAL_HANDLE_ERROR:
|
|
|
|
|
return HAL_HANDLE_ERROR_MESSAGE;
|
2016-05-20 17:30:37 -07:00
|
|
|
case NULL_PARAMETER:
|
|
|
|
|
return NULL_PARAMETER_MESSAGE;
|
|
|
|
|
case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
|
|
|
|
|
return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
|
|
|
|
|
case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
|
|
|
|
|
return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
|
|
|
|
|
case PARAMETER_OUT_OF_RANGE:
|
|
|
|
|
return PARAMETER_OUT_OF_RANGE_MESSAGE;
|
2016-07-03 15:22:22 -07:00
|
|
|
case HAL_COUNTER_NOT_SUPPORTED:
|
|
|
|
|
return HAL_COUNTER_NOT_SUPPORTED_MESSAGE;
|
2017-09-07 21:40:30 -07:00
|
|
|
case HAL_ERR_CANSessionMux_InvalidBuffer:
|
2016-05-20 17:30:37 -07:00
|
|
|
return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
|
2017-09-07 21:40:30 -07:00
|
|
|
case HAL_ERR_CANSessionMux_MessageNotFound:
|
2016-05-20 17:30:37 -07:00
|
|
|
return ERR_CANSessionMux_MessageNotFound_MESSAGE;
|
2017-09-07 21:40:30 -07:00
|
|
|
case HAL_WARN_CANSessionMux_NoToken:
|
2016-05-20 17:30:37 -07:00
|
|
|
return WARN_CANSessionMux_NoToken_MESSAGE;
|
2017-09-07 21:40:30 -07:00
|
|
|
case HAL_ERR_CANSessionMux_NotAllowed:
|
2016-05-20 17:30:37 -07:00
|
|
|
return ERR_CANSessionMux_NotAllowed_MESSAGE;
|
2017-09-07 21:40:30 -07:00
|
|
|
case HAL_ERR_CANSessionMux_NotInitialized:
|
2016-05-20 17:30:37 -07:00
|
|
|
return ERR_CANSessionMux_NotInitialized_MESSAGE;
|
|
|
|
|
case VI_ERROR_SYSTEM_ERROR:
|
|
|
|
|
return VI_ERROR_SYSTEM_ERROR_MESSAGE;
|
|
|
|
|
case VI_ERROR_INV_OBJECT:
|
|
|
|
|
return VI_ERROR_INV_OBJECT_MESSAGE;
|
|
|
|
|
case VI_ERROR_RSRC_LOCKED:
|
|
|
|
|
return VI_ERROR_RSRC_LOCKED_MESSAGE;
|
|
|
|
|
case VI_ERROR_RSRC_NFOUND:
|
|
|
|
|
return VI_ERROR_RSRC_NFOUND_MESSAGE;
|
|
|
|
|
case VI_ERROR_INV_RSRC_NAME:
|
|
|
|
|
return VI_ERROR_INV_RSRC_NAME_MESSAGE;
|
|
|
|
|
case VI_ERROR_QUEUE_OVERFLOW:
|
|
|
|
|
return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
|
|
|
|
|
case VI_ERROR_IO:
|
|
|
|
|
return VI_ERROR_IO_MESSAGE;
|
|
|
|
|
case VI_ERROR_ASRL_PARITY:
|
|
|
|
|
return VI_ERROR_ASRL_PARITY_MESSAGE;
|
|
|
|
|
case VI_ERROR_ASRL_FRAMING:
|
|
|
|
|
return VI_ERROR_ASRL_FRAMING_MESSAGE;
|
|
|
|
|
case VI_ERROR_ASRL_OVERRUN:
|
|
|
|
|
return VI_ERROR_ASRL_OVERRUN_MESSAGE;
|
|
|
|
|
case VI_ERROR_RSRC_BUSY:
|
|
|
|
|
return VI_ERROR_RSRC_BUSY_MESSAGE;
|
|
|
|
|
case VI_ERROR_INV_PARAMETER:
|
|
|
|
|
return VI_ERROR_INV_PARAMETER_MESSAGE;
|
2016-07-08 21:29:29 -07:00
|
|
|
case HAL_PWM_SCALE_ERROR:
|
|
|
|
|
return HAL_PWM_SCALE_ERROR_MESSAGE;
|
2018-05-21 16:09:38 -07:00
|
|
|
case HAL_CAN_TIMEOUT:
|
|
|
|
|
return HAL_CAN_TIMEOUT_MESSAGE;
|
2019-11-01 23:41:30 -07:00
|
|
|
case HAL_SIM_NOT_SUPPORTED:
|
|
|
|
|
return HAL_SIM_NOT_SUPPORTED_MESSAGE;
|
2019-11-08 22:51:11 -08:00
|
|
|
case HAL_CAN_BUFFER_OVERRUN:
|
|
|
|
|
return HAL_CAN_BUFFER_OVERRUN_MESSAGE;
|
2019-11-18 15:25:04 -08:00
|
|
|
case HAL_LED_CHANNEL_ERROR:
|
|
|
|
|
return HAL_LED_CHANNEL_ERROR_MESSAGE;
|
2016-05-20 17:30:37 -07:00
|
|
|
default:
|
|
|
|
|
return "Unknown error status";
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
HAL_RuntimeType HAL_GetRuntimeType(void) {
|
|
|
|
|
return runtimeType;
|
|
|
|
|
}
|
2020-06-26 20:46:13 -07:00
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
void HALSIM_SetRuntimeType(HAL_RuntimeType type) {
|
|
|
|
|
runtimeType = type;
|
|
|
|
|
}
|
2016-09-13 21:21:57 -07:00
|
|
|
|
2016-07-12 10:45:14 -07:00
|
|
|
int32_t HAL_GetFPGAVersion(int32_t* status) {
|
2017-08-18 21:35:53 -07:00
|
|
|
return 2018; // Automatically script this at some point
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
2016-07-12 10:45:14 -07:00
|
|
|
int64_t HAL_GetFPGARevision(int32_t* status) {
|
2017-08-18 21:35:53 -07:00
|
|
|
return 0; // TODO: Find a better number to return;
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
uint64_t HAL_GetFPGATime(int32_t* status) {
|
|
|
|
|
return hal::GetFPGATime();
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2019-11-14 22:52:34 -08:00
|
|
|
uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status) {
|
|
|
|
|
// Capture the current FPGA time. This will give us the upper half of the
|
|
|
|
|
// clock.
|
|
|
|
|
uint64_t fpga_time = HAL_GetFPGATime(status);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (*status != 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-11-14 22:52:34 -08:00
|
|
|
|
|
|
|
|
// Now, we need to detect the case where the lower bits rolled over after we
|
|
|
|
|
// sampled. In that case, the upper bits will be 1 bigger than they should
|
|
|
|
|
// be.
|
|
|
|
|
|
|
|
|
|
// Break it into lower and upper portions.
|
|
|
|
|
uint32_t lower = fpga_time & 0xffffffffull;
|
|
|
|
|
uint64_t upper = (fpga_time >> 32) & 0xffffffff;
|
|
|
|
|
|
|
|
|
|
// The time was sampled *before* the current time, so roll it back.
|
|
|
|
|
if (lower < unexpanded_lower) {
|
|
|
|
|
--upper;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (upper << 32) + static_cast<uint64_t>(unexpanded_lower);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-12 10:45:14 -07:00
|
|
|
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
|
2018-09-03 16:08:07 -07:00
|
|
|
return SimRoboRioData[0].fpgaButton;
|
2014-07-29 14:34:52 -04:00
|
|
|
}
|
|
|
|
|
|
2016-07-12 10:45:14 -07:00
|
|
|
HAL_Bool HAL_GetSystemActive(int32_t* status) {
|
2020-05-01 09:05:54 -07:00
|
|
|
return HALSIM_GetDriverStationEnabled();
|
2014-11-18 10:56:25 -05:00
|
|
|
}
|
2015-08-19 11:12:54 -04:00
|
|
|
|
2016-07-12 10:45:14 -07:00
|
|
|
HAL_Bool HAL_GetBrownedOut(int32_t* status) {
|
2017-08-18 21:35:53 -07:00
|
|
|
return false; // Figure out if we need to detect a brownout condition
|
2016-12-02 00:32:01 -08:00
|
|
|
}
|
|
|
|
|
|
2017-07-01 00:43:06 -07:00
|
|
|
HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
|
2017-10-16 20:00:32 -07:00
|
|
|
static std::atomic_bool initialized{false};
|
2017-11-13 09:51:48 -08:00
|
|
|
static wpi::mutex initializeMutex;
|
2017-10-16 20:00:32 -07:00
|
|
|
// Initial check, as if it's true initialization has finished
|
2020-12-28 12:58:06 -08:00
|
|
|
if (initialized) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2017-10-16 20:00:32 -07:00
|
|
|
|
2019-07-08 22:58:39 -07:00
|
|
|
std::scoped_lock lock(initializeMutex);
|
2017-10-16 20:00:32 -07:00
|
|
|
// Second check in case another thread was waiting
|
2020-12-28 12:58:06 -08:00
|
|
|
if (initialized) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2017-10-16 20:00:32 -07:00
|
|
|
|
2017-12-10 19:38:53 -08:00
|
|
|
hal::init::InitializeHAL();
|
|
|
|
|
|
2018-05-13 22:02:47 -07:00
|
|
|
hal::init::HAL_IsInitialized.store(true);
|
|
|
|
|
|
2017-08-18 21:35:53 -07:00
|
|
|
hal::RestartTiming();
|
2016-07-17 19:42:33 -07:00
|
|
|
HAL_InitializeDriverStation();
|
2017-10-16 20:00:32 -07:00
|
|
|
|
|
|
|
|
initialized = true;
|
2020-06-28 20:45:40 -04:00
|
|
|
|
|
|
|
|
// Set Timer Precision to 1ms on Windows
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
TIMECAPS tc;
|
|
|
|
|
if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) {
|
|
|
|
|
UINT target = min(1, tc.wPeriodMin);
|
|
|
|
|
timeBeginPeriod(target);
|
|
|
|
|
std::atexit([]() {
|
|
|
|
|
TIMECAPS tc;
|
|
|
|
|
if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) {
|
|
|
|
|
UINT target = min(1, tc.wPeriodMin);
|
|
|
|
|
timeEndPeriod(target);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
#endif // _WIN32
|
|
|
|
|
|
2020-07-05 22:12:12 -07:00
|
|
|
wpi::outs().SetUnbuffered();
|
2020-12-28 12:58:06 -08:00
|
|
|
if (HAL_LoadExtensions() < 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-07-05 22:12:12 -07:00
|
|
|
|
2017-08-18 21:35:53 -07:00
|
|
|
return true; // Add initialization if we need to at a later point
|
2014-01-06 10:12:21 -05:00
|
|
|
}
|
|
|
|
|
|
2020-09-04 08:59:26 -07:00
|
|
|
void HAL_Shutdown(void) {
|
|
|
|
|
std::vector<std::pair<void*, void (*)(void*)>> funcs;
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(gOnShutdownMutex);
|
|
|
|
|
funcs.swap(gOnShutdown);
|
|
|
|
|
}
|
|
|
|
|
for (auto&& func : funcs) {
|
|
|
|
|
func.second(func.first);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HAL_OnShutdown(void* param, void (*func)(void*)) {
|
|
|
|
|
std::scoped_lock lock(gOnShutdownMutex);
|
|
|
|
|
gOnShutdown.emplace_back(param, func);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
void HAL_SimPeriodicBefore(void) {
|
|
|
|
|
gSimPeriodicBefore();
|
|
|
|
|
}
|
2020-11-30 23:55:36 -08:00
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
void HAL_SimPeriodicAfter(void) {
|
|
|
|
|
gSimPeriodicAfter();
|
|
|
|
|
}
|
2020-11-30 23:55:36 -08:00
|
|
|
|
|
|
|
|
int32_t HALSIM_RegisterSimPeriodicBeforeCallback(
|
|
|
|
|
HALSIM_SimPeriodicCallback callback, void* param) {
|
|
|
|
|
return gSimPeriodicBefore.Register(callback, param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HALSIM_CancelSimPeriodicBeforeCallback(int32_t uid) {
|
|
|
|
|
gSimPeriodicBefore.Cancel(uid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t HALSIM_RegisterSimPeriodicAfterCallback(
|
|
|
|
|
HALSIM_SimPeriodicCallback callback, void* param) {
|
|
|
|
|
return gSimPeriodicAfter.Register(callback, param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HALSIM_CancelSimPeriodicAfterCallback(int32_t uid) {
|
|
|
|
|
gSimPeriodicAfter.Cancel(uid);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-12 10:45:14 -07:00
|
|
|
int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
|
|
|
|
|
const char* feature) {
|
2017-08-18 21:35:53 -07:00
|
|
|
return 0; // Do nothing for now
|
2014-05-02 17:54:01 -04:00
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2015-11-26 00:08:32 -08:00
|
|
|
} // extern "C"
|