blob: c53db11ca754645d33b138926cebf73a435112e3 [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
3/* 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/Solenoid.h"
9
10#include <FRC_NetworkCommunication/LoadOut.h>
11
12#include "HALInitializer.h"
13#include "PCMInternal.h"
14#include "PortsInternal.h"
15#include "ctre/PCM.h"
16#include "hal/ChipObject.h"
17#include "hal/Errors.h"
18#include "hal/Ports.h"
19#include "hal/handles/HandlesInternal.h"
20#include "hal/handles/IndexedHandleResource.h"
21
22namespace {
23
24struct Solenoid {
25 uint8_t module;
26 uint8_t channel;
27};
28
29} // namespace
30
31using namespace hal;
32
33static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
34 kNumPCMModules * kNumSolenoidChannels,
35 HAL_HandleEnum::Solenoid>* solenoidHandles;
36
37namespace hal {
38namespace init {
39void InitializeSolenoid() {
40 static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
41 kNumPCMModules * kNumSolenoidChannels,
42 HAL_HandleEnum::Solenoid>
43 sH;
44 solenoidHandles = &sH;
45}
46} // namespace init
47} // namespace hal
48
49extern "C" {
50
51HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
52 int32_t* status) {
53 hal::init::CheckInit();
54 int16_t channel = getPortHandleChannel(portHandle);
55 int16_t module = getPortHandleModule(portHandle);
56 if (channel == InvalidHandleIndex) {
57 *status = HAL_HANDLE_ERROR;
58 return HAL_kInvalidHandle;
59 }
60
61 // initializePCM will check the module
62 if (!HAL_CheckSolenoidChannel(channel)) {
63 *status = RESOURCE_OUT_OF_RANGE;
64 return HAL_kInvalidHandle;
65 }
66
67 initializePCM(module, status);
68 if (*status != 0) {
69 return HAL_kInvalidHandle;
70 }
71
72 auto handle = solenoidHandles->Allocate(
73 module * kNumSolenoidChannels + channel, status);
74 if (*status != 0) {
75 return HAL_kInvalidHandle;
76 }
77 auto solenoidPort = solenoidHandles->Get(handle);
78 if (solenoidPort == nullptr) { // would only occur on thread issues
79 *status = HAL_HANDLE_ERROR;
80 return HAL_kInvalidHandle;
81 }
82 solenoidPort->module = static_cast<uint8_t>(module);
83 solenoidPort->channel = static_cast<uint8_t>(channel);
84
85 return handle;
86}
87
88void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
89 solenoidHandles->Free(solenoidPortHandle);
90}
91
92HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
93 return module < kNumPCMModules && module >= 0;
94}
95
96HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
97 return channel < kNumSolenoidChannels && channel >= 0;
98}
99
100HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
101 int32_t* status) {
102 auto port = solenoidHandles->Get(solenoidPortHandle);
103 if (port == nullptr) {
104 *status = HAL_HANDLE_ERROR;
105 return false;
106 }
107 bool value;
108
109 *status = PCM_modules[port->module]->GetSolenoid(port->channel, value);
110
111 return value;
112}
113
114int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
115 if (!checkPCMInit(module, status)) return 0;
116 uint8_t value;
117
118 *status = PCM_modules[module]->GetAllSolenoids(value);
119
120 return value;
121}
122
123void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
124 int32_t* status) {
125 auto port = solenoidHandles->Get(solenoidPortHandle);
126 if (port == nullptr) {
127 *status = HAL_HANDLE_ERROR;
128 return;
129 }
130
131 *status = PCM_modules[port->module]->SetSolenoid(port->channel, value);
132}
133
134void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
135 if (!checkPCMInit(module, status)) return;
136
137 *status = PCM_modules[module]->SetAllSolenoids(state);
138}
139
140int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
141 if (!checkPCMInit(module, status)) return 0;
142 uint8_t value;
143
144 *status = PCM_modules[module]->GetSolenoidBlackList(value);
145
146 return value;
147}
148HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
149 if (!checkPCMInit(module, status)) return 0;
150 bool value;
151
152 *status = PCM_modules[module]->GetSolenoidStickyFault(value);
153
154 return value;
155}
156HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
157 if (!checkPCMInit(module, status)) return false;
158 bool value;
159
160 *status = PCM_modules[module]->GetSolenoidFault(value);
161
162 return value;
163}
164void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
165 if (!checkPCMInit(module, status)) return;
166
167 *status = PCM_modules[module]->ClearStickyFaults();
168}
169
170void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
171 int32_t durMS, int32_t* status) {
172 auto port = solenoidHandles->Get(solenoidPortHandle);
173 if (port == nullptr) {
174 *status = HAL_HANDLE_ERROR;
175 return;
176 }
177
178 *status =
179 PCM_modules[port->module]->SetOneShotDurationMs(port->channel, durMS);
180}
181
182void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {
183 auto port = solenoidHandles->Get(solenoidPortHandle);
184 if (port == nullptr) {
185 *status = HAL_HANDLE_ERROR;
186 return;
187 }
188
189 *status = PCM_modules[port->module]->FireOneShotSolenoid(port->channel);
190}
191} // extern "C"