WPILibC++ 2025.0.0-alpha-1-14-g3b6f38d
HandlesInternal.h
Go to the documentation of this file.
1// 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#pragma once
6
7#include <stdint.h>
8
10
11#include "hal/Types.h"
12
13/* General Handle Data Layout
14 * Bits 0-15: Handle Index
15 * Bits 16-23: 8 bit rolling reset detection
16 * Bits 24-30: Handle Type
17 * Bit 31: 1 if handle error, 0 if no error
18 *
19 * Other specialized handles will use different formats, however Bits 24-31 are
20 * always reserved for type and error handling.
21 */
22
23namespace hal {
24
25/**
26 * Base for all HAL Handles.
27 */
29 public:
32 HandleBase(const HandleBase&) = delete;
33 HandleBase& operator=(const HandleBase&) = delete;
34 virtual void ResetHandles();
35 static void ResetGlobalHandles();
36
37 protected:
38 int16_t m_version;
39};
40
41constexpr int16_t InvalidHandleIndex = -1;
42
43/**
44 * Enum of HAL handle types. Vendors/Teams should use Vendor (17).
45 */
46enum class HAL_HandleEnum {
47 Undefined = 0,
49 Port = 2,
50 Notifier = 3,
51 Interrupt = 4,
52 AnalogOutput = 5,
53 AnalogInput = 6,
54 AnalogTrigger = 7,
55 Relay = 8,
56 PWM = 9,
57 DigitalPWM = 10,
58 Counter = 11,
59 FPGAEncoder = 12,
60 Encoder = 13,
61 Compressor = 14,
62 Solenoid = 15,
63 AnalogGyro = 16,
64 Vendor = 17,
65 SimulationJni = 18,
66 CAN = 19,
67 SerialPort = 20,
68 DutyCycle = 21,
69 DMA = 22,
70 AddressableLED = 23,
71 CTREPCM = 24,
72 CTREPDP = 25,
73 REVPDH = 26,
74 REVPH = 27,
75};
76
77/**
78 * Get the handle index from a handle.
79 *
80 * @param handle the handle
81 * @return the index
82 */
83static inline int16_t getHandleIndex(HAL_Handle handle) {
84 // mask and return last 16 bits
85 return static_cast<int16_t>(handle & 0xffff);
86}
87
88/**
89 * Get the handle type from a handle.
90 *
91 * @param handle the handle
92 * @return the type
93 */
95 // mask first 8 bits and cast to enum
96 return static_cast<HAL_HandleEnum>((handle >> 24) & 0xff);
97}
98
99/**
100 * Get if the handle is a specific type.
101 *
102 * @param handle the handle
103 * @param handleType the type to check
104 * @return true if the type is correct, otherwise false
105 */
106static inline bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType) {
107 return handleType == getHandleType(handle);
108}
109
110/**
111 * Get if the version of the handle is correct.
112 *
113 * Do not use on the roboRIO, used specifically for the sim to handle resets.
114 *
115 * @param handle the handle
116 * @param version the handle version to check
117 * @return true if the handle is the right version, otherwise false
118 */
119static inline bool isHandleCorrectVersion(HAL_Handle handle, int16_t version) {
120 return (((handle & 0xFF0000) >> 16) & version) == version;
121}
122
123/**
124 * Get if the handle is a correct type and version.
125 *
126 * Note the version is not checked on the roboRIO.
127 *
128 * @param handle the handle
129 * @param enumType the type to check
130 * @param version the handle version to check
131 * @return true if the handle is proper version and type, otherwise
132 * false.
133 */
134inline int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType,
135 int16_t version) {
136 if (!isHandleType(handle, enumType)) {
137 return InvalidHandleIndex;
138 }
139#if !defined(__FRC_ROBORIO__)
140 if (!isHandleCorrectVersion(handle, version)) {
141 return InvalidHandleIndex;
142 }
143#endif
144 return getHandleIndex(handle);
145}
146
147/* specialized functions for Port handle
148 * Port Handle Data Layout
149 * Bits 0-7: Channel Number
150 * Bits 8-15: Module Number
151 * Bits 16-23: Unused
152 * Bits 24-30: Handle Type
153 * Bit 31: 1 if handle error, 0 if no error
154 */
155
156// using a 16 bit value so we can store 0-255 and still report error
157/**
158 * Gets the port channel of a port handle.
159 *
160 * @param handle the port handle
161 * @return the port channel
162 */
163inline int16_t getPortHandleChannel(HAL_PortHandle handle) {
164 if (!isHandleType(handle, HAL_HandleEnum::Port)) {
165 return InvalidHandleIndex;
166 }
167 return static_cast<uint8_t>(handle & 0xff);
168}
169
170// using a 16 bit value so we can store 0-255 and still report error
171/**
172 * Gets the port module of a port handle.
173 *
174 * @param handle the port handle
175 * @return the port module
176 */
177inline int16_t getPortHandleModule(HAL_PortHandle handle) {
178 if (!isHandleType(handle, HAL_HandleEnum::Port)) {
179 return InvalidHandleIndex;
180 }
181 return static_cast<uint8_t>((handle >> 8) & 0xff);
182}
183
184// using a 16 bit value so we can store 0-255 and still report error
185/**
186 * Gets the SPI channel of a port handle.
187 *
188 * @param handle the port handle
189 * @return the port SPI channel
190 */
192 if (!isHandleType(handle, HAL_HandleEnum::Port)) {
193 return InvalidHandleIndex;
194 }
195 return static_cast<uint8_t>((handle >> 16) & 0xff);
196}
197
198/**
199 * Create a port handle.
200 *
201 * @param channel the channel
202 * @param module the module
203 * @return port handle for the module and channel
204 */
205HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module);
206
207/**
208 * Create a port handle for SPI.
209 *
210 * @param channel the SPI channel
211 * @return port handle for the channel
212 */
214
215/**
216 * Create a handle for a specific index, type and version.
217 *
218 * Note the version is not checked on the roboRIO.
219 *
220 * @param index the index
221 * @param handleType the handle type
222 * @param version the handle version
223 * @return the created handle
224 */
225HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
226 int16_t version);
227} // namespace hal
Base for all HAL Handles.
Definition: HandlesInternal.h:28
HandleBase & operator=(const HandleBase &)=delete
virtual void ResetHandles()
static void ResetGlobalHandles()
HandleBase(const HandleBase &)=delete
int16_t m_version
Definition: HandlesInternal.h:38
int32_t HAL_Handle
Definition: Types.h:17
HAL_Handle HAL_PortHandle
Definition: Types.h:19
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: InterruptManager.h:13
static bool isHandleCorrectVersion(HAL_Handle handle, int16_t version)
Get if the version of the handle is correct.
Definition: HandlesInternal.h:119
HAL_HandleEnum
Enum of HAL handle types.
Definition: HandlesInternal.h:46
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.
constexpr int16_t InvalidHandleIndex
Definition: HandlesInternal.h:41
int16_t getPortHandleModule(HAL_PortHandle handle)
Gets the port module of a port handle.
Definition: HandlesInternal.h:177
static bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType)
Get if the handle is a specific type.
Definition: HandlesInternal.h:106
HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module)
Create a port handle.
static HAL_HandleEnum getHandleType(HAL_Handle handle)
Get the handle type from a handle.
Definition: HandlesInternal.h:94
static int16_t getHandleIndex(HAL_Handle handle)
Get the handle index from a handle.
Definition: HandlesInternal.h:83
HAL_PortHandle createPortHandleForSPI(uint8_t channel)
Create a port handle for SPI.
int16_t getPortHandleChannel(HAL_PortHandle handle)
Gets the port channel of a port handle.
Definition: HandlesInternal.h:163
int16_t getPortHandleSPIEnable(HAL_PortHandle handle)
Gets the SPI channel of a port handle.
Definition: HandlesInternal.h:191
int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType, int16_t version)
Get if the handle is a correct type and version.
Definition: HandlesInternal.h:134
constexpr int kHandleTypeHALBase
Definition: Synchronization.h:45