blob: 0dda617300abcece3da4164b7cbb14e958b5ab1b [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();
James Kuszmaul4b81d302019-12-14 20:53:14 -080028 InitializeAddressableLEDData();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080029 InitializeAnalogGyroData();
30 InitializeAnalogInData();
31 InitializeAnalogOutData();
32 InitializeAnalogTriggerData();
33 InitializeCanData();
34 InitializeCANAPI();
35 InitializeDigitalPWMData();
James Kuszmaul4b81d302019-12-14 20:53:14 -080036 InitializeDutyCycleData();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080037 InitializeDIOData();
38 InitializeDriverStationData();
39 InitializeEncoderData();
40 InitializeI2CData();
41 InitializePCMData();
42 InitializePDPData();
43 InitializePWMData();
44 InitializeRelayData();
45 InitializeRoboRioData();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080046 InitializeSimDeviceData();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080047 InitializeSPIAccelerometerData();
48 InitializeSPIData();
49 InitializeAccelerometer();
James Kuszmaul4b81d302019-12-14 20:53:14 -080050 InitializeAddressableLED();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080051 InitializeAnalogAccumulator();
52 InitializeAnalogGyro();
53 InitializeAnalogInput();
54 InitializeAnalogInternal();
55 InitializeAnalogOutput();
56 InitializeCAN();
57 InitializeCompressor();
58 InitializeConstants();
59 InitializeCounter();
60 InitializeDigitalInternal();
61 InitializeDIO();
James Kuszmaul4b81d302019-12-14 20:53:14 -080062 InitializeDutyCycle();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080063 InitializeDriverStation();
64 InitializeEncoder();
65 InitializeExtensions();
66 InitializeI2C();
67 InitializeInterrupts();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080068 InitializeMain();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080069 InitializeMockHooks();
70 InitializeNotifier();
71 InitializePDP();
72 InitializePorts();
73 InitializePower();
74 InitializePWM();
75 InitializeRelay();
76 InitializeSerialPort();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080077 InitializeSimDevice();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080078 InitializeSolenoid();
79 InitializeSPI();
80 InitializeThreads();
81}
82} // namespace init
83} // namespace hal
84
85extern "C" {
86
87HAL_PortHandle HAL_GetPort(int32_t channel) {
88 // Dont allow a number that wouldn't fit in a uint8_t
89 if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
90 return createPortHandle(channel, 1);
91}
92
93HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
94 // Dont allow a number that wouldn't fit in a uint8_t
95 if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
96 if (module < 0 || module >= 255) return HAL_kInvalidHandle;
97 return createPortHandle(channel, module);
98}
99
100const char* HAL_GetErrorMessage(int32_t code) {
101 switch (code) {
102 case 0:
103 return "";
104 case CTR_RxTimeout:
105 return CTR_RxTimeout_MESSAGE;
106 case CTR_TxTimeout:
107 return CTR_TxTimeout_MESSAGE;
108 case CTR_InvalidParamValue:
109 return CTR_InvalidParamValue_MESSAGE;
110 case CTR_UnexpectedArbId:
111 return CTR_UnexpectedArbId_MESSAGE;
112 case CTR_TxFailed:
113 return CTR_TxFailed_MESSAGE;
114 case CTR_SigNotUpdated:
115 return CTR_SigNotUpdated_MESSAGE;
116 case NiFpga_Status_FifoTimeout:
117 return NiFpga_Status_FifoTimeout_MESSAGE;
118 case NiFpga_Status_TransferAborted:
119 return NiFpga_Status_TransferAborted_MESSAGE;
120 case NiFpga_Status_MemoryFull:
121 return NiFpga_Status_MemoryFull_MESSAGE;
122 case NiFpga_Status_SoftwareFault:
123 return NiFpga_Status_SoftwareFault_MESSAGE;
124 case NiFpga_Status_InvalidParameter:
125 return NiFpga_Status_InvalidParameter_MESSAGE;
126 case NiFpga_Status_ResourceNotFound:
127 return NiFpga_Status_ResourceNotFound_MESSAGE;
128 case NiFpga_Status_ResourceNotInitialized:
129 return NiFpga_Status_ResourceNotInitialized_MESSAGE;
130 case NiFpga_Status_HardwareFault:
131 return NiFpga_Status_HardwareFault_MESSAGE;
132 case NiFpga_Status_IrqTimeout:
133 return NiFpga_Status_IrqTimeout_MESSAGE;
134 case SAMPLE_RATE_TOO_HIGH:
135 return SAMPLE_RATE_TOO_HIGH_MESSAGE;
136 case VOLTAGE_OUT_OF_RANGE:
137 return VOLTAGE_OUT_OF_RANGE_MESSAGE;
138 case LOOP_TIMING_ERROR:
139 return LOOP_TIMING_ERROR_MESSAGE;
140 case SPI_WRITE_NO_MOSI:
141 return SPI_WRITE_NO_MOSI_MESSAGE;
142 case SPI_READ_NO_MISO:
143 return SPI_READ_NO_MISO_MESSAGE;
144 case SPI_READ_NO_DATA:
145 return SPI_READ_NO_DATA_MESSAGE;
146 case INCOMPATIBLE_STATE:
147 return INCOMPATIBLE_STATE_MESSAGE;
148 case NO_AVAILABLE_RESOURCES:
149 return NO_AVAILABLE_RESOURCES_MESSAGE;
150 case RESOURCE_IS_ALLOCATED:
151 return RESOURCE_IS_ALLOCATED_MESSAGE;
152 case RESOURCE_OUT_OF_RANGE:
153 return RESOURCE_OUT_OF_RANGE_MESSAGE;
154 case HAL_INVALID_ACCUMULATOR_CHANNEL:
155 return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE;
156 case HAL_HANDLE_ERROR:
157 return HAL_HANDLE_ERROR_MESSAGE;
158 case NULL_PARAMETER:
159 return NULL_PARAMETER_MESSAGE;
160 case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
161 return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
162 case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
163 return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
164 case PARAMETER_OUT_OF_RANGE:
165 return PARAMETER_OUT_OF_RANGE_MESSAGE;
166 case HAL_COUNTER_NOT_SUPPORTED:
167 return HAL_COUNTER_NOT_SUPPORTED_MESSAGE;
168 case HAL_ERR_CANSessionMux_InvalidBuffer:
169 return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
170 case HAL_ERR_CANSessionMux_MessageNotFound:
171 return ERR_CANSessionMux_MessageNotFound_MESSAGE;
172 case HAL_WARN_CANSessionMux_NoToken:
173 return WARN_CANSessionMux_NoToken_MESSAGE;
174 case HAL_ERR_CANSessionMux_NotAllowed:
175 return ERR_CANSessionMux_NotAllowed_MESSAGE;
176 case HAL_ERR_CANSessionMux_NotInitialized:
177 return ERR_CANSessionMux_NotInitialized_MESSAGE;
178 case VI_ERROR_SYSTEM_ERROR:
179 return VI_ERROR_SYSTEM_ERROR_MESSAGE;
180 case VI_ERROR_INV_OBJECT:
181 return VI_ERROR_INV_OBJECT_MESSAGE;
182 case VI_ERROR_RSRC_LOCKED:
183 return VI_ERROR_RSRC_LOCKED_MESSAGE;
184 case VI_ERROR_RSRC_NFOUND:
185 return VI_ERROR_RSRC_NFOUND_MESSAGE;
186 case VI_ERROR_INV_RSRC_NAME:
187 return VI_ERROR_INV_RSRC_NAME_MESSAGE;
188 case VI_ERROR_QUEUE_OVERFLOW:
189 return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
190 case VI_ERROR_IO:
191 return VI_ERROR_IO_MESSAGE;
192 case VI_ERROR_ASRL_PARITY:
193 return VI_ERROR_ASRL_PARITY_MESSAGE;
194 case VI_ERROR_ASRL_FRAMING:
195 return VI_ERROR_ASRL_FRAMING_MESSAGE;
196 case VI_ERROR_ASRL_OVERRUN:
197 return VI_ERROR_ASRL_OVERRUN_MESSAGE;
198 case VI_ERROR_RSRC_BUSY:
199 return VI_ERROR_RSRC_BUSY_MESSAGE;
200 case VI_ERROR_INV_PARAMETER:
201 return VI_ERROR_INV_PARAMETER_MESSAGE;
202 case HAL_PWM_SCALE_ERROR:
203 return HAL_PWM_SCALE_ERROR_MESSAGE;
204 case HAL_CAN_TIMEOUT:
205 return HAL_CAN_TIMEOUT_MESSAGE;
James Kuszmaul4b81d302019-12-14 20:53:14 -0800206 case HAL_SIM_NOT_SUPPORTED:
207 return HAL_SIM_NOT_SUPPORTED_MESSAGE;
208 case HAL_CAN_BUFFER_OVERRUN:
209 return HAL_CAN_BUFFER_OVERRUN_MESSAGE;
210 case HAL_LED_CHANNEL_ERROR:
211 return HAL_LED_CHANNEL_ERROR_MESSAGE;
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800212 default:
213 return "Unknown error status";
214 }
215}
216
217HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
218
219int32_t HAL_GetFPGAVersion(int32_t* status) {
220 return 2018; // Automatically script this at some point
221}
222
223int64_t HAL_GetFPGARevision(int32_t* status) {
224 return 0; // TODO: Find a better number to return;
225}
226
227uint64_t HAL_GetFPGATime(int32_t* status) { return hal::GetFPGATime(); }
228
James Kuszmaul4b81d302019-12-14 20:53:14 -0800229uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status) {
230 // Capture the current FPGA time. This will give us the upper half of the
231 // clock.
232 uint64_t fpga_time = HAL_GetFPGATime(status);
233 if (*status != 0) return 0;
234
235 // Now, we need to detect the case where the lower bits rolled over after we
236 // sampled. In that case, the upper bits will be 1 bigger than they should
237 // be.
238
239 // Break it into lower and upper portions.
240 uint32_t lower = fpga_time & 0xffffffffull;
241 uint64_t upper = (fpga_time >> 32) & 0xffffffff;
242
243 // The time was sampled *before* the current time, so roll it back.
244 if (lower < unexpanded_lower) {
245 --upper;
246 }
247
248 return (upper << 32) + static_cast<uint64_t>(unexpanded_lower);
249}
250
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800251HAL_Bool HAL_GetFPGAButton(int32_t* status) {
252 return SimRoboRioData[0].fpgaButton;
253}
254
255HAL_Bool HAL_GetSystemActive(int32_t* status) {
256 return true; // Figure out if we need to handle this
257}
258
259HAL_Bool HAL_GetBrownedOut(int32_t* status) {
260 return false; // Figure out if we need to detect a brownout condition
261}
262
263HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
264 static std::atomic_bool initialized{false};
265 static wpi::mutex initializeMutex;
266 // Initial check, as if it's true initialization has finished
267 if (initialized) return true;
268
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800269 std::scoped_lock lock(initializeMutex);
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800270 // Second check in case another thread was waiting
271 if (initialized) return true;
272
273 hal::init::InitializeHAL();
274
275 hal::init::HAL_IsInitialized.store(true);
276
277 wpi::outs().SetUnbuffered();
278 if (HAL_LoadExtensions() < 0) return false;
279 hal::RestartTiming();
280 HAL_InitializeDriverStation();
281
282 initialized = true;
283 return true; // Add initialization if we need to at a later point
284}
285
286int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
287 const char* feature) {
288 return 0; // Do nothing for now
289}
290
291} // extern "C"