blob: d3f0c5da8aa381e57fd51a088355844e6897c7c1 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -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 "HALInitializer.h"
11#include "PortsInternal.h"
12#include "hal/Errors.h"
13#include "hal/handles/HandlesInternal.h"
14#include "hal/handles/IndexedHandleResource.h"
15#include "mockdata/PCMDataInternal.h"
16
17namespace {
18struct Solenoid {
19 uint8_t module;
20 uint8_t channel;
21};
22} // namespace
23
24using namespace hal;
25
26static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
27 kNumPCMModules * kNumSolenoidChannels,
28 HAL_HandleEnum::Solenoid>* solenoidHandles;
29
30namespace hal {
31namespace init {
32void InitializeSolenoid() {
33 static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
34 kNumPCMModules * kNumSolenoidChannels,
35 HAL_HandleEnum::Solenoid>
36 sH;
37 solenoidHandles = &sH;
38}
39} // namespace init
40} // namespace hal
41
42extern "C" {
43HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
44 int32_t* status) {
45 hal::init::CheckInit();
46 int16_t channel = getPortHandleChannel(portHandle);
47 int16_t module = getPortHandleModule(portHandle);
48 if (channel == InvalidHandleIndex) {
49 *status = HAL_HANDLE_ERROR;
50 return HAL_kInvalidHandle;
51 }
52
53 if (!HAL_CheckSolenoidChannel(channel)) {
54 *status = RESOURCE_OUT_OF_RANGE;
55 return HAL_kInvalidHandle;
56 }
57
58 if (!HAL_CheckSolenoidModule(module)) {
59 *status = RESOURCE_OUT_OF_RANGE;
60 return HAL_kInvalidHandle;
61 }
62
63 auto handle = solenoidHandles->Allocate(
64 module * kNumSolenoidChannels + channel, status);
65 if (handle == HAL_kInvalidHandle) { // out of resources
66 *status = NO_AVAILABLE_RESOURCES;
67 return HAL_kInvalidHandle;
68 }
69 auto solenoidPort = solenoidHandles->Get(handle);
70 if (solenoidPort == nullptr) { // would only occur on thread issues
71 *status = HAL_HANDLE_ERROR;
72 return HAL_kInvalidHandle;
73 }
74 solenoidPort->module = static_cast<uint8_t>(module);
75 solenoidPort->channel = static_cast<uint8_t>(channel);
76
77 HALSIM_SetPCMSolenoidInitialized(module, channel, true);
78
79 return handle;
80}
81void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
82 auto port = solenoidHandles->Get(solenoidPortHandle);
83 if (port == nullptr) return;
84 solenoidHandles->Free(solenoidPortHandle);
85 HALSIM_SetPCMSolenoidInitialized(port->module, port->channel, false);
86}
87HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
88 return module < kNumPCMModules && module >= 0;
89}
90
91HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
92 return channel < kNumSolenoidChannels && channel >= 0;
93}
94HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
95 int32_t* status) {
96 auto port = solenoidHandles->Get(solenoidPortHandle);
97 if (port == nullptr) {
98 *status = HAL_HANDLE_ERROR;
99 return false;
100 }
101
102 return HALSIM_GetPCMSolenoidOutput(port->module, port->channel);
103}
104int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
105 int32_t total = 0;
106 for (int i = 0; i < kNumSolenoidChannels; i++) {
107 int32_t channel = HALSIM_GetPCMSolenoidOutput(module, i) ? 1 : 0;
108 total = total + (channel << i);
109 }
110
111 return total;
112}
113void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
114 int32_t* status) {
115 auto port = solenoidHandles->Get(solenoidPortHandle);
116 if (port == nullptr) {
117 *status = HAL_HANDLE_ERROR;
118 return;
119 }
120
121 HALSIM_SetPCMSolenoidOutput(port->module, port->channel, value);
122}
123int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
124 return 0;
125}
126HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
127 return 0;
128}
129HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
130 return 0;
131}
132void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {}
133void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
134 int32_t durMS, int32_t* status) {}
135void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {}
136} // extern "C"