blob: 8df86646cbddf63a06c91c138a07df6c978e91e6 [file] [log] [blame]
Brian Silvermanf7f267a2017-02-04 16:16:08 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2016-2017. 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#include "HAL/ChipObject.h"
12#include "HAL/Errors.h"
13#include "HAL/Ports.h"
14#include "HAL/handles/HandlesInternal.h"
15#include "HAL/handles/IndexedHandleResource.h"
16#include "PCMInternal.h"
17#include "PortsInternal.h"
18#include "ctre/PCM.h"
19
20namespace {
21struct Solenoid {
22 uint8_t module;
23 uint8_t channel;
24};
25}
26
27using namespace hal;
28
29static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
30 kNumPCMModules * kNumSolenoidChannels,
31 HAL_HandleEnum::Solenoid>
32 solenoidHandles;
33
34extern "C" {
35
36HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
37 int32_t* status) {
38 int16_t channel = getPortHandleChannel(portHandle);
39 int16_t module = getPortHandleModule(portHandle);
40 if (channel == InvalidHandleIndex) {
41 *status = HAL_HANDLE_ERROR;
42 return HAL_kInvalidHandle;
43 }
44
45 // initializePCM will check the module
46 if (!HAL_CheckSolenoidChannel(channel)) {
47 *status = RESOURCE_OUT_OF_RANGE;
48 return HAL_kInvalidHandle;
49 }
50
51 initializePCM(module, status);
52 if (*status != 0) {
53 return HAL_kInvalidHandle;
54 }
55
56 auto handle =
57 solenoidHandles.Allocate(module * kNumSolenoidChannels + channel, status);
58 if (*status != 0) {
59 return HAL_kInvalidHandle;
60 }
61 auto solenoidPort = solenoidHandles.Get(handle);
62 if (solenoidPort == nullptr) { // would only occur on thread issues
63 *status = HAL_HANDLE_ERROR;
64 return HAL_kInvalidHandle;
65 }
66 solenoidPort->module = static_cast<uint8_t>(module);
67 solenoidPort->channel = static_cast<uint8_t>(channel);
68
69 return handle;
70}
71
72void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
73 solenoidHandles.Free(solenoidPortHandle);
74}
75
76HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
77 return module < kNumPCMModules && module >= 0;
78}
79
80HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
81 return channel < kNumSolenoidChannels && channel >= 0;
82}
83
84HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
85 int32_t* status) {
86 auto port = solenoidHandles.Get(solenoidPortHandle);
87 if (port == nullptr) {
88 *status = HAL_HANDLE_ERROR;
89 return false;
90 }
91 bool value;
92
93 *status = PCM_modules[port->module]->GetSolenoid(port->channel, value);
94
95 return value;
96}
97
98int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
99 if (!checkPCMInit(module, status)) return 0;
100 uint8_t value;
101
102 *status = PCM_modules[module]->GetAllSolenoids(value);
103
104 return value;
105}
106
107void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
108 int32_t* status) {
109 auto port = solenoidHandles.Get(solenoidPortHandle);
110 if (port == nullptr) {
111 *status = HAL_HANDLE_ERROR;
112 return;
113 }
114
115 *status = PCM_modules[port->module]->SetSolenoid(port->channel, value);
116}
117
118void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
119 if (!checkPCMInit(module, status)) return;
120
121 *status = PCM_modules[module]->SetAllSolenoids(state);
122}
123
124int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
125 if (!checkPCMInit(module, status)) return 0;
126 uint8_t value;
127
128 *status = PCM_modules[module]->GetSolenoidBlackList(value);
129
130 return value;
131}
132HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
133 if (!checkPCMInit(module, status)) return 0;
134 bool value;
135
136 *status = PCM_modules[module]->GetSolenoidStickyFault(value);
137
138 return value;
139}
140HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
141 if (!checkPCMInit(module, status)) return false;
142 bool value;
143
144 *status = PCM_modules[module]->GetSolenoidFault(value);
145
146 return value;
147}
148void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
149 if (!checkPCMInit(module, status)) return;
150
151 *status = PCM_modules[module]->ClearStickyFaults();
152}
153
154} // extern "C"