blob: 9ddb6558487f40e6d958d02c10fa7be6657288d1 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#include "hal/REVPH.h"
6
7#include "HALInitializer.h"
8#include "HALInternal.h"
9#include "PortsInternal.h"
10#include "hal/CANAPI.h"
11#include "hal/Errors.h"
12#include "hal/handles/IndexedHandleResource.h"
13#include "mockdata/REVPHDataInternal.h"
14
15using namespace hal;
16
17namespace {
18struct PCM {
19 int32_t module;
20 wpi::mutex lock;
21 std::string previousAllocation;
22};
23} // namespace
24
25static IndexedHandleResource<HAL_REVPHHandle, PCM, kNumREVPHModules,
26 HAL_HandleEnum::REVPH>* pcmHandles;
27
28namespace hal::init {
29void InitializeREVPH() {
30 static IndexedHandleResource<HAL_REVPHHandle, PCM, kNumREVPHModules,
31 HAL_HandleEnum::REVPH>
32 pH;
33 pcmHandles = &pH;
34}
35} // namespace hal::init
36
37HAL_REVPHHandle HAL_InitializeREVPH(int32_t module,
38 const char* allocationLocation,
39 int32_t* status) {
40 hal::init::CheckInit();
41
42 if (module == 0) {
43 hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PH", 1,
44 kNumREVPHModules, module);
45 return HAL_kInvalidHandle;
46 }
47
48 HAL_REVPHHandle handle;
49 auto pcm = pcmHandles->Allocate(module, &handle, status);
50
51 if (*status != 0) {
52 if (pcm) {
53 hal::SetLastErrorPreviouslyAllocated(status, "REV PH", module,
54 pcm->previousAllocation);
55 } else {
56 hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PH", 1,
57 kNumREVPHModules, module);
58 }
59 return HAL_kInvalidHandle; // failed to allocate. Pass error back.
60 }
61
62 pcm->previousAllocation = allocationLocation ? allocationLocation : "";
63 pcm->module = module;
64
65 SimREVPHData[module].initialized = true;
66 // Enable closed loop
67 SimREVPHData[module].closedLoopEnabled = true;
68
69 return handle;
70}
71
72void HAL_FreeREVPH(HAL_REVPHHandle handle) {
73 auto pcm = pcmHandles->Get(handle);
74 if (pcm == nullptr) {
75 pcmHandles->Free(handle);
76 return;
77 }
78 SimREVPHData[pcm->module].initialized = false;
79 pcmHandles->Free(handle);
80}
81
82HAL_Bool HAL_CheckREVPHModuleNumber(int32_t module) {
83 return module >= 1 && module < kNumREVPDHModules;
84}
85
86HAL_Bool HAL_CheckREVPHSolenoidChannel(int32_t channel) {
87 return channel < kNumREVPHChannels && channel >= 0;
88}
89
90HAL_Bool HAL_GetREVPHCompressor(HAL_REVPHHandle handle, int32_t* status) {
91 auto pcm = pcmHandles->Get(handle);
92 if (pcm == nullptr) {
93 *status = HAL_HANDLE_ERROR;
94 return false;
95 }
96
97 return SimREVPHData[pcm->module].compressorOn;
98}
99
100void HAL_SetREVPHClosedLoopControl(HAL_REVPHHandle handle, HAL_Bool enabled,
101 int32_t* status) {
102 auto pcm = pcmHandles->Get(handle);
103 if (pcm == nullptr) {
104 *status = HAL_HANDLE_ERROR;
105 return;
106 }
107
108 SimREVPHData[pcm->module].closedLoopEnabled = enabled;
109}
110
111HAL_Bool HAL_GetREVPHClosedLoopControl(HAL_REVPHHandle handle,
112 int32_t* status) {
113 auto pcm = pcmHandles->Get(handle);
114 if (pcm == nullptr) {
115 *status = HAL_HANDLE_ERROR;
116 return false;
117 }
118
119 return SimREVPHData[pcm->module].closedLoopEnabled;
120}
121
122HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status) {
123 auto pcm = pcmHandles->Get(handle);
124 if (pcm == nullptr) {
125 *status = HAL_HANDLE_ERROR;
126 return false;
127 }
128
129 return SimREVPHData[pcm->module].pressureSwitch;
130}
131
132double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
133 int32_t* status) {
134 return 0;
135}
136
137double HAL_GetREVPHCompressorCurrent(HAL_REVPHHandle handle, int32_t* status) {
138 auto pcm = pcmHandles->Get(handle);
139 if (pcm == nullptr) {
140 *status = HAL_HANDLE_ERROR;
141 return 0;
142 }
143
144 return SimREVPHData[pcm->module].compressorCurrent;
145}
146
147int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status) {
148 auto pcm = pcmHandles->Get(handle);
149 if (pcm == nullptr) {
150 *status = HAL_HANDLE_ERROR;
151 return 0;
152 }
153
154 std::scoped_lock lock{pcm->lock};
155 auto& data = SimREVPHData[pcm->module].solenoidOutput;
156 uint8_t ret = 0;
157 for (int i = 0; i < kNumREVPHChannels; i++) {
158 ret |= (data[i] << i);
159 }
160 return ret;
161}
162void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
163 int32_t* status) {
164 auto pcm = pcmHandles->Get(handle);
165 if (pcm == nullptr) {
166 *status = HAL_HANDLE_ERROR;
167 return;
168 }
169
170 auto& data = SimREVPHData[pcm->module].solenoidOutput;
171 std::scoped_lock lock{pcm->lock};
172 for (int i = 0; i < kNumREVPHChannels; i++) {
173 auto indexMask = (1 << i);
174 if ((mask & indexMask) != 0) {
175 data[i] = (values & indexMask) != 0;
176 }
177 }
178}
179
180void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
181 int32_t* status) {}