#pragma once
#include <stdint.h>
#include <wpi/Synchronization.h>
#include "hal/Types.h"
namespace hal {
class HandleBase {
public:
HandleBase();
~HandleBase();
HandleBase(const HandleBase&) = delete;
HandleBase& operator=(const HandleBase&) = delete;
virtual void ResetHandles();
static void ResetGlobalHandles();
protected:
int16_t m_version;
};
constexpr int16_t InvalidHandleIndex = -1;
enum class HAL_HandleEnum {
Undefined = 0,
DIO = wpi::kHandleTypeHALBase,
Port = 2,
Notifier = 3,
Interrupt = 4,
AnalogOutput = 5,
AnalogInput = 6,
AnalogTrigger = 7,
Relay = 8,
PWM = 9,
DigitalPWM = 10,
Counter = 11,
FPGAEncoder = 12,
Encoder = 13,
Compressor = 14,
Solenoid = 15,
AnalogGyro = 16,
Vendor = 17,
SimulationJni = 18,
CAN = 19,
SerialPort = 20,
DutyCycle = 21,
DMA = 22,
AddressableLED = 23,
CTREPCM = 24,
CTREPDP = 25,
REVPDH = 26,
REVPH = 27,
};
static inline int16_t getHandleIndex(HAL_Handle handle) {
return static_cast<int16_t>(handle & 0xffff);
}
static inline HAL_HandleEnum getHandleType(HAL_Handle handle) {
return static_cast<HAL_HandleEnum>((handle >> 24) & 0xff);
}
static inline bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType) {
return handleType == getHandleType(handle);
}
static inline bool isHandleCorrectVersion(HAL_Handle handle, int16_t version) {
return (((handle & 0xFF0000) >> 16) & version) == version;
}
inline int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType,
int16_t version) {
if (!isHandleType(handle, enumType)) {
return InvalidHandleIndex;
}
#if !defined(__FRC_ROBORIO__)
if (!isHandleCorrectVersion(handle, version)) {
return InvalidHandleIndex;
}
#endif
return getHandleIndex(handle);
}
inline int16_t getPortHandleChannel(HAL_PortHandle handle) {
if (!isHandleType(handle, HAL_HandleEnum::Port)) {
return InvalidHandleIndex;
}
return static_cast<uint8_t>(handle & 0xff);
}
inline int16_t getPortHandleModule(HAL_PortHandle handle) {
if (!isHandleType(handle, HAL_HandleEnum::Port)) {
return InvalidHandleIndex;
}
return static_cast<uint8_t>((handle >> 8) & 0xff);
}
inline int16_t getPortHandleSPIEnable(HAL_PortHandle handle) {
if (!isHandleType(handle, HAL_HandleEnum::Port)) {
return InvalidHandleIndex;
}
return static_cast<uint8_t>((handle >> 16) & 0xff);
}
HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module);
HAL_PortHandle createPortHandleForSPI(uint8_t channel);
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
int16_t version);
}