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