mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-02 02:51:42 +00:00
[hal] Add a unified PCM object (#3331)
This commit is contained in:
394
hal/src/main/native/athena/CTREPCM.cpp
Normal file
394
hal/src/main/native/athena/CTREPCM.cpp
Normal file
@@ -0,0 +1,394 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "hal/CTREPCM.h"
|
||||
|
||||
#include "HALInitializer.h"
|
||||
#include "HALInternal.h"
|
||||
#include "PortsInternal.h"
|
||||
#include "hal/CANAPI.h"
|
||||
#include "hal/Errors.h"
|
||||
#include "hal/handles/IndexedHandleResource.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
static constexpr HAL_CANManufacturer manufacturer =
|
||||
HAL_CANManufacturer::HAL_CAN_Man_kCTRE;
|
||||
|
||||
static constexpr HAL_CANDeviceType deviceType =
|
||||
HAL_CANDeviceType::HAL_CAN_Dev_kPneumatics;
|
||||
|
||||
static constexpr int32_t Status1 = 0x50;
|
||||
static constexpr int32_t StatusSolFaults = 0x51;
|
||||
static constexpr int32_t StatusDebug = 0x52;
|
||||
|
||||
static constexpr int32_t Control1 = 0x70;
|
||||
static constexpr int32_t Control2 = 0x71;
|
||||
static constexpr int32_t Control3 = 0x72;
|
||||
|
||||
static constexpr int32_t TimeoutMs = 100;
|
||||
static constexpr int32_t SendPeriod = 20;
|
||||
|
||||
union PcmStatus {
|
||||
uint8_t data[8];
|
||||
struct Bits {
|
||||
/* Byte 0 */
|
||||
unsigned SolenoidBits : 8;
|
||||
/* Byte 1 */
|
||||
unsigned compressorOn : 1;
|
||||
unsigned stickyFaultFuseTripped : 1;
|
||||
unsigned stickyFaultCompCurrentTooHigh : 1;
|
||||
unsigned faultFuseTripped : 1;
|
||||
unsigned faultCompCurrentTooHigh : 1;
|
||||
unsigned faultHardwareFailure : 1;
|
||||
unsigned isCloseloopEnabled : 1;
|
||||
unsigned pressureSwitchEn : 1;
|
||||
/* Byte 2*/
|
||||
unsigned battVoltage : 8;
|
||||
/* Byte 3 */
|
||||
unsigned solenoidVoltageTop8 : 8;
|
||||
/* Byte 4 */
|
||||
unsigned compressorCurrentTop6 : 6;
|
||||
unsigned solenoidVoltageBtm2 : 2;
|
||||
/* Byte 5 */
|
||||
unsigned StickyFault_dItooHigh : 1;
|
||||
unsigned Fault_dItooHigh : 1;
|
||||
unsigned moduleEnabled : 1;
|
||||
unsigned closedLoopOutput : 1;
|
||||
unsigned compressorCurrentBtm4 : 4;
|
||||
/* Byte 6 */
|
||||
unsigned tokenSeedTop8 : 8;
|
||||
/* Byte 7 */
|
||||
unsigned tokenSeedBtm8 : 8;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union PcmControl {
|
||||
uint8_t data[8];
|
||||
struct Bits {
|
||||
/* Byte 0 */
|
||||
unsigned tokenTop8 : 8;
|
||||
/* Byte 1 */
|
||||
unsigned tokenBtm8 : 8;
|
||||
/* Byte 2 */
|
||||
unsigned solenoidBits : 8;
|
||||
/* Byte 3*/
|
||||
unsigned reserved : 4;
|
||||
unsigned closeLoopOutput : 1;
|
||||
unsigned compressorOn : 1;
|
||||
unsigned closedLoopEnable : 1;
|
||||
unsigned clearStickyFaults : 1;
|
||||
/* Byte 4 */
|
||||
unsigned OneShotField_h8 : 8;
|
||||
/* Byte 5 */
|
||||
unsigned OneShotField_l8 : 8;
|
||||
} bits;
|
||||
};
|
||||
|
||||
struct PcmControlSetOneShotDur {
|
||||
uint8_t sol10MsPerUnit[8];
|
||||
};
|
||||
|
||||
union PcmStatusFault {
|
||||
uint8_t data[8];
|
||||
struct Bits {
|
||||
/* Byte 0 */
|
||||
unsigned SolenoidDisabledList : 8;
|
||||
/* Byte 1 */
|
||||
unsigned reserved_bit0 : 1;
|
||||
unsigned reserved_bit1 : 1;
|
||||
unsigned reserved_bit2 : 1;
|
||||
unsigned reserved_bit3 : 1;
|
||||
unsigned StickyFault_CompNoCurrent : 1;
|
||||
unsigned Fault_CompNoCurrent : 1;
|
||||
unsigned StickyFault_SolenoidJumper : 1;
|
||||
unsigned Fault_SolenoidJumper : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union PcmDebug {
|
||||
uint8_t data[8];
|
||||
struct Bits {
|
||||
unsigned tokFailsTop8 : 8;
|
||||
unsigned tokFailsBtm8 : 8;
|
||||
unsigned lastFailedTokTop8 : 8;
|
||||
unsigned lastFailedTokBtm8 : 8;
|
||||
unsigned tokSuccessTop8 : 8;
|
||||
unsigned tokSuccessBtm8 : 8;
|
||||
} bits;
|
||||
};
|
||||
|
||||
namespace {
|
||||
struct PCM {
|
||||
HAL_CANHandle canHandle;
|
||||
wpi::mutex lock;
|
||||
std::string previousAllocation;
|
||||
PcmControl control;
|
||||
PcmControlSetOneShotDur oneShot;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static IndexedHandleResource<HAL_CTREPCMHandle, PCM, kNumCTREPCMModules,
|
||||
HAL_HandleEnum::CTREPCM>* pcmHandles;
|
||||
|
||||
namespace hal::init {
|
||||
void InitializeCTREPCM() {
|
||||
static IndexedHandleResource<HAL_CTREPCMHandle, PCM, kNumCTREPCMModules,
|
||||
HAL_HandleEnum::CTREPCM>
|
||||
pH;
|
||||
pcmHandles = &pH;
|
||||
}
|
||||
} // namespace hal::init
|
||||
|
||||
#define READ_PACKET(type, frame, failureValue) \
|
||||
auto pcm = pcmHandles->Get(handle); \
|
||||
if (pcm == nullptr) { \
|
||||
*status = HAL_HANDLE_ERROR; \
|
||||
return failureValue; \
|
||||
} \
|
||||
type pcmStatus; \
|
||||
int32_t length = 0; \
|
||||
uint64_t receivedTimestamp = 0; \
|
||||
HAL_ReadCANPacketTimeout(pcm->canHandle, frame, pcmStatus.data, &length, \
|
||||
&receivedTimestamp, TimeoutMs, status); \
|
||||
if (*status != 0) { \
|
||||
return failureValue; \
|
||||
}
|
||||
|
||||
#define READ_STATUS(failureValue) READ_PACKET(PcmStatus, Status1, failureValue)
|
||||
#define READ_SOL_FAULTS(failureValue) \
|
||||
READ_PACKET(PcmStatusFault, StatusSolFaults, failureValue)
|
||||
|
||||
static void SendControl(PCM* pcm, int32_t* status) {
|
||||
HAL_WriteCANPacketRepeating(pcm->canHandle, pcm->control.data, 8, Control1,
|
||||
SendPeriod, status);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_CTREPCMHandle HAL_InitializeCTREPCM(int32_t module,
|
||||
const char* allocationLocation,
|
||||
int32_t* status) {
|
||||
hal::init::CheckInit();
|
||||
|
||||
HAL_CTREPCMHandle handle;
|
||||
auto pcm = pcmHandles->Allocate(module, &handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
if (pcm) {
|
||||
hal::SetLastErrorPreviouslyAllocated(status, "CTRE PCM", module,
|
||||
pcm->previousAllocation);
|
||||
} else {
|
||||
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for CTRE PCM", 0,
|
||||
kNumAccumulators, module);
|
||||
}
|
||||
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
|
||||
}
|
||||
|
||||
pcm->canHandle = HAL_InitializeCAN(manufacturer, module, deviceType, status);
|
||||
if (*status != 0) {
|
||||
pcmHandles->Free(handle);
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
std::memset(&pcm->oneShot, 0, sizeof(pcm->oneShot));
|
||||
std::memset(&pcm->control, 0, sizeof(pcm->control));
|
||||
|
||||
pcm->previousAllocation = allocationLocation ? allocationLocation : "";
|
||||
|
||||
// Enable closed loop control
|
||||
HAL_SetCTREPCMClosedLoopControl(handle, true, status);
|
||||
if (*status != 0) {
|
||||
HAL_FreeCTREPCM(handle);
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void HAL_FreeCTREPCM(HAL_CTREPCMHandle handle) {
|
||||
auto pcm = pcmHandles->Get(handle);
|
||||
if (pcm) {
|
||||
HAL_CleanCAN(pcm->canHandle);
|
||||
}
|
||||
pcmHandles->Free(handle);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckCTREPCMSolenoidChannel(int32_t channel) {
|
||||
return channel < kNumCTRESolenoidChannels && channel >= 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMCompressor(HAL_CTREPCMHandle handle, int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.compressorOn;
|
||||
}
|
||||
|
||||
void HAL_SetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle, HAL_Bool enabled,
|
||||
int32_t* status) {
|
||||
auto pcm = pcmHandles->Get(handle);
|
||||
if (pcm == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock lock{pcm->lock};
|
||||
pcm->control.bits.closedLoopEnable = enabled ? 1 : 0;
|
||||
SendControl(pcm.get(), status);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.isCloseloopEnabled;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMPressureSwitch(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.pressureSwitchEn;
|
||||
}
|
||||
|
||||
double HAL_GetCTREPCMCompressorCurrent(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(0);
|
||||
uint32_t result = pcmStatus.bits.compressorCurrentTop6;
|
||||
result <<= 4;
|
||||
result |= pcmStatus.bits.compressorCurrentBtm4;
|
||||
return result * 0.03125; /* 5.5 fixed pt value in Amps */
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighFault(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.faultCompCurrentTooHigh;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighStickyFault(
|
||||
HAL_CTREPCMHandle handle, int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.stickyFaultCompCurrentTooHigh;
|
||||
}
|
||||
HAL_Bool HAL_GetCTREPCMCompressorShortedStickyFault(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.Fault_dItooHigh;
|
||||
}
|
||||
HAL_Bool HAL_GetCTREPCMCompressorShortedFault(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.StickyFault_dItooHigh;
|
||||
}
|
||||
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedStickyFault(
|
||||
HAL_CTREPCMHandle handle, int32_t* status) {
|
||||
READ_SOL_FAULTS(false);
|
||||
return pcmStatus.bits.StickyFault_CompNoCurrent;
|
||||
}
|
||||
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedFault(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_SOL_FAULTS(false);
|
||||
return pcmStatus.bits.Fault_CompNoCurrent;
|
||||
}
|
||||
|
||||
int32_t HAL_GetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t* status) {
|
||||
READ_STATUS(0);
|
||||
return pcmStatus.bits.SolenoidBits & 0xFF;
|
||||
}
|
||||
|
||||
void HAL_SetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t mask,
|
||||
int32_t values, int32_t* status) {
|
||||
auto pcm = pcmHandles->Get(handle);
|
||||
if (pcm == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t smallMask = mask & 0xFF;
|
||||
uint8_t smallValues =
|
||||
(values & 0xFF) & smallMask; // Enforce only masked values are set
|
||||
uint8_t invertMask = ~smallMask;
|
||||
|
||||
std::scoped_lock lock{pcm->lock};
|
||||
uint8_t existingValue = invertMask & pcm->control.bits.solenoidBits;
|
||||
pcm->control.bits.solenoidBits = existingValue | smallValues;
|
||||
SendControl(pcm.get(), status);
|
||||
}
|
||||
|
||||
int32_t HAL_GetCTREPCMSolenoidDisabledList(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_SOL_FAULTS(0);
|
||||
return pcmStatus.bits.SolenoidDisabledList;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMSolenoidVoltageStickyFault(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.stickyFaultFuseTripped;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCTREPCMSolenoidVoltageFault(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
READ_STATUS(false);
|
||||
return pcmStatus.bits.faultFuseTripped;
|
||||
}
|
||||
|
||||
void HAL_ClearAllCTREPCMStickyFaults(HAL_CTREPCMHandle handle,
|
||||
int32_t* status) {
|
||||
uint8_t controlData[] = {0, 0, 0, 0x80};
|
||||
HAL_WriteCANPacket(handle, controlData, sizeof(controlData), Control2,
|
||||
status);
|
||||
}
|
||||
|
||||
void HAL_FireCTREPCMOneShot(HAL_CTREPCMHandle handle, int32_t index,
|
||||
int32_t* status) {
|
||||
if (index > 7 || index < 0) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
hal::SetLastError(status, "Only [0-7] are valid index values. Requested " +
|
||||
wpi::Twine(index));
|
||||
return;
|
||||
}
|
||||
|
||||
auto pcm = pcmHandles->Get(handle);
|
||||
if (pcm == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock lock{pcm->lock};
|
||||
uint16_t oneShotField = pcm->control.bits.OneShotField_h8;
|
||||
oneShotField <<= 8;
|
||||
oneShotField |= pcm->control.bits.OneShotField_l8;
|
||||
|
||||
uint16_t shift = 2 * index;
|
||||
uint16_t mask = 3;
|
||||
uint8_t chBits = (oneShotField >> shift) & mask;
|
||||
chBits = (chBits % 3) + 1;
|
||||
oneShotField &= ~(mask << shift);
|
||||
oneShotField |= (chBits << shift);
|
||||
pcm->control.bits.OneShotField_h8 = oneShotField >> 8;
|
||||
pcm->control.bits.OneShotField_l8 = oneShotField;
|
||||
SendControl(pcm.get(), status);
|
||||
}
|
||||
|
||||
void HAL_SetCTREPCMOneShotDuration(HAL_CTREPCMHandle handle, int32_t index,
|
||||
int32_t durMs, int32_t* status) {
|
||||
if (index > 7 || index < 0) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
hal::SetLastError(status, "Only [0-7] are valid index values. Requested " +
|
||||
wpi::Twine(index));
|
||||
return;
|
||||
}
|
||||
|
||||
auto pcm = pcmHandles->Get(handle);
|
||||
if (pcm == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock lock{pcm->lock};
|
||||
pcm->oneShot.sol10MsPerUnit[index] = (std::min)(
|
||||
static_cast<uint32_t>(durMs) / 10, static_cast<uint32_t>(0xFF));
|
||||
HAL_WriteCANPacketRepeating(pcm->canHandle, pcm->oneShot.sol10MsPerUnit, 8,
|
||||
Control2, SendPeriod, status);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -1,197 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "hal/Compressor.h"
|
||||
|
||||
#include "HALInitializer.h"
|
||||
#include "PCMInternal.h"
|
||||
#include "PortsInternal.h"
|
||||
#include "ctre/PCM.h"
|
||||
#include "hal/Errors.h"
|
||||
#include "hal/handles/HandlesInternal.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal::init {
|
||||
void InitializeCompressor() {}
|
||||
} // namespace hal::init
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
|
||||
hal::init::CheckInit();
|
||||
// Use status to check for invalid index
|
||||
initializePCM(module, status);
|
||||
if (*status != 0) {
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
// As compressors can have unlimited objects, just create a
|
||||
// handle with the module number as the index.
|
||||
|
||||
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
|
||||
HAL_HandleEnum::Compressor, 0);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
|
||||
return module < kNumPCMModules && module >= 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressor(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
|
||||
HAL_Bool value, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
*status = PCM_modules[index]->SetClosedLoopControl(value);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressorClosedLoopControl(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetClosedLoopControl(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetPressure(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
float value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorCurrent(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorCurrentTooHighFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorCurrentTooHighStickyFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorShortedStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorShortedStickyFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
|
||||
int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorShortedFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorNotConnectedStickyFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetCompressorNotConnectedFault(
|
||||
HAL_CompressorHandle compressorHandle, int32_t* status) {
|
||||
int16_t index =
|
||||
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
|
||||
if (index == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[index]->GetCompressorNotConnectedFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "HALInitializer.h"
|
||||
#include "HALInternal.h"
|
||||
#include "ctre/ctre.h"
|
||||
#include "hal/ChipObject.h"
|
||||
#include "hal/DriverStation.h"
|
||||
#include "hal/Errors.h"
|
||||
@@ -40,6 +39,7 @@ using namespace hal;
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeHAL() {
|
||||
InitializeCTREPCM();
|
||||
InitializeAddressableLED();
|
||||
InitializeAccelerometer();
|
||||
InitializeAnalogAccumulator();
|
||||
@@ -50,7 +50,6 @@ void InitializeHAL() {
|
||||
InitializeAnalogTrigger();
|
||||
InitializeCAN();
|
||||
InitializeCANAPI();
|
||||
InitializeCompressor();
|
||||
InitializeConstants();
|
||||
InitializeCounter();
|
||||
InitializeDigitalInternal();
|
||||
@@ -64,14 +63,12 @@ void InitializeHAL() {
|
||||
InitializeInterrupts();
|
||||
InitializeMain();
|
||||
InitializeNotifier();
|
||||
InitializePCMInternal();
|
||||
InitializePDP();
|
||||
InitializePorts();
|
||||
InitializePower();
|
||||
InitializePWM();
|
||||
InitializeRelay();
|
||||
InitializeSerialPort();
|
||||
InitializeSolenoid();
|
||||
InitializeSPI();
|
||||
InitializeThreads();
|
||||
}
|
||||
@@ -113,18 +110,6 @@ const char* HAL_GetErrorMessage(int32_t code) {
|
||||
switch (code) {
|
||||
case 0:
|
||||
return "";
|
||||
case CTR_RxTimeout:
|
||||
return CTR_RxTimeout_MESSAGE;
|
||||
case CTR_TxTimeout:
|
||||
return CTR_TxTimeout_MESSAGE;
|
||||
case CTR_InvalidParamValue:
|
||||
return CTR_InvalidParamValue_MESSAGE;
|
||||
case CTR_UnexpectedArbId:
|
||||
return CTR_UnexpectedArbId_MESSAGE;
|
||||
case CTR_TxFailed:
|
||||
return CTR_TxFailed_MESSAGE;
|
||||
case CTR_SigNotUpdated:
|
||||
return CTR_SigNotUpdated_MESSAGE;
|
||||
case NiFpga_Status_FifoTimeout:
|
||||
return NiFpga_Status_FifoTimeout_MESSAGE;
|
||||
case NiFpga_Status_TransferAborted:
|
||||
|
||||
@@ -16,6 +16,7 @@ inline void CheckInit() {
|
||||
RunInitialize();
|
||||
}
|
||||
|
||||
extern void InitializeCTREPCM();
|
||||
extern void InitializeAccelerometer();
|
||||
extern void InitializeAddressableLED();
|
||||
extern void InitializeAnalogAccumulator();
|
||||
@@ -26,7 +27,6 @@ extern void InitializeAnalogOutput();
|
||||
extern void InitializeAnalogTrigger();
|
||||
extern void InitializeCAN();
|
||||
extern void InitializeCANAPI();
|
||||
extern void InitializeCompressor();
|
||||
extern void InitializeConstants();
|
||||
extern void InitializeCounter();
|
||||
extern void InitializeDigitalInternal();
|
||||
@@ -41,14 +41,12 @@ extern void InitializeI2C();
|
||||
extern void InitializeInterrupts();
|
||||
extern void InitializeMain();
|
||||
extern void InitializeNotifier();
|
||||
extern void InitializePCMInternal();
|
||||
extern void InitializePDP();
|
||||
extern void InitializePorts();
|
||||
extern void InitializePower();
|
||||
extern void InitializePWM();
|
||||
extern void InitializeRelay();
|
||||
extern void InitializeSerialPort();
|
||||
extern void InitializeSolenoid();
|
||||
extern void InitializeSPI();
|
||||
extern void InitializeThreads();
|
||||
} // namespace hal::init
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "PCMInternal.h"
|
||||
|
||||
#include "HALInitializer.h"
|
||||
#include "hal/Errors.h"
|
||||
#include "hal/Solenoid.h"
|
||||
|
||||
namespace hal {
|
||||
|
||||
std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
|
||||
|
||||
namespace init {
|
||||
void InitializePCMInternal() {
|
||||
for (int i = 0; i < kNumPCMModules; i++) {
|
||||
PCM_modules[i] = nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace init
|
||||
|
||||
void initializePCM(int32_t module, int32_t* status) {
|
||||
hal::init::CheckInit();
|
||||
if (!HAL_CheckSolenoidModule(module)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
if (!PCM_modules[module]) {
|
||||
PCM_modules[module] = std::make_unique<PCM>(module);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace hal
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "PortsInternal.h"
|
||||
#include "ctre/PCM.h"
|
||||
#include "hal/Errors.h"
|
||||
#include "hal/Solenoid.h"
|
||||
|
||||
namespace hal {
|
||||
|
||||
extern std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
|
||||
|
||||
static inline bool checkPCMInit(int32_t module, int32_t* status) {
|
||||
if (!HAL_CheckSolenoidModule(module)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
if (!PCM_modules[module]) {
|
||||
*status = INCOMPATIBLE_STATE;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void initializePCM(int32_t module, int32_t* status);
|
||||
|
||||
} // namespace hal
|
||||
@@ -56,11 +56,11 @@ int32_t HAL_GetNumRelayChannels(void) {
|
||||
int32_t HAL_GetNumRelayHeaders(void) {
|
||||
return kNumRelayHeaders;
|
||||
}
|
||||
int32_t HAL_GetNumPCMModules(void) {
|
||||
return kNumPCMModules;
|
||||
int32_t HAL_GetNumCTREPCMModules(void) {
|
||||
return kNumCTREPCMModules;
|
||||
}
|
||||
int32_t HAL_GetNumSolenoidChannels(void) {
|
||||
return kNumSolenoidChannels;
|
||||
return kNumCTRESolenoidChannels;
|
||||
}
|
||||
int32_t HAL_GetNumPDPModules(void) {
|
||||
return kNumPDPModules;
|
||||
|
||||
@@ -28,8 +28,8 @@ constexpr int32_t kNumEncoders = tEncoder::kNumSystems;
|
||||
constexpr int32_t kNumInterrupts = tInterrupt::kNumSystems;
|
||||
constexpr int32_t kNumRelayChannels = 8;
|
||||
constexpr int32_t kNumRelayHeaders = kNumRelayChannels / 2;
|
||||
constexpr int32_t kNumPCMModules = 63;
|
||||
constexpr int32_t kNumSolenoidChannels = 8;
|
||||
constexpr int32_t kNumCTREPCMModules = 63;
|
||||
constexpr int32_t kNumCTRESolenoidChannels = 8;
|
||||
constexpr int32_t kNumPDPModules = 63;
|
||||
constexpr int32_t kNumPDPChannels = 16;
|
||||
constexpr int32_t kNumDutyCycles = tDutyCycle::kNumSystems;
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "hal/Solenoid.h"
|
||||
|
||||
#include "HALInitializer.h"
|
||||
#include "PCMInternal.h"
|
||||
#include "PortsInternal.h"
|
||||
#include "ctre/PCM.h"
|
||||
#include "hal/Errors.h"
|
||||
#include "hal/handles/HandlesInternal.h"
|
||||
#include "hal/handles/IndexedHandleResource.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct Solenoid {
|
||||
uint8_t module;
|
||||
uint8_t channel;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
using namespace hal;
|
||||
|
||||
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
|
||||
kNumPCMModules * kNumSolenoidChannels,
|
||||
HAL_HandleEnum::Solenoid>* solenoidHandles;
|
||||
|
||||
namespace hal::init {
|
||||
void InitializeSolenoid() {
|
||||
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
|
||||
kNumPCMModules * kNumSolenoidChannels,
|
||||
HAL_HandleEnum::Solenoid>
|
||||
sH;
|
||||
solenoidHandles = &sH;
|
||||
}
|
||||
} // namespace hal::init
|
||||
|
||||
extern "C" {
|
||||
|
||||
HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
|
||||
int32_t* status) {
|
||||
hal::init::CheckInit();
|
||||
int16_t channel = getPortHandleChannel(portHandle);
|
||||
int16_t module = getPortHandleModule(portHandle);
|
||||
if (channel == InvalidHandleIndex) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
// initializePCM will check the module
|
||||
if (!HAL_CheckSolenoidChannel(channel)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
initializePCM(module, status);
|
||||
if (*status != 0) {
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
HAL_SolenoidHandle handle;
|
||||
auto solenoidPort = solenoidHandles->Allocate(
|
||||
module * kNumSolenoidChannels + channel, &handle, status);
|
||||
if (*status != 0) {
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
solenoidPort->module = static_cast<uint8_t>(module);
|
||||
solenoidPort->channel = static_cast<uint8_t>(channel);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
|
||||
solenoidHandles->Free(solenoidPortHandle);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
|
||||
return module < kNumPCMModules && module >= 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
|
||||
return channel < kNumSolenoidChannels && channel >= 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[port->module]->GetSolenoid(port->channel, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
|
||||
if (!checkPCMInit(module, status)) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t value;
|
||||
|
||||
*status = PCM_modules[module]->GetAllSolenoids(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
|
||||
int32_t* status) {
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
*status = PCM_modules[port->module]->SetSolenoid(port->channel, value);
|
||||
}
|
||||
|
||||
void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
|
||||
if (!checkPCMInit(module, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*status = PCM_modules[module]->SetAllSolenoids(state);
|
||||
}
|
||||
|
||||
int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
|
||||
if (!checkPCMInit(module, status)) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t value;
|
||||
|
||||
*status = PCM_modules[module]->GetSolenoidBlackList(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
|
||||
if (!checkPCMInit(module, status)) {
|
||||
return 0;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[module]->GetSolenoidStickyFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
|
||||
if (!checkPCMInit(module, status)) {
|
||||
return false;
|
||||
}
|
||||
bool value;
|
||||
|
||||
*status = PCM_modules[module]->GetSolenoidFault(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
|
||||
if (!checkPCMInit(module, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*status = PCM_modules[module]->ClearStickyFaults();
|
||||
}
|
||||
|
||||
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
|
||||
int32_t durMS, int32_t* status) {
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
*status =
|
||||
PCM_modules[port->module]->SetOneShotDurationMs(port->channel, durMS);
|
||||
}
|
||||
|
||||
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {
|
||||
auto port = solenoidHandles->Get(solenoidPortHandle);
|
||||
if (port == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
*status = PCM_modules[port->module]->FireOneShotSolenoid(port->channel);
|
||||
}
|
||||
} // extern "C"
|
||||
@@ -1,157 +0,0 @@
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
|
||||
#include "CtreCanNode.h"
|
||||
#include "FRC_NetworkCommunication/CANSessionMux.h"
|
||||
#include <string.h> // memset
|
||||
|
||||
static const UINT32 kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
|
||||
{
|
||||
_deviceNumber = deviceNumber;
|
||||
}
|
||||
CtreCanNode::~CtreCanNode()
|
||||
{
|
||||
}
|
||||
void CtreCanNode::RegisterRx(uint32_t arbId)
|
||||
{
|
||||
/* no need to do anything, we just use new API to poll last received message */
|
||||
}
|
||||
/**
|
||||
* Schedule a CAN Frame for periodic transmit.
|
||||
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
|
||||
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
|
||||
* @param dlc Number of bytes to transmit (0 to 8).
|
||||
* @param initialFrame Ptr to the frame data to schedule for transmitting. Passing null will result
|
||||
* in defaulting to zero data value.
|
||||
*/
|
||||
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs, uint32_t dlc, const uint8_t * initialFrame)
|
||||
{
|
||||
int32_t status = 0;
|
||||
if(dlc > 8)
|
||||
dlc = 8;
|
||||
txJob_t job = {0};
|
||||
job.arbId = arbId;
|
||||
job.periodMs = periodMs;
|
||||
job.dlc = dlc;
|
||||
if(initialFrame){
|
||||
/* caller wants to specify original data */
|
||||
memcpy(job.toSend, initialFrame, dlc);
|
||||
}
|
||||
_txJobs[arbId] = job;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
|
||||
job.toSend,
|
||||
job.dlc,
|
||||
job.periodMs,
|
||||
&status);
|
||||
}
|
||||
/**
|
||||
* Schedule a CAN Frame for periodic transmit. Assume eight byte DLC and zero value for initial transmission.
|
||||
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
|
||||
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
|
||||
*/
|
||||
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
|
||||
{
|
||||
RegisterTx(arbId,periodMs, 8, 0);
|
||||
}
|
||||
/**
|
||||
* Remove a CAN frame Arbid to stop transmission.
|
||||
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
|
||||
*/
|
||||
void CtreCanNode::UnregisterTx(uint32_t arbId)
|
||||
{
|
||||
/* set period to zero */
|
||||
ChangeTxPeriod(arbId, 0);
|
||||
/* look and remove */
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end()) {
|
||||
_txJobs.erase(iter);
|
||||
}
|
||||
}
|
||||
static int64_t GetTimeMs() {
|
||||
std::chrono::time_point < std::chrono::system_clock > now;
|
||||
now = std::chrono::system_clock::now();
|
||||
auto duration = now.time_since_epoch();
|
||||
auto millis = std::chrono::duration_cast < std::chrono::milliseconds
|
||||
> (duration).count();
|
||||
return (int64_t) millis;
|
||||
}
|
||||
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
|
||||
{
|
||||
CTR_Code retval = CTR_OKAY;
|
||||
int32_t status = 0;
|
||||
uint8_t len = 0;
|
||||
uint32_t timeStamp;
|
||||
/* cap timeout at 999ms */
|
||||
if(timeoutMs > 999)
|
||||
timeoutMs = 999;
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
|
||||
std::scoped_lock lock(_lck);
|
||||
if(status == 0){
|
||||
/* fresh update */
|
||||
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
|
||||
r.time = GetTimeMs();
|
||||
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
|
||||
}else{
|
||||
/* did not get the message */
|
||||
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
|
||||
if(i == _rxRxEvents.end()){
|
||||
/* we've never gotten this mesage */
|
||||
retval = CTR_RxTimeout;
|
||||
/* fill caller's buffer with zeros */
|
||||
memset(dataBytes,0,8);
|
||||
}else{
|
||||
/* we've gotten this message before but not recently */
|
||||
memcpy(dataBytes,i->second.bytes,8);
|
||||
/* get the time now */
|
||||
int64_t now = GetTimeMs(); /* get now */
|
||||
/* how long has it been? */
|
||||
int64_t temp = now - i->second.time; /* temp = now - last */
|
||||
if (temp > ((int64_t) timeoutMs)) {
|
||||
retval = CTR_RxTimeout;
|
||||
} else {
|
||||
/* our last update was recent enough */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void CtreCanNode::FlushTx(uint32_t arbId)
|
||||
{
|
||||
int32_t status = 0;
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end())
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
|
||||
iter->second.toSend,
|
||||
iter->second.dlc,
|
||||
iter->second.periodMs,
|
||||
&status);
|
||||
}
|
||||
/**
|
||||
* Change the transmit period of an already scheduled CAN frame.
|
||||
* This keeps the frame payload contents the same without caller having to perform
|
||||
* a read-modify-write.
|
||||
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
|
||||
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
|
||||
* @return true if scheduled job was found and updated, false if there was no preceding job for the specified arbID.
|
||||
*/
|
||||
bool CtreCanNode::ChangeTxPeriod(uint32_t arbId, uint32_t periodMs)
|
||||
{
|
||||
int32_t status = 0;
|
||||
/* lookup the data bytes and period for this message */
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end()) {
|
||||
/* modify th periodMs */
|
||||
iter->second.periodMs = periodMs;
|
||||
/* reinsert into scheduler with the same data bytes, only the period changed. */
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
|
||||
iter->second.toSend,
|
||||
iter->second.dlc,
|
||||
iter->second.periodMs,
|
||||
&status);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include <map>
|
||||
#include <wpi/mutex.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
/**
|
||||
* Schedule a CAN Frame for periodic transmit. Assume eight byte DLC and zero value for initial transmission.
|
||||
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
|
||||
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
|
||||
*/
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
/**
|
||||
* Schedule a CAN Frame for periodic transmit.
|
||||
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
|
||||
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
|
||||
* @param dlc Number of bytes to transmit (0 to 8).
|
||||
* @param initialFrame Ptr to the frame data to schedule for transmitting. Passing null will result
|
||||
* in defaulting to zero data value.
|
||||
*/
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs, uint32_t dlc, const uint8_t * initialFrame);
|
||||
void UnregisterTx(uint32_t arbId);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
bool ChangeTxPeriod(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0, nullptr};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
uint8_t dlc;
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
int64_t time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
|
||||
wpi::mutex _lck;
|
||||
};
|
||||
#endif
|
||||
@@ -1,573 +0,0 @@
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
|
||||
#include "PCM.h"
|
||||
#include "FRC_NetworkCommunication/CANSessionMux.h"
|
||||
/* This can be a constant, as long as nobody needs to update solenoids within
|
||||
1/50 of a second. */
|
||||
static const INT32 kCANPeriod = 20;
|
||||
|
||||
#define STATUS_1 0x9041400
|
||||
#define STATUS_SOL_FAULTS 0x9041440
|
||||
#define STATUS_DEBUG 0x9041480
|
||||
|
||||
#define EXPECTED_RESPONSE_TIMEOUT_MS (50)
|
||||
#define GET_PCM_STATUS() CtreCanNode::recMsg<PcmStatus_t> rx = GetRx<PcmStatus_t> (STATUS_1|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_PCM_SOL_FAULTS() CtreCanNode::recMsg<PcmStatusFault_t> rx = GetRx<PcmStatusFault_t> (STATUS_SOL_FAULTS|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_PCM_DEBUG() CtreCanNode::recMsg<PcmDebug_t> rx = GetRx<PcmDebug_t> (STATUS_DEBUG|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
|
||||
#define CONTROL_1 0x09041C00 /* PCM_Control */
|
||||
#define CONTROL_2 0x09041C40 /* PCM_SupplemControl */
|
||||
#define CONTROL_3 0x09041C80 /* PcmControlSetOneShotDur_t */
|
||||
|
||||
/* encoder/decoders */
|
||||
typedef struct _PcmStatus_t{
|
||||
/* Byte 0 */
|
||||
unsigned SolenoidBits:8;
|
||||
/* Byte 1 */
|
||||
unsigned compressorOn:1;
|
||||
unsigned stickyFaultFuseTripped:1;
|
||||
unsigned stickyFaultCompCurrentTooHigh:1;
|
||||
unsigned faultFuseTripped:1;
|
||||
unsigned faultCompCurrentTooHigh:1;
|
||||
unsigned faultHardwareFailure:1;
|
||||
unsigned isCloseloopEnabled:1;
|
||||
unsigned pressureSwitchEn:1;
|
||||
/* Byte 2*/
|
||||
unsigned battVoltage:8;
|
||||
/* Byte 3 */
|
||||
unsigned solenoidVoltageTop8:8;
|
||||
/* Byte 4 */
|
||||
unsigned compressorCurrentTop6:6;
|
||||
unsigned solenoidVoltageBtm2:2;
|
||||
/* Byte 5 */
|
||||
unsigned StickyFault_dItooHigh :1;
|
||||
unsigned Fault_dItooHigh :1;
|
||||
unsigned moduleEnabled:1;
|
||||
unsigned closedLoopOutput:1;
|
||||
unsigned compressorCurrentBtm4:4;
|
||||
/* Byte 6 */
|
||||
unsigned tokenSeedTop8:8;
|
||||
/* Byte 7 */
|
||||
unsigned tokenSeedBtm8:8;
|
||||
}PcmStatus_t;
|
||||
|
||||
typedef struct _PcmControl_t{
|
||||
/* Byte 0 */
|
||||
unsigned tokenTop8:8;
|
||||
/* Byte 1 */
|
||||
unsigned tokenBtm8:8;
|
||||
/* Byte 2 */
|
||||
unsigned solenoidBits:8;
|
||||
/* Byte 3*/
|
||||
unsigned reserved:4;
|
||||
unsigned closeLoopOutput:1;
|
||||
unsigned compressorOn:1;
|
||||
unsigned closedLoopEnable:1;
|
||||
unsigned clearStickyFaults:1;
|
||||
/* Byte 4 */
|
||||
unsigned OneShotField_h8:8;
|
||||
/* Byte 5 */
|
||||
unsigned OneShotField_l8:8;
|
||||
}PcmControl_t;
|
||||
|
||||
typedef struct _PcmControlSetOneShotDur_t{
|
||||
uint8_t sol10MsPerUnit[8];
|
||||
}PcmControlSetOneShotDur_t;
|
||||
|
||||
typedef struct _PcmStatusFault_t{
|
||||
/* Byte 0 */
|
||||
unsigned SolenoidBlacklist:8;
|
||||
/* Byte 1 */
|
||||
unsigned reserved_bit0 :1;
|
||||
unsigned reserved_bit1 :1;
|
||||
unsigned reserved_bit2 :1;
|
||||
unsigned reserved_bit3 :1;
|
||||
unsigned StickyFault_CompNoCurrent :1;
|
||||
unsigned Fault_CompNoCurrent :1;
|
||||
unsigned StickyFault_SolenoidJumper :1;
|
||||
unsigned Fault_SolenoidJumper :1;
|
||||
}PcmStatusFault_t;
|
||||
|
||||
typedef struct _PcmDebug_t{
|
||||
unsigned tokFailsTop8:8;
|
||||
unsigned tokFailsBtm8:8;
|
||||
unsigned lastFailedTokTop8:8;
|
||||
unsigned lastFailedTokBtm8:8;
|
||||
unsigned tokSuccessTop8:8;
|
||||
unsigned tokSuccessBtm8:8;
|
||||
}PcmDebug_t;
|
||||
|
||||
|
||||
/* PCM Constructor - Clears all vars, establishes default settings, starts PCM background process
|
||||
*
|
||||
* @Return - void
|
||||
*
|
||||
* @Param - deviceNumber - Device ID of PCM to be controlled
|
||||
*/
|
||||
PCM::PCM(UINT8 deviceNumber): CtreCanNode(deviceNumber)
|
||||
{
|
||||
RegisterRx(STATUS_1 | deviceNumber );
|
||||
RegisterRx(STATUS_SOL_FAULTS | deviceNumber );
|
||||
RegisterRx(STATUS_DEBUG | deviceNumber );
|
||||
RegisterTx(CONTROL_1 | deviceNumber, kCANPeriod);
|
||||
/* enable close loop */
|
||||
SetClosedLoopControl(1);
|
||||
}
|
||||
/* PCM D'tor
|
||||
*/
|
||||
PCM::~PCM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* Set PCM solenoid state
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoid
|
||||
*
|
||||
* @Param - idx - ID of solenoid (0-7)
|
||||
* @Param - en - Enable / Disable identified solenoid
|
||||
*/
|
||||
CTR_Code PCM::SetSolenoid(unsigned char idx, bool en)
|
||||
{
|
||||
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
|
||||
if (en)
|
||||
toFill->solenoidBits |= (1ul << (idx));
|
||||
else
|
||||
toFill->solenoidBits &= ~(1ul << (idx));
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
|
||||
/* Set all PCM solenoid states
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoids
|
||||
* @Param - state Bitfield to set all solenoids to
|
||||
*/
|
||||
CTR_Code PCM::SetAllSolenoids(UINT8 state) {
|
||||
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
|
||||
toFill->solenoidBits = state;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
|
||||
/* Clears PCM sticky faults (indicators of past faults
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoid
|
||||
*
|
||||
* @Param - clr - Clear / do not clear faults
|
||||
*/
|
||||
CTR_Code PCM::ClearStickyFaults()
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint8_t pcmSupplemControl[] = { 0, 0, 0, 0x80 }; /* only bit set is ClearStickyFaults */
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_2 | GetDeviceNumber(), pcmSupplemControl, sizeof(pcmSupplemControl), 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
|
||||
/* Enables PCM Closed Loop Control of Compressor via pressure switch
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoid
|
||||
*
|
||||
* @Param - en - Enable / Disable Closed Loop Control
|
||||
*/
|
||||
CTR_Code PCM::SetClosedLoopControl(bool en)
|
||||
{
|
||||
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
|
||||
toFill->closedLoopEnable = en;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
/* Get solenoid Blacklist status
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid [0,7] to fire one shot pulse.
|
||||
*/
|
||||
CTR_Code PCM::FireOneShotSolenoid(UINT8 idx)
|
||||
{
|
||||
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
|
||||
/* grab field as it is now */
|
||||
uint16_t oneShotField;
|
||||
oneShotField = toFill->OneShotField_h8;
|
||||
oneShotField <<= 8;
|
||||
oneShotField |= toFill->OneShotField_l8;
|
||||
/* get the caller's channel */
|
||||
uint16_t shift = 2*idx;
|
||||
uint16_t mask = 3; /* two bits wide */
|
||||
uint8_t chBits = (oneShotField >> shift) & mask;
|
||||
/* flip it */
|
||||
chBits = (chBits)%3 + 1;
|
||||
/* clear out 2bits for this channel*/
|
||||
oneShotField &= ~(mask << shift);
|
||||
/* put new field in */
|
||||
oneShotField |= chBits << shift;
|
||||
/* apply field as it is now */
|
||||
toFill->OneShotField_h8 = oneShotField >> 8;
|
||||
toFill->OneShotField_l8 = oneShotField;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
/* Configure the pulse width of a solenoid channel for one-shot pulse.
|
||||
* Preprogrammed pulsewidth is 10ms resolution and can be between 10ms and
|
||||
* 2.55s.
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid [0,7] to configure.
|
||||
* @Param - durMs - pulse width in ms.
|
||||
*/
|
||||
CTR_Code PCM::SetOneShotDurationMs(UINT8 idx,uint32_t durMs)
|
||||
{
|
||||
/* sanity check caller's param */
|
||||
if(idx > 7)
|
||||
return CTR_InvalidParamValue;
|
||||
/* get latest tx frame */
|
||||
CtreCanNode::txTask<PcmControlSetOneShotDur_t> toFill = GetTx<PcmControlSetOneShotDur_t>(CONTROL_3 | GetDeviceNumber());
|
||||
if(toFill.IsEmpty()){
|
||||
/* only send this out if caller wants to do one-shots */
|
||||
RegisterTx(CONTROL_3 | _deviceNumber, kCANPeriod);
|
||||
/* grab it */
|
||||
toFill = GetTx<PcmControlSetOneShotDur_t>(CONTROL_3 | GetDeviceNumber());
|
||||
}
|
||||
toFill->sol10MsPerUnit[idx] = std::min(durMs/10,(uint32_t)0xFF);
|
||||
/* apply the new data bytes */
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
|
||||
/* Get solenoid state
|
||||
*
|
||||
* @Return - True/False - True if solenoid enabled, false otherwise
|
||||
*
|
||||
* @Param - idx - ID of solenoid (0-7) to return status of
|
||||
*/
|
||||
CTR_Code PCM::GetSolenoid(UINT8 idx, bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = (rx->SolenoidBits & (1ul<<(idx)) ) ? 1 : 0;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get solenoid state for all solenoids on the PCM
|
||||
*
|
||||
* @Return - Bitfield of solenoid states
|
||||
*/
|
||||
CTR_Code PCM::GetAllSolenoids(UINT8 &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->SolenoidBits;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get pressure switch state
|
||||
*
|
||||
* @Return - True/False - True if pressure adequate, false if low
|
||||
*/
|
||||
CTR_Code PCM::GetPressure(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = (rx->pressureSwitchEn ) ? 1 : 0;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get compressor state
|
||||
*
|
||||
* @Return - True/False - True if enabled, false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetCompressor(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = (rx->compressorOn);
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get closed loop control state
|
||||
*
|
||||
* @Return - True/False - True if closed loop enabled, false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetClosedLoopControl(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = (rx->isCloseloopEnabled);
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get compressor current draw
|
||||
*
|
||||
* @Return - Amperes - Compressor current
|
||||
*/
|
||||
CTR_Code PCM::GetCompressorCurrent(float &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
uint32_t temp =(rx->compressorCurrentTop6);
|
||||
temp <<= 4;
|
||||
temp |= rx->compressorCurrentBtm4;
|
||||
status = temp * 0.03125; /* 5.5 fixed pt value in Amps */
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get voltage across solenoid rail
|
||||
*
|
||||
* @Return - Volts - Voltage across solenoid rail
|
||||
*/
|
||||
CTR_Code PCM::GetSolenoidVoltage(float &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
uint32_t raw =(rx->solenoidVoltageTop8);
|
||||
raw <<= 2;
|
||||
raw |= rx->solenoidVoltageBtm2;
|
||||
status = (double) raw * 0.03125; /* 5.5 fixed pt value in Volts */
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get hardware fault value
|
||||
*
|
||||
* @Return - True/False - True if hardware failure detected, false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetHardwareFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->faultHardwareFailure;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get compressor fault value
|
||||
*
|
||||
* @Return - True/False - True if shorted compressor detected, false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetCompressorCurrentTooHighFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->faultCompCurrentTooHigh;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PCM::GetCompressorShortedStickyFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->StickyFault_dItooHigh;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PCM::GetCompressorShortedFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->Fault_dItooHigh;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PCM::GetCompressorNotConnectedStickyFault(bool &status)
|
||||
{
|
||||
GET_PCM_SOL_FAULTS();
|
||||
status = rx->StickyFault_CompNoCurrent;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PCM::GetCompressorNotConnectedFault(bool &status)
|
||||
{
|
||||
GET_PCM_SOL_FAULTS();
|
||||
status = rx->Fault_CompNoCurrent;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get solenoid fault value
|
||||
*
|
||||
* @Return - True/False - True if shorted solenoid detected, false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetSolenoidFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->faultFuseTripped;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get compressor sticky fault value
|
||||
*
|
||||
* @Return - True/False - True if solenoid had previously been shorted
|
||||
* (and sticky fault was not cleared), false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetCompressorCurrentTooHighStickyFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->stickyFaultCompCurrentTooHigh;
|
||||
return rx.err;
|
||||
}
|
||||
|
||||
/* Get solenoid sticky fault value
|
||||
*
|
||||
* @Return - True/False - True if compressor had previously been shorted
|
||||
* (and sticky fault was not cleared), false if otherwise
|
||||
*/
|
||||
CTR_Code PCM::GetSolenoidStickyFault(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->stickyFaultFuseTripped;
|
||||
return rx.err;
|
||||
}
|
||||
/* Get battery voltage
|
||||
*
|
||||
* @Return - Volts - Voltage across PCM power ports
|
||||
*/
|
||||
CTR_Code PCM::GetBatteryVoltage(float &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = (float)rx->battVoltage * 0.05 + 4.0; /* 50mV per unit plus 4V. */
|
||||
return rx.err;
|
||||
}
|
||||
/* Return status of module enable/disable
|
||||
*
|
||||
* @Return - bool - Returns TRUE if PCM is enabled, FALSE if disabled
|
||||
*/
|
||||
CTR_Code PCM::isModuleEnabled(bool &status)
|
||||
{
|
||||
GET_PCM_STATUS();
|
||||
status = rx->moduleEnabled;
|
||||
return rx.err;
|
||||
}
|
||||
/* Get number of total failed PCM Control Frame
|
||||
*
|
||||
* @Return - Failed Control Frames - Number of failed control frames (tokenization fails)
|
||||
*
|
||||
* @WARNING - Return only valid if [SeekDebugFrames] is enabled
|
||||
* See function SeekDebugFrames
|
||||
* See function EnableSeekDebugFrames
|
||||
*/
|
||||
CTR_Code PCM::GetNumberOfFailedControlFrames(UINT16 &status)
|
||||
{
|
||||
GET_PCM_DEBUG();
|
||||
status = rx->tokFailsTop8;
|
||||
status <<= 8;
|
||||
status |= rx->tokFailsBtm8;
|
||||
return rx.err;
|
||||
}
|
||||
/* Get raw Solenoid Blacklist
|
||||
*
|
||||
* @Return - BINARY - Raw binary breakdown of Solenoid Blacklist
|
||||
* BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.
|
||||
*
|
||||
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
|
||||
* See function SeekStatusFaultFrames
|
||||
* See function EnableSeekStatusFaultFrames
|
||||
*/
|
||||
CTR_Code PCM::GetSolenoidBlackList(UINT8 &status)
|
||||
{
|
||||
GET_PCM_SOL_FAULTS();
|
||||
status = rx->SolenoidBlacklist;
|
||||
return rx.err;
|
||||
}
|
||||
/* Get solenoid Blacklist status
|
||||
* - Blacklisted solenoids cannot be enabled until PCM is power cycled
|
||||
*
|
||||
* @Return - True/False - True if Solenoid is blacklisted, false if otherwise
|
||||
*
|
||||
* @Param - idx - ID of solenoid [0,7]
|
||||
*
|
||||
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
|
||||
* See function SeekStatusFaultFrames
|
||||
* See function EnableSeekStatusFaultFrames
|
||||
*/
|
||||
CTR_Code PCM::IsSolenoidBlacklisted(UINT8 idx, bool &status)
|
||||
{
|
||||
GET_PCM_SOL_FAULTS();
|
||||
status = (rx->SolenoidBlacklist & (1ul<<(idx)) )? 1 : 0;
|
||||
return rx.err;
|
||||
}
|
||||
//------------------ C interface --------------------------------------------//
|
||||
extern "C" {
|
||||
void * c_PCM_Init(void) {
|
||||
return new PCM();
|
||||
}
|
||||
CTR_Code c_SetSolenoid(void * handle, unsigned char idx, INT8 param) {
|
||||
return ((PCM*) handle)->SetSolenoid(idx, param);
|
||||
}
|
||||
CTR_Code c_SetAllSolenoids(void * handle, UINT8 state) {
|
||||
return ((PCM*) handle)->SetAllSolenoids(state);
|
||||
}
|
||||
CTR_Code c_SetClosedLoopControl(void * handle, INT8 param) {
|
||||
return ((PCM*) handle)->SetClosedLoopControl(param);
|
||||
}
|
||||
CTR_Code c_ClearStickyFaults(void * handle, INT8 param) {
|
||||
return ((PCM*) handle)->ClearStickyFaults();
|
||||
}
|
||||
CTR_Code c_GetSolenoid(void * handle, UINT8 idx, INT8 * status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetSolenoid(idx, bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetAllSolenoids(void * handle, UINT8 * status) {
|
||||
return ((PCM*) handle)->GetAllSolenoids(*status);
|
||||
}
|
||||
CTR_Code c_GetPressure(void * handle, INT8 * status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetPressure(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetCompressor(void * handle, INT8 * status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetCompressor(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetClosedLoopControl(void * handle, INT8 * status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetClosedLoopControl(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetCompressorCurrent(void * handle, float * status) {
|
||||
CTR_Code retval = ((PCM*) handle)->GetCompressorCurrent(*status);
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetSolenoidVoltage(void * handle, float*status) {
|
||||
return ((PCM*) handle)->GetSolenoidVoltage(*status);
|
||||
}
|
||||
CTR_Code c_GetHardwareFault(void * handle, INT8*status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetHardwareFault(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetCompressorFault(void * handle, INT8*status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetCompressorCurrentTooHighFault(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetSolenoidFault(void * handle, INT8*status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetSolenoidFault(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetCompressorStickyFault(void * handle, INT8*status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetCompressorCurrentTooHighStickyFault(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetSolenoidStickyFault(void * handle, INT8*status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->GetSolenoidStickyFault(bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
CTR_Code c_GetBatteryVoltage(void * handle, float*status) {
|
||||
CTR_Code retval = ((PCM*) handle)->GetBatteryVoltage(*status);
|
||||
return retval;
|
||||
}
|
||||
void c_SetDeviceNumber_PCM(void * handle, UINT8 deviceNumber) {
|
||||
}
|
||||
CTR_Code c_GetNumberOfFailedControlFrames(void * handle, UINT16*status) {
|
||||
return ((PCM*) handle)->GetNumberOfFailedControlFrames(*status);
|
||||
}
|
||||
CTR_Code c_GetSolenoidBlackList(void * handle, UINT8 *status) {
|
||||
return ((PCM*) handle)->GetSolenoidBlackList(*status);
|
||||
}
|
||||
CTR_Code c_IsSolenoidBlacklisted(void * handle, UINT8 idx, INT8*status) {
|
||||
bool bstatus;
|
||||
CTR_Code retval = ((PCM*) handle)->IsSolenoidBlacklisted(idx, bstatus);
|
||||
*status = bstatus;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
#ifndef PCM_H_
|
||||
#define PCM_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "CtreCanNode.h"
|
||||
class PCM : public CtreCanNode
|
||||
{
|
||||
public:
|
||||
PCM(UINT8 deviceNumber=0);
|
||||
~PCM();
|
||||
|
||||
/* Set PCM solenoid state
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoid
|
||||
* @Param - idx - ID of solenoid (0-7)
|
||||
* @Param - en - Enable / Disable identified solenoid
|
||||
*/
|
||||
CTR_Code SetSolenoid(unsigned char idx, bool en);
|
||||
|
||||
/* Set all PCM solenoid states
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoids
|
||||
* @Param - state Bitfield to set all solenoids to
|
||||
*/
|
||||
CTR_Code SetAllSolenoids(UINT8 state);
|
||||
|
||||
/* Enables PCM Closed Loop Control of Compressor via pressure switch
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoid
|
||||
* @Param - en - Enable / Disable Closed Loop Control
|
||||
*/
|
||||
CTR_Code SetClosedLoopControl(bool en);
|
||||
|
||||
/* Clears PCM sticky faults (indicators of past faults
|
||||
* @Return - CTR_Code - Error code (if any) for setting solenoid
|
||||
*/
|
||||
CTR_Code ClearStickyFaults();
|
||||
|
||||
/* Get solenoid state
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid (0-7) to return if solenoid is on.
|
||||
* @Param - status - true if solenoid enabled, false otherwise
|
||||
*/
|
||||
CTR_Code GetSolenoid(UINT8 idx, bool &status);
|
||||
|
||||
/* Get state of all solenoids
|
||||
*
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - bitfield of solenoid states
|
||||
*/
|
||||
CTR_Code GetAllSolenoids(UINT8 &status);
|
||||
|
||||
/* Get pressure switch state
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if pressure adequate, false if low
|
||||
*/
|
||||
CTR_Code GetPressure(bool &status);
|
||||
|
||||
/* Get compressor state
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if compress output is on, false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressor(bool &status);
|
||||
|
||||
/* Get closed loop control state
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if closed loop enabled, false if otherwise
|
||||
*/
|
||||
CTR_Code GetClosedLoopControl(bool &status);
|
||||
|
||||
/* Get compressor current draw
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - Compressor current returned in Amperes (A)
|
||||
*/
|
||||
CTR_Code GetCompressorCurrent(float &status);
|
||||
|
||||
/* Get voltage across solenoid rail
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - Voltage across solenoid rail in Volts (V)
|
||||
*/
|
||||
CTR_Code GetSolenoidVoltage(float &status);
|
||||
|
||||
/* Get hardware fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if hardware failure detected, false if otherwise
|
||||
*/
|
||||
CTR_Code GetHardwareFault(bool &status);
|
||||
|
||||
/* Get compressor fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if abnormally high compressor current detected, false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressorCurrentTooHighFault(bool &status);
|
||||
|
||||
/* Get solenoid fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if shorted solenoid detected, false if otherwise
|
||||
*/
|
||||
CTR_Code GetSolenoidFault(bool &status);
|
||||
|
||||
/* Get compressor sticky fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if solenoid had previously been shorted
|
||||
* (and sticky fault was not cleared), false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressorCurrentTooHighStickyFault(bool &status);
|
||||
/* Get compressor shorted sticky fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if compressor output is shorted, false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressorShortedStickyFault(bool &status);
|
||||
/* Get compressor shorted fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if compressor output is shorted, false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressorShortedFault(bool &status);
|
||||
/* Get compressor is not connected sticky fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if compressor current is too low,
|
||||
* indicating compressor is not connected, false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressorNotConnectedStickyFault(bool &status);
|
||||
/* Get compressor is not connected fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if compressor current is too low,
|
||||
* indicating compressor is not connected, false if otherwise
|
||||
*/
|
||||
CTR_Code GetCompressorNotConnectedFault(bool &status);
|
||||
|
||||
/* Get solenoid sticky fault value
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - True if compressor had previously been shorted
|
||||
* (and sticky fault was not cleared), false if otherwise
|
||||
*/
|
||||
CTR_Code GetSolenoidStickyFault(bool &status);
|
||||
|
||||
/* Get battery voltage
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - Voltage across PCM power ports in Volts (V)
|
||||
*/
|
||||
CTR_Code GetBatteryVoltage(float &status);
|
||||
|
||||
/* Set PCM Device Number and according CAN frame IDs
|
||||
* @Return - void
|
||||
* @Param - deviceNumber - Device number of PCM to control
|
||||
*/
|
||||
void SetDeviceNumber(UINT8 deviceNumber);
|
||||
/* Get number of total failed PCM Control Frame
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - Number of failed control frames (tokenization fails)
|
||||
* @WARNING - Return only valid if [SeekDebugFrames] is enabled
|
||||
* See function SeekDebugFrames
|
||||
* See function EnableSeekDebugFrames
|
||||
*/
|
||||
CTR_Code GetNumberOfFailedControlFrames(UINT16 &status);
|
||||
|
||||
/* Get raw Solenoid Blacklist
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - Raw binary breakdown of Solenoid Blacklist
|
||||
* BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.
|
||||
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
|
||||
* See function SeekStatusFaultFrames
|
||||
* See function EnableSeekStatusFaultFrames
|
||||
*/
|
||||
CTR_Code GetSolenoidBlackList(UINT8 &status);
|
||||
|
||||
/* Get solenoid Blacklist status
|
||||
* - Blacklisted solenoids cannot be enabled until PCM is power cycled
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid [0,7]
|
||||
* @Param - status - True if Solenoid is blacklisted, false if otherwise
|
||||
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
|
||||
* See function SeekStatusFaultFrames
|
||||
* See function EnableSeekStatusFaultFrames
|
||||
*/
|
||||
CTR_Code IsSolenoidBlacklisted(UINT8 idx, bool &status);
|
||||
|
||||
/* Return status of module enable/disable
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - status - Returns TRUE if PCM is enabled, FALSE if disabled
|
||||
*/
|
||||
CTR_Code isModuleEnabled(bool &status);
|
||||
|
||||
/* Get solenoid Blacklist status
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid [0,7] to fire one shot pulse.
|
||||
*/
|
||||
CTR_Code FireOneShotSolenoid(UINT8 idx);
|
||||
|
||||
/* Configure the pulse width of a solenoid channel for one-shot pulse.
|
||||
* Preprogrammed pulsewidth is 10ms resolute and can be between 20ms and 5.1s.
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
* @Param - idx - ID of solenoid [0,7] to configure.
|
||||
* @Param - durMs - pulse width in ms.
|
||||
*/
|
||||
CTR_Code SetOneShotDurationMs(UINT8 idx,uint32_t durMs);
|
||||
|
||||
};
|
||||
//------------------ C interface --------------------------------------------//
|
||||
extern "C" {
|
||||
void * c_PCM_Init(void);
|
||||
CTR_Code c_SetSolenoid(void * handle,unsigned char idx,INT8 param);
|
||||
CTR_Code c_SetAllSolenoids(void * handle,UINT8 state);
|
||||
CTR_Code c_SetClosedLoopControl(void * handle,INT8 param);
|
||||
CTR_Code c_ClearStickyFaults(void * handle,INT8 param);
|
||||
CTR_Code c_GetSolenoid(void * handle,UINT8 idx,INT8 * status);
|
||||
CTR_Code c_GetAllSolenoids(void * handle,UINT8 * status);
|
||||
CTR_Code c_GetPressure(void * handle,INT8 * status);
|
||||
CTR_Code c_GetCompressor(void * handle,INT8 * status);
|
||||
CTR_Code c_GetClosedLoopControl(void * handle,INT8 * status);
|
||||
CTR_Code c_GetCompressorCurrent(void * handle,float * status);
|
||||
CTR_Code c_GetSolenoidVoltage(void * handle,float*status);
|
||||
CTR_Code c_GetHardwareFault(void * handle,INT8*status);
|
||||
CTR_Code c_GetCompressorFault(void * handle,INT8*status);
|
||||
CTR_Code c_GetSolenoidFault(void * handle,INT8*status);
|
||||
CTR_Code c_GetCompressorStickyFault(void * handle,INT8*status);
|
||||
CTR_Code c_GetSolenoidStickyFault(void * handle,INT8*status);
|
||||
CTR_Code c_GetBatteryVoltage(void * handle,float*status);
|
||||
void c_SetDeviceNumber_PCM(void * handle,UINT8 deviceNumber);
|
||||
void c_EnableSeekStatusFrames(void * handle,INT8 enable);
|
||||
void c_EnableSeekStatusFaultFrames(void * handle,INT8 enable);
|
||||
void c_EnableSeekDebugFrames(void * handle,INT8 enable);
|
||||
CTR_Code c_GetNumberOfFailedControlFrames(void * handle,UINT16*status);
|
||||
CTR_Code c_GetSolenoidBlackList(void * handle,UINT8 *status);
|
||||
CTR_Code c_IsSolenoidBlacklisted(void * handle,UINT8 idx,INT8*status);
|
||||
}
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* @file ctre.h
|
||||
* Common header for all CTRE HAL modules.
|
||||
*/
|
||||
#ifndef CTRE_H
|
||||
#define CTRE_H
|
||||
|
||||
//Bit Defines
|
||||
#define BIT0 0x01
|
||||
#define BIT1 0x02
|
||||
#define BIT2 0x04
|
||||
#define BIT3 0x08
|
||||
#define BIT4 0x10
|
||||
#define BIT5 0x20
|
||||
#define BIT6 0x40
|
||||
#define BIT7 0x80
|
||||
#define BIT8 0x0100
|
||||
#define BIT9 0x0200
|
||||
#define BIT10 0x0400
|
||||
#define BIT11 0x0800
|
||||
#define BIT12 0x1000
|
||||
#define BIT13 0x2000
|
||||
#define BIT14 0x4000
|
||||
#define BIT15 0x8000
|
||||
|
||||
//Signed
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
typedef signed long long INT64;
|
||||
|
||||
//Unsigned
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
typedef unsigned long long UINT64;
|
||||
|
||||
//Other
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef enum {
|
||||
CTR_OKAY, //!< No Error - Function executed as expected
|
||||
CTR_RxTimeout, //!< CAN frame has not been received within specified period of time.
|
||||
CTR_TxTimeout, //!< Not used.
|
||||
CTR_InvalidParamValue, //!< Caller passed an invalid param
|
||||
CTR_UnexpectedArbId, //!< Specified CAN Id is invalid.
|
||||
CTR_TxFailed, //!< Could not transmit the CAN frame.
|
||||
CTR_SigNotUpdated, //!< Have not received an value response for signal.
|
||||
CTR_BufferFull, //!< Caller attempted to insert data into a buffer that is full.
|
||||
}CTR_Code;
|
||||
|
||||
#endif /* CTRE_H */
|
||||
38
hal/src/main/native/athena/mockdata/CTREPCMData.cpp
Normal file
38
hal/src/main/native/athena/mockdata/CTREPCMData.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "hal/simulation/CTREPCMData.h"
|
||||
|
||||
#include "hal/simulation/SimDataValue.h"
|
||||
|
||||
extern "C" {
|
||||
void HALSIM_ResetCTREPCMData(int32_t index) {}
|
||||
|
||||
#define DEFINE_CAPI(TYPE, CAPINAME, RETURN) \
|
||||
HAL_SIMDATAVALUE_STUB_CAPI(TYPE, HALSIM, CTREPCM##CAPINAME, RETURN)
|
||||
|
||||
HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(HAL_Bool, HALSIM, CTREPCMSolenoidOutput,
|
||||
false)
|
||||
DEFINE_CAPI(HAL_Bool, Initialized, false)
|
||||
DEFINE_CAPI(HAL_Bool, CompressorOn, false)
|
||||
DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, false)
|
||||
DEFINE_CAPI(HAL_Bool, PressureSwitch, false)
|
||||
DEFINE_CAPI(double, CompressorCurrent, 0)
|
||||
|
||||
void HALSIM_GetCTREPCMAllSolenoids(int32_t index, uint8_t* values) {
|
||||
*values = 0;
|
||||
}
|
||||
|
||||
void HALSIM_SetCTREPCMAllSolenoids(int32_t index, uint8_t values) {}
|
||||
|
||||
void HALSIM_RegisterCTREPCMAllNonSolenoidCallbacks(int32_t index,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify) {}
|
||||
|
||||
void HALSIM_RegisterCTREPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify) {}
|
||||
} // extern "C"
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "hal/simulation/PCMData.h"
|
||||
|
||||
#include "hal/simulation/SimDataValue.h"
|
||||
|
||||
extern "C" {
|
||||
void HALSIM_ResetPCMData(int32_t index) {}
|
||||
|
||||
#define DEFINE_CAPI(TYPE, CAPINAME, RETURN) \
|
||||
HAL_SIMDATAVALUE_STUB_CAPI(TYPE, HALSIM, PCM##CAPINAME, RETURN)
|
||||
|
||||
HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidInitialized,
|
||||
false)
|
||||
HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidOutput, false)
|
||||
DEFINE_CAPI(HAL_Bool, CompressorInitialized, false)
|
||||
DEFINE_CAPI(HAL_Bool, CompressorOn, false)
|
||||
DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, false)
|
||||
DEFINE_CAPI(HAL_Bool, PressureSwitch, false)
|
||||
DEFINE_CAPI(double, CompressorCurrent, 0)
|
||||
|
||||
void HALSIM_GetPCMAllSolenoids(int32_t index, uint8_t* values) {
|
||||
*values = 0;
|
||||
}
|
||||
|
||||
void HALSIM_SetPCMAllSolenoids(int32_t index, uint8_t values) {}
|
||||
|
||||
void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify) {}
|
||||
|
||||
void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify) {}
|
||||
} // extern "C"
|
||||
Reference in New Issue
Block a user