blob: cf019cfcc42fecd68188390608208bb6f1d9b6cf [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -08002/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
Brian Silverman41cdd3e2019-01-19 19:48:58 -08003/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "hal/HAL.h"
9
10#include <wpi/mutex.h>
11#include <wpi/raw_ostream.h>
12
13#include "ErrorsInternal.h"
14#include "HALInitializer.h"
15#include "MockHooksInternal.h"
16#include "hal/DriverStation.h"
17#include "hal/Errors.h"
18#include "hal/Extensions.h"
19#include "hal/handles/HandlesInternal.h"
20#include "mockdata/RoboRioDataInternal.h"
21
22using namespace hal;
23
24namespace hal {
25namespace init {
26void InitializeHAL() {
27 InitializeAccelerometerData();
28 InitializeAnalogGyroData();
29 InitializeAnalogInData();
30 InitializeAnalogOutData();
31 InitializeAnalogTriggerData();
32 InitializeCanData();
33 InitializeCANAPI();
34 InitializeDigitalPWMData();
35 InitializeDIOData();
36 InitializeDriverStationData();
37 InitializeEncoderData();
38 InitializeI2CData();
39 InitializePCMData();
40 InitializePDPData();
41 InitializePWMData();
42 InitializeRelayData();
43 InitializeRoboRioData();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080044 InitializeSimDeviceData();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080045 InitializeSPIAccelerometerData();
46 InitializeSPIData();
47 InitializeAccelerometer();
48 InitializeAnalogAccumulator();
49 InitializeAnalogGyro();
50 InitializeAnalogInput();
51 InitializeAnalogInternal();
52 InitializeAnalogOutput();
53 InitializeCAN();
54 InitializeCompressor();
55 InitializeConstants();
56 InitializeCounter();
57 InitializeDigitalInternal();
58 InitializeDIO();
59 InitializeDriverStation();
60 InitializeEncoder();
61 InitializeExtensions();
62 InitializeI2C();
63 InitializeInterrupts();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080064 InitializeMain();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080065 InitializeMockHooks();
66 InitializeNotifier();
67 InitializePDP();
68 InitializePorts();
69 InitializePower();
70 InitializePWM();
71 InitializeRelay();
72 InitializeSerialPort();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080073 InitializeSimDevice();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080074 InitializeSolenoid();
75 InitializeSPI();
76 InitializeThreads();
77}
78} // namespace init
79} // namespace hal
80
81extern "C" {
82
83HAL_PortHandle HAL_GetPort(int32_t channel) {
84 // Dont allow a number that wouldn't fit in a uint8_t
85 if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
86 return createPortHandle(channel, 1);
87}
88
89HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
90 // Dont allow a number that wouldn't fit in a uint8_t
91 if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
92 if (module < 0 || module >= 255) return HAL_kInvalidHandle;
93 return createPortHandle(channel, module);
94}
95
96const char* HAL_GetErrorMessage(int32_t code) {
97 switch (code) {
98 case 0:
99 return "";
100 case CTR_RxTimeout:
101 return CTR_RxTimeout_MESSAGE;
102 case CTR_TxTimeout:
103 return CTR_TxTimeout_MESSAGE;
104 case CTR_InvalidParamValue:
105 return CTR_InvalidParamValue_MESSAGE;
106 case CTR_UnexpectedArbId:
107 return CTR_UnexpectedArbId_MESSAGE;
108 case CTR_TxFailed:
109 return CTR_TxFailed_MESSAGE;
110 case CTR_SigNotUpdated:
111 return CTR_SigNotUpdated_MESSAGE;
112 case NiFpga_Status_FifoTimeout:
113 return NiFpga_Status_FifoTimeout_MESSAGE;
114 case NiFpga_Status_TransferAborted:
115 return NiFpga_Status_TransferAborted_MESSAGE;
116 case NiFpga_Status_MemoryFull:
117 return NiFpga_Status_MemoryFull_MESSAGE;
118 case NiFpga_Status_SoftwareFault:
119 return NiFpga_Status_SoftwareFault_MESSAGE;
120 case NiFpga_Status_InvalidParameter:
121 return NiFpga_Status_InvalidParameter_MESSAGE;
122 case NiFpga_Status_ResourceNotFound:
123 return NiFpga_Status_ResourceNotFound_MESSAGE;
124 case NiFpga_Status_ResourceNotInitialized:
125 return NiFpga_Status_ResourceNotInitialized_MESSAGE;
126 case NiFpga_Status_HardwareFault:
127 return NiFpga_Status_HardwareFault_MESSAGE;
128 case NiFpga_Status_IrqTimeout:
129 return NiFpga_Status_IrqTimeout_MESSAGE;
130 case SAMPLE_RATE_TOO_HIGH:
131 return SAMPLE_RATE_TOO_HIGH_MESSAGE;
132 case VOLTAGE_OUT_OF_RANGE:
133 return VOLTAGE_OUT_OF_RANGE_MESSAGE;
134 case LOOP_TIMING_ERROR:
135 return LOOP_TIMING_ERROR_MESSAGE;
136 case SPI_WRITE_NO_MOSI:
137 return SPI_WRITE_NO_MOSI_MESSAGE;
138 case SPI_READ_NO_MISO:
139 return SPI_READ_NO_MISO_MESSAGE;
140 case SPI_READ_NO_DATA:
141 return SPI_READ_NO_DATA_MESSAGE;
142 case INCOMPATIBLE_STATE:
143 return INCOMPATIBLE_STATE_MESSAGE;
144 case NO_AVAILABLE_RESOURCES:
145 return NO_AVAILABLE_RESOURCES_MESSAGE;
146 case RESOURCE_IS_ALLOCATED:
147 return RESOURCE_IS_ALLOCATED_MESSAGE;
148 case RESOURCE_OUT_OF_RANGE:
149 return RESOURCE_OUT_OF_RANGE_MESSAGE;
150 case HAL_INVALID_ACCUMULATOR_CHANNEL:
151 return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE;
152 case HAL_HANDLE_ERROR:
153 return HAL_HANDLE_ERROR_MESSAGE;
154 case NULL_PARAMETER:
155 return NULL_PARAMETER_MESSAGE;
156 case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
157 return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
158 case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
159 return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
160 case PARAMETER_OUT_OF_RANGE:
161 return PARAMETER_OUT_OF_RANGE_MESSAGE;
162 case HAL_COUNTER_NOT_SUPPORTED:
163 return HAL_COUNTER_NOT_SUPPORTED_MESSAGE;
164 case HAL_ERR_CANSessionMux_InvalidBuffer:
165 return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
166 case HAL_ERR_CANSessionMux_MessageNotFound:
167 return ERR_CANSessionMux_MessageNotFound_MESSAGE;
168 case HAL_WARN_CANSessionMux_NoToken:
169 return WARN_CANSessionMux_NoToken_MESSAGE;
170 case HAL_ERR_CANSessionMux_NotAllowed:
171 return ERR_CANSessionMux_NotAllowed_MESSAGE;
172 case HAL_ERR_CANSessionMux_NotInitialized:
173 return ERR_CANSessionMux_NotInitialized_MESSAGE;
174 case VI_ERROR_SYSTEM_ERROR:
175 return VI_ERROR_SYSTEM_ERROR_MESSAGE;
176 case VI_ERROR_INV_OBJECT:
177 return VI_ERROR_INV_OBJECT_MESSAGE;
178 case VI_ERROR_RSRC_LOCKED:
179 return VI_ERROR_RSRC_LOCKED_MESSAGE;
180 case VI_ERROR_RSRC_NFOUND:
181 return VI_ERROR_RSRC_NFOUND_MESSAGE;
182 case VI_ERROR_INV_RSRC_NAME:
183 return VI_ERROR_INV_RSRC_NAME_MESSAGE;
184 case VI_ERROR_QUEUE_OVERFLOW:
185 return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
186 case VI_ERROR_IO:
187 return VI_ERROR_IO_MESSAGE;
188 case VI_ERROR_ASRL_PARITY:
189 return VI_ERROR_ASRL_PARITY_MESSAGE;
190 case VI_ERROR_ASRL_FRAMING:
191 return VI_ERROR_ASRL_FRAMING_MESSAGE;
192 case VI_ERROR_ASRL_OVERRUN:
193 return VI_ERROR_ASRL_OVERRUN_MESSAGE;
194 case VI_ERROR_RSRC_BUSY:
195 return VI_ERROR_RSRC_BUSY_MESSAGE;
196 case VI_ERROR_INV_PARAMETER:
197 return VI_ERROR_INV_PARAMETER_MESSAGE;
198 case HAL_PWM_SCALE_ERROR:
199 return HAL_PWM_SCALE_ERROR_MESSAGE;
200 case HAL_CAN_TIMEOUT:
201 return HAL_CAN_TIMEOUT_MESSAGE;
202 default:
203 return "Unknown error status";
204 }
205}
206
207HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
208
209int32_t HAL_GetFPGAVersion(int32_t* status) {
210 return 2018; // Automatically script this at some point
211}
212
213int64_t HAL_GetFPGARevision(int32_t* status) {
214 return 0; // TODO: Find a better number to return;
215}
216
217uint64_t HAL_GetFPGATime(int32_t* status) { return hal::GetFPGATime(); }
218
219HAL_Bool HAL_GetFPGAButton(int32_t* status) {
220 return SimRoboRioData[0].fpgaButton;
221}
222
223HAL_Bool HAL_GetSystemActive(int32_t* status) {
224 return true; // Figure out if we need to handle this
225}
226
227HAL_Bool HAL_GetBrownedOut(int32_t* status) {
228 return false; // Figure out if we need to detect a brownout condition
229}
230
231HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
232 static std::atomic_bool initialized{false};
233 static wpi::mutex initializeMutex;
234 // Initial check, as if it's true initialization has finished
235 if (initialized) return true;
236
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800237 std::scoped_lock lock(initializeMutex);
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800238 // Second check in case another thread was waiting
239 if (initialized) return true;
240
241 hal::init::InitializeHAL();
242
243 hal::init::HAL_IsInitialized.store(true);
244
245 wpi::outs().SetUnbuffered();
246 if (HAL_LoadExtensions() < 0) return false;
247 hal::RestartTiming();
248 HAL_InitializeDriverStation();
249
250 initialized = true;
251 return true; // Add initialization if we need to at a later point
252}
253
254int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
255 const char* feature) {
256 return 0; // Do nothing for now
257}
258
259} // extern "C"