WPILibC++  2020.3.2
HandlesInternal.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2019 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 #pragma once
9 
10 #include <stdint.h>
11 
12 #include "hal/Types.h"
13 
14 /* General Handle Data Layout
15  * Bits 0-15: Handle Index
16  * Bits 16-23: 8 bit rolling reset detection
17  * Bits 24-30: Handle Type
18  * Bit 31: 1 if handle error, 0 if no error
19  *
20  * Other specialized handles will use different formats, however Bits 24-31 are
21  * always reserved for type and error handling.
22  */
23 
24 namespace hal {
25 
29 class HandleBase {
30  public:
31  HandleBase();
32  ~HandleBase();
33  HandleBase(const HandleBase&) = delete;
34  HandleBase& operator=(const HandleBase&) = delete;
35  virtual void ResetHandles();
36  static void ResetGlobalHandles();
37 
38  protected:
39  int16_t m_version;
40 };
41 
42 constexpr int16_t InvalidHandleIndex = -1;
43 
47 enum class HAL_HandleEnum {
48  Undefined = 0,
49  DIO = 1,
50  Port = 2,
51  Notifier = 3,
52  Interrupt = 4,
53  AnalogOutput = 5,
54  AnalogInput = 6,
55  AnalogTrigger = 7,
56  Relay = 8,
57  PWM = 9,
58  DigitalPWM = 10,
59  Counter = 11,
60  FPGAEncoder = 12,
61  Encoder = 13,
62  Compressor = 14,
63  Solenoid = 15,
64  AnalogGyro = 16,
65  Vendor = 17,
66  SimulationJni = 18,
67  CAN = 19,
68  SerialPort = 20,
69  DutyCycle = 21,
70  DMA = 22,
71  AddressableLED = 23,
72 };
73 
80 static inline int16_t getHandleIndex(HAL_Handle handle) {
81  // mask and return last 16 bits
82  return static_cast<int16_t>(handle & 0xffff);
83 }
84 
91 static inline HAL_HandleEnum getHandleType(HAL_Handle handle) {
92  // mask first 8 bits and cast to enum
93  return static_cast<HAL_HandleEnum>((handle >> 24) & 0xff);
94 }
95 
103 static inline bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType) {
104  return handleType == getHandleType(handle);
105 }
106 
116 static inline bool isHandleCorrectVersion(HAL_Handle handle, int16_t version) {
117  return (((handle & 0xFF0000) >> 16) & version) == version;
118 }
119 
131 static inline int16_t getHandleTypedIndex(HAL_Handle handle,
132  HAL_HandleEnum enumType,
133  int16_t version) {
134  if (!isHandleType(handle, enumType)) return InvalidHandleIndex;
135 #if !defined(__FRC_ROBORIO__)
136  if (!isHandleCorrectVersion(handle, version)) return InvalidHandleIndex;
137 #endif
138  return getHandleIndex(handle);
139 }
140 
141 /* specialized functions for Port handle
142  * Port Handle Data Layout
143  * Bits 0-7: Channel Number
144  * Bits 8-15: Module Number
145  * Bits 16-23: Unused
146  * Bits 24-30: Handle Type
147  * Bit 31: 1 if handle error, 0 if no error
148  */
149 
150 // using a 16 bit value so we can store 0-255 and still report error
157 static inline int16_t getPortHandleChannel(HAL_PortHandle handle) {
158  if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
159  return static_cast<uint8_t>(handle & 0xff);
160 }
161 
162 // using a 16 bit value so we can store 0-255 and still report error
169 static inline int16_t getPortHandleModule(HAL_PortHandle handle) {
170  if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
171  return static_cast<uint8_t>((handle >> 8) & 0xff);
172 }
173 
174 // using a 16 bit value so we can store 0-255 and still report error
181 static inline int16_t getPortHandleSPIEnable(HAL_PortHandle handle) {
182  if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
183  return static_cast<uint8_t>((handle >> 16) & 0xff);
184 }
185 
193 HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module);
194 
201 HAL_PortHandle createPortHandleForSPI(uint8_t channel);
202 
213 HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
214  int16_t version);
215 } // namespace hal
hal::HAL_HandleEnum
HAL_HandleEnum
Enum of HAL handle types.
Definition: HandlesInternal.h:47
hal::getHandleIndex
static int16_t getHandleIndex(HAL_Handle handle)
Get the handle index from a handle.
Definition: HandlesInternal.h:80
hal::createPortHandle
HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module)
Create a port handle.
hal
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: UnsafeDIO.h:15
hal::isHandleCorrectVersion
static bool isHandleCorrectVersion(HAL_Handle handle, int16_t version)
Get if the version of the handle is correct.
Definition: HandlesInternal.h:116
hal::getHandleType
static HAL_HandleEnum getHandleType(HAL_Handle handle)
Get the handle type from a handle.
Definition: HandlesInternal.h:91
hal::getPortHandleChannel
static int16_t getPortHandleChannel(HAL_PortHandle handle)
Gets the port channel of a port handle.
Definition: HandlesInternal.h:157
hal::getPortHandleModule
static int16_t getPortHandleModule(HAL_PortHandle handle)
Gets the port module of a port handle.
Definition: HandlesInternal.h:169
hal::isHandleType
static bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType)
Get if the handle is a specific type.
Definition: HandlesInternal.h:103
hal::getHandleTypedIndex
static 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:131
hal::createPortHandleForSPI
HAL_PortHandle createPortHandleForSPI(uint8_t channel)
Create a port handle for SPI.
hal::getPortHandleSPIEnable
static int16_t getPortHandleSPIEnable(HAL_PortHandle handle)
Gets the SPI channel of a port handle.
Definition: HandlesInternal.h:181
hal::HandleBase
Base for all HAL Handles.
Definition: HandlesInternal.h:29
hal::createHandle
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.