diff --git a/hal/lib/Athena/ctre/CtreCanNode.cpp b/hal/lib/Athena/ctre/CtreCanNode.cpp new file mode 100644 index 0000000000..3b66d37b22 --- /dev/null +++ b/hal/lib/Athena/ctre/CtreCanNode.cpp @@ -0,0 +1,99 @@ +#include "CtreCanNode.h" +#include "NetworkCommunication/CANSessionMux.h" +#include // memset +#include // usleep + +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 */ +} +void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs) +{ + int32_t status = 0; + + txJob_t job = {0}; + job.arbId = arbId; + job.periodMs = periodMs; + _txJobs[arbId] = job; + FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId, + job.toSend, + 8, + job.periodMs, + &status); +} +timespec diff(const timespec & start, const timespec & end) +{ + timespec temp; + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + return temp; +} +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); + if(status == 0){ + /* fresh update */ + rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */ + clock_gettime(2,&r.time); /* fill in time */ + 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 */ + struct timespec temp; + clock_gettime(2,&temp); /* get now */ + /* how long has it been? */ + temp = diff(i->second.time,temp); /* temp = now - last */ + if(temp.tv_sec > 0){ + retval = CTR_RxTimeout; + }else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){ + 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, + 8, + iter->second.periodMs, + &status); +} + diff --git a/hal/lib/Athena/ctre/CtreCanNode.h b/hal/lib/Athena/ctre/CtreCanNode.h new file mode 100644 index 0000000000..bf5a4a5353 --- /dev/null +++ b/hal/lib/Athena/ctre/CtreCanNode.h @@ -0,0 +1,116 @@ +#ifndef CtreCanNode_H_ +#define CtreCanNode_H_ +#include "ctre.h" //BIT Defines + Typedefs +#include "NetworkCommunication/CANSessionMux.h" //CAN Comm +#include +#include +#include // memcpy +#include +class CtreCanNode +{ +public: + CtreCanNode(UINT8 deviceNumber); + ~CtreCanNode(); + + UINT8 GetDeviceNumber() + { + return _deviceNumber; + } +protected: + + + template 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 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); + void RegisterTx(uint32_t arbId, uint32_t periodMs); + + CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs); + void FlushTx(uint32_t arbId); + + template txTask GetTx(uint32_t arbId) + { + txTask retval = {0}; + 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 void FlushTx(T & par) + { + FlushTx(par.arbId); + } + + template recMsg GetRx(uint32_t arbId, uint32_t timeoutMs) + { + recMsg 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; + }; + + class rxEvent_t{ + public: + uint8_t bytes[8]; + struct timespec 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 txJobs_t; + txJobs_t _txJobs; + + typedef std::map rxRxEvents_t; + rxRxEvents_t _rxRxEvents; +}; +#endif diff --git a/hal/lib/Athena/ctre/PCM.cpp b/hal/lib/Athena/ctre/PCM.cpp index 9371bac1dd..ab747bc1c2 100644 --- a/hal/lib/Athena/ctre/PCM.cpp +++ b/hal/lib/Athena/ctre/PCM.cpp @@ -1,16 +1,93 @@ +#if 0 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #include "PCM.h" #include "NetworkCommunication/CANSessionMux.h" #include // memset #include // usleep - -static const UINT32 kFullMessageIDMask = 0x1fffffff; - /* This can be a constant, as long as nobody needs to updatie 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 rx = GetRx (STATUS_1,EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_PCM_SOL_FAULTS() CtreCanNode::recMsg rx = GetRx (STATUS_SOL_FAULTS,EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_PCM_DEBUG() CtreCanNode::recMsg rx = GetRx (STATUS_DEBUG,EXPECTED_RESPONSE_TIMEOUT_MS) + +#define CONTROL_1 0x09041C00 + +/* encoder/decoders */ +typedef struct _PcmStatus_t{ + /* Byte 0 */ + unsigned SolenoidBits:8; + /* Byte 1 */ + unsigned compressorOn:1; + unsigned stickyFaultFuseTripped:1; + unsigned stickyFaultCompCurrentTooHigh:1; + unsigned faultCompCurrentTooHigh:1; + unsigned faultFuseTripped: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 reserved:2; + 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; +}PcmControl_t; + +typedef struct _PcmStatusFault_t{ + /* Byte 0 */ + unsigned SolenoidBlacklist:8; + /* Byte 1 */ + unsigned reserved1:8; + unsigned reserved2:8; + unsigned reserved3:8; + unsigned reserved4:8; + unsigned reserved5:8; + unsigned reserved6:8; + unsigned reserved7:8; +}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 * @@ -18,60 +95,39 @@ static const INT32 kCANPeriod = 20; * * @Param - deviceNumber - Device ID of PCM to be controlled */ -PCM::PCM(UINT8 deviceNumber) +PCM::PCM(UINT8 deviceNumber): CtreCanNode(deviceNumber) { - memset(&_PcmDebug, 0, sizeof(_PcmDebug)); - memset(&_PcmControl, 0, sizeof(_PcmControl)); - memset(&_PcmStatus, 0, sizeof(_PcmStatus)); - memset(&_PcmStatusFault,0, sizeof(_PcmStatusFault)); - /* setup arbids */ - SetDeviceNumber(deviceNumber); - /* clear error info */ - _timeSinceLastRx = 0; - _timeSinceLastTx = 0; - _numFailedRxs = 0; - _numFailedTxs = 0; - /* start thread */ - _threadIsRunning = 1; - _threadErr = pthread_create( &_thread, NULL, ThreadFunc, (void*) this); + RegisterRx(STATUS_1 | deviceNumber ); + RegisterRx(STATUS_SOL_FAULTS | deviceNumber ); + RegisterRx(STATUS_DEBUG | deviceNumber ); + RegisterTx(CONTROL_1 | deviceNumber, kCANPeriod); + /* enable close loop */ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + toFill->closedLoopEnable = 1; } /* PCM D'tor */ -PCM::~PCM() { - /* wait for thread to finish */ - _threadIsRunning = 0; - pthread_join( _thread, NULL); - _thread = 0; -} -/* Set PCM Device Number and according CAN frame IDs - * - * @Return - void - * - * @Param - deviceNumber - Device number of PCM to control - */ -void PCM::SetDeviceNumber(UINT8 deviceNumber) { - PCM_settings.deviceNumber = deviceNumber; - PCM_settings.controlFrameID = 0x9041C00 + (deviceNumber) + (UINT32) (0 * BIT6); - PCM_settings.statusFrameID = 0x9041400 + (deviceNumber) + (UINT32) (0 * BIT6); - PCM_settings.statusFaultFrameID = 0x9041400 + (deviceNumber) + (UINT32) (1 * BIT6); - PCM_settings.debugFrameID = 0x9041400 + (deviceNumber) + (UINT32) (2 * BIT6); +PCM::~PCM() +{ + } /* Set PCM solenoid state * * @Return - CTR_Code - Error code (if any) for setting solenoid * - * @Param - idx - ID of solenoid (1-8) + * @Param - idx - ID of solenoid (0-7) * @Param - en - Enable / Disable identified solenoid */ -CTR_Code PCM::SetSolenoid(unsigned char idx, bool en) { - idx--; /* make it zero based */ +CTR_Code PCM::SetSolenoid(unsigned char idx, bool en) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if(toFill.IsEmpty())return CTR_UnexpectedArbId; if (en) - _PcmControl.solenoidBits |= (1ul << (7-idx)); + toFill->solenoidBits |= (1ul << (7-idx)); else - _PcmControl.solenoidBits &= ~(1ul << (7-idx)); - if (GetTimeSinceLastTx() >= 50) - return CTR_TxTimeout; + toFill->solenoidBits &= ~(1ul << (7-idx)); + FlushTx(toFill); return CTR_OKAY; } @@ -81,10 +137,12 @@ CTR_Code PCM::SetSolenoid(unsigned char idx, bool en) { * * @Param - clr - Clear / do not clear faults */ -CTR_Code PCM::ClearStickyFaults(bool clr) { - _PcmControl.clearStickyFaults = clr; - if (GetTimeSinceLastTx() >= 50) - return CTR_TxTimeout; +CTR_Code PCM::ClearStickyFaults(bool clr) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if(toFill.IsEmpty())return CTR_UnexpectedArbId; + toFill->clearStickyFaults = clr; + FlushTx(toFill); return CTR_OKAY; } @@ -94,299 +152,212 @@ CTR_Code PCM::ClearStickyFaults(bool clr) { * * @Param - en - Enable / Disable Closed Loop Control */ -CTR_Code PCM::SetClosedLoopControl(bool en) { - _PcmControl.closedLoopEnable = en; - if (GetTimeSinceLastTx() >= 50) - return CTR_TxTimeout; +CTR_Code PCM::SetClosedLoopControl(bool en) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if(toFill.IsEmpty())return CTR_UnexpectedArbId; + toFill->closedLoopEnable = en; + FlushTx(toFill); return CTR_OKAY; } /* Get solenoid state - * + * * @Return - True/False - True if solenoid enabled, false otherwise - * - * @Param - idx - ID of solenoid (1-8) to return status of + * + * @Param - idx - ID of solenoid (0-7) to return status of */ -CTR_Code PCM::GetSolenoid(UINT8 idx, bool &status) { - idx--; - status = (_PcmStatus.SolenoidBits & (1ul<<(7-idx))) ? 1 : 0; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetSolenoid(UINT8 idx, bool &status) +{ + GET_PCM_STATUS(); + status = (rx->SolenoidBits & (1ul<<(7-idx)) ) ? 1 : 0; + return rx.err; } /* Get pressure switch state - * + * * @Return - True/False - True if pressure adequate, false if low */ -CTR_Code PCM::GetPressure(bool &status) { - status = _PcmStatus.pressureSwitchEn; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +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) { - status = _PcmStatus.compressorOn; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +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) { - status = _PcmStatus.isCloseloopEnabled; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetClosedLoopControl(bool &status) +{ + GET_PCM_STATUS(); + status = (rx->isCloseloopEnabled); + return rx.err; } /* Get compressor current draw - * - * @Return - Amperes - Compressor current + * + * @Return - Amperes - Compressor current */ -CTR_Code PCM::GetCompressorCurrent(float &status) { - uint16_t bt = _PcmStatus.compressorCurrentTop6; - bt <<= 4; - bt |= _PcmStatus.compressorCurrentBtm4; - status = 0.0201612903225806 * bt; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetCompressorCurrent(float &status) +{ + GET_PCM_STATUS(); + uint32_t temp =(rx->compressorCurrentTop6); + temp <<= 4; + temp |= rx->compressorCurrentBtm4; + status = 20.1612903225806 * temp; + return rx.err; } /* Get voltage across solenoid rail - * + * * @Return - Volts - Voltage across solenoid rail */ -CTR_Code PCM::GetSolenoidVoltage(float &status) { - uint32_t raw = _PcmStatus.solenoidVoltageTop8; +CTR_Code PCM::GetSolenoidVoltage(float &status) +{ + GET_PCM_STATUS(); + uint32_t raw =(rx->solenoidVoltageTop8); raw <<= 2; - raw |= _PcmStatus.solenoidVoltageBtm2; + raw |= rx->solenoidVoltageBtm2; status = (double) raw * 24.7800586510264 / 1000; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; + return rx.err; } /* Get hardware fault value - * + * * @Return - True/False - True if hardware failure detected, false if otherwise */ -CTR_Code PCM::GetHardwareFault(bool &status) { - status = _PcmStatus.faultHardwareFailure; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +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::GetCompressorFault(bool &status) { - status = _PcmStatus.faultCompCurrentTooHigh; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetCompressorFault(bool &status) +{ + GET_PCM_STATUS(); + status = rx->faultCompCurrentTooHigh; + return rx.err; } /* Get solenoid fault value - * + * * @Return - True/False - True if shorted solenoid detected, false if otherwise */ -CTR_Code PCM::GetSolenoidFault(bool &status) { - status = _PcmStatus.faultFuseTripped; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetSolenoidFault(bool &status) +{ + GET_PCM_STATUS(); + status = rx->faultFuseTripped; + return rx.err; } -// Past Faults /* 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::GetCompressorStickyFault(bool &status) { - status = _PcmStatus.stickyFaultCompCurrentTooHigh; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetCompressorStickyFault(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) { /* fix this */ - status = _PcmStatus.stickyFaultFuseTripped; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +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) { - status = (float)_PcmStatus.battVoltage * ((59.0420332355816) / 1000.0);; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; -} -/* 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) { - status = _PcmDebug.tokFailsTop8; - status <<= 8; - status |= _PcmDebug.tokFailsBtm8; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; -} -/* 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) { - status = _PcmStatusFault.SolenoidBlacklist; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; -} -/* 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 - * - * @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled - * See function SeekStatusFaultFrames - * See function EnableSeekStatusFaultFrames - */ -CTR_Code PCM::IsSolenoidBlacklisted(UINT8 idx, bool &status) { - idx--; - if(_PcmStatusFault.SolenoidBlacklist & (1ul<<(7-idx))) - status = 1; - else - status = 0; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; +CTR_Code PCM::GetBatteryVoltage(float &status) +{ + GET_PCM_STATUS(); + status = (float)rx->battVoltage * ((59.0420332355816) / 1000.0);; + 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) { - status = _PcmStatus.moduleEnabled; - if (GetTimeSinceLastRx() >= 50) - return CTR_RxTimeout; - return CTR_OKAY; -} -void PCM::GetErrorInfo( uint32_t * timeSinceLastRx, - uint32_t * timeSinceLastTx, - uint32_t * numFailedRxs, - uint32_t * numFailedTxs) +CTR_Code PCM::isModuleEnabled(bool &status) { - if(timeSinceLastRx) *timeSinceLastRx = _timeSinceLastRx; - if(timeSinceLastTx) *timeSinceLastTx = _timeSinceLastTx; - if(numFailedRxs) *numFailedRxs = _numFailedRxs; - if(numFailedTxs) *numFailedTxs = _numFailedTxs; + GET_PCM_STATUS(); + status = rx->moduleEnabled; + return rx.err; } -//------------------ CAN interface and thread --------------------------------------------// -/* Search for PCM Status Frame on CAN bus */ -void PCM::ReadStatusFrame(void) { - PcmStatus_t frame = {0}; - UINT8 size = 0; - INT32 status = 0; - UINT32 timeStamp = 0; - FRC_NetworkCommunication_CANSessionMux_receiveMessage(&PCM_settings.statusFrameID, kFullMessageIDMask, (uint8_t *)&frame, &size, &timeStamp, &status); - if (status == 0) { - _timeSinceLastRx = 0; - _PcmStatus = frame; - } else { - ++_numFailedRxs; - } -} -/* Search for PCM Status Fault Frame on CAN bus */ -void PCM::ReadStatusFaultFrame(void) { - PcmStatusFault_t frame= {0}; - UINT8 size = 0; - INT32 status = 0; - UINT32 timeStamp = 0; - FRC_NetworkCommunication_CANSessionMux_receiveMessage(&PCM_settings.statusFaultFrameID, kFullMessageIDMask, (uint8_t *)&frame, &size, &timeStamp, &status); - if (status == 0) { - _timeSinceLastRx = 0; - _PcmStatusFault = frame; - } else { - ++_numFailedRxs; - } -} -/* Search for PCM Debug Frame on CAN bus */ -void PCM::ReadDebugFrame(void) { - PcmDebug_t frame= {0}; - UINT8 size = 0; - INT32 status = 0; - UINT32 timeStamp = 0; - FRC_NetworkCommunication_CANSessionMux_receiveMessage(&PCM_settings.debugFrameID, kFullMessageIDMask, (uint8_t *)&frame, &size, &timeStamp, &status); - if (status == 0) { - _timeSinceLastRx = 0; - _PcmDebug = frame; - } else { - ++_numFailedRxs; - } -} -void * PCM::ThreadFunc() +/* 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) { - while(_threadIsRunning){ - int32_t status = 0; - FRC_NetworkCommunication_CANSessionMux_sendMessage(PCM_settings.controlFrameID, (const uint8_t *)&_PcmControl, sizeof(_PcmControl), kCANPeriod, &status); - if(status == 0){ - /* success */ - _timeSinceLastTx = 0; - }else { - /* something is wrong */ - ++_numFailedTxs; - } - /* reads */ - ReadStatusFrame(); - ReadStatusFaultFrame(); - ReadDebugFrame(); - /* yield for 25ms */ - usleep(25e3); - /* incrememnt times since comm without overflow */ - if(_timeSinceLastTx < 60000) - _timeSinceLastTx += 25; - if(_timeSinceLastRx < 60000) - _timeSinceLastRx += 25; - } - return 0; + GET_PCM_DEBUG(); + status = rx->tokFailsTop8; + status <<= 8; + status |= rx->tokFailsBtm8; + return rx.err; } -void * PCM::ThreadFunc( void *ptr ) +/* 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) { - return ((PCM*)ptr)->ThreadFunc(); + 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<<(7-idx)) )? 1 : 0; + return rx.err; } //------------------ C interface --------------------------------------------// extern "C" { @@ -430,7 +401,6 @@ extern "C" { CTR_Code retval = ((PCM*) handle)->GetCompressorCurrent(*status); return retval; } - CTR_Code c_GetSolenoidVoltage(void * handle, float*status) { return ((PCM*) handle)->GetSolenoidVoltage(*status); } @@ -469,7 +439,6 @@ extern "C" { return retval; } void c_SetDeviceNumber_PCM(void * handle, UINT8 deviceNumber) { - return ((PCM*) handle)->SetDeviceNumber(deviceNumber); } CTR_Code c_GetNumberOfFailedControlFrames(void * handle, UINT16*status) { return ((PCM*) handle)->GetNumberOfFailedControlFrames(*status); @@ -484,3 +453,4 @@ extern "C" { return retval; } } +#endif diff --git a/hal/lib/Athena/ctre/PCM.h b/hal/lib/Athena/ctre/PCM.h index bc7b482b5d..b832fd2c6f 100644 --- a/hal/lib/Athena/ctre/PCM.h +++ b/hal/lib/Athena/ctre/PCM.h @@ -1,84 +1,19 @@ #ifndef PCM_H_ #define PCM_H_ -#include "ctre.h" //BIT Defines + Typedefs +#include "ctre.h" //BIT Defines + Typedefs #include //CAN Comm +#include "CtreCanNode.h" #include -/* encoder/decoders */ -typedef struct _PcmStatus_t{ - /* Byte 0 */ - unsigned SolenoidBits:8; - /* Byte 1 */ - unsigned compressorOn:1; - unsigned stickyFaultFuseTripped:1; - unsigned stickyFaultCompCurrentTooHigh:1; - unsigned faultCompCurrentTooHigh:1; - unsigned faultFuseTripped: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 reserved:2; - 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:5; - unsigned CompressorOn_deprecated:1; //!< This is ignored by PCM firm now. - unsigned closedLoopEnable:1; - unsigned clearStickyFaults:1; -}PcmControl_t; - -typedef struct _PcmStatusFault_t{ - /* Byte 0 */ - unsigned SolenoidBlacklist:8; - /* Byte 1 */ - unsigned reserved1:8; - unsigned reserved2:8; - unsigned reserved3:8; - unsigned reserved4:8; - unsigned reserved5:8; - unsigned reserved6:8; - unsigned reserved7:8; -}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; - -class PCM +class PCM : public CtreCanNode { public: - PCM(UINT8 deviceNumber=50); + PCM(UINT8 deviceNumber=0); ~PCM(); - + /* Set PCM solenoid state + * * @Return - CTR_Code - Error code (if any) for setting solenoid - * @Param - idx - ID of solenoid (1-8) + * @Param - idx - ID of solenoid (0-7) * @Param - en - Enable / Disable identified solenoid */ CTR_Code SetSolenoid(unsigned char idx, bool en); @@ -94,14 +29,12 @@ public: * @Param - clr - Clear / do not clear faults */ CTR_Code ClearStickyFaults(bool clr); - + /* Get solenoid state * * @Return - CTR_Code - Error code (if any) - * @Param - idx - ID of solenoid (1-8) to return status of - * @Param - status - True if solenoid output is set to be enabled, false otherwise. - * If the phsyical output led still isn't on, then check webdash for - * any faults/is PCM enabled. + * @Param - idx - ID of solenoid (0-7) to return if solenoid is on. + * @Param - status - OK if solenoid enabled, false otherwise */ CTR_Code GetSolenoid(UINT8 idx, bool &status); @@ -172,7 +105,7 @@ public: * @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 @@ -186,7 +119,7 @@ public: * 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 @@ -200,7 +133,7 @@ public: /* 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 + * @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 @@ -213,70 +146,6 @@ public: * @Param - status - Returns TRUE if PCM is enabled, FALSE if disabled */ CTR_Code isModuleEnabled(bool &status); - - /* Get time since last sent frame - * @Return - int - Returns time in milliseconds (ms) since last sent PCM frame - */ - int GetTimeSinceLastTx(void) { return _timeSinceLastTx;} - - /* Get time since last received frame - * @Return - int - Returns time in milliseconds (ms) since last received PCM frame - */ - int GetTimeSinceLastRx(void) { return _timeSinceLastRx;} -private: - - /* Seek PCM Status Frames on CAN bus - * @Return - void - * @Param - en - Enable / Disable seeking of PCM Status Frame - * @Notes - Status Frames identify - */ - void EnableSeekStatusFrames(bool en); - - /* Seek PCM Status Fault Frames on CAN bus - * @Return - void - * @Param - en - Enable / Disable seeking of PCM Status Fault Frame - * @Notes - Status Fault Frames identify Blacklisted Solenoids - */ - void EnableSeekStatusFaultFrames(bool en); - - /* Seek PCM Debug Frames on CAN bus - * @Return - void - * @Param - en - Enable / Disable seeking of PCM Debug Frame - * @Notes - Debug Frames identify the number of failed tokens (for exclusive, secure control of PCM by RoboRIO) - */ - void EnableSeekDebugFrames(bool en); - /* frames to receive */ - PcmDebug_t _PcmDebug; - PcmStatus_t _PcmStatus; - PcmStatusFault_t _PcmStatusFault; - /* frames to send */ - PcmControl_t _PcmControl; - /* tracking health and error info */ - uint32_t _timeSinceLastRx; - uint32_t _timeSinceLastTx; - uint32_t _numFailedRxs; - uint32_t _numFailedTxs; - /* threading */ - pthread_t _thread; - int _threadErr; - int _threadIsRunning; - /** arbids */ - struct PCM_SETTINGS{ - UINT8 deviceNumber; - UINT32 controlFrameID; - UINT32 statusFrameID; - UINT32 statusFaultFrameID; - UINT32 debugFrameID; - }PCM_settings; - void ReadStatusFrame(void); - void ReadStatusFaultFrame(void); - void ReadDebugFrame(void); - void GetErrorInfo( uint32_t * timeSinceLastRx, - uint32_t * timeSinceLastTx, - uint32_t * numFailedRxs, - uint32_t * numFailedTxs); - static void * ThreadFunc(void *); - void * ThreadFunc(); }; //------------------ C interface --------------------------------------------// extern "C" { diff --git a/hal/lib/Athena/ctre/PDP.cpp b/hal/lib/Athena/ctre/PDP.cpp index 555c201104..8f0a6a08a4 100644 --- a/hal/lib/Athena/ctre/PDP.cpp +++ b/hal/lib/Athena/ctre/PDP.cpp @@ -3,145 +3,130 @@ #include // memset #include // usleep -#define kFullMessageIDMask 0x1fffffff +#define STATUS_1 0x8041400 +#define STATUS_2 0x8041440 +#define STATUS_3 0x8041480 -PDP::PDP(UINT8 deviceNumber) +#define EXPECTED_RESPONSE_TIMEOUT_MS (50) +#define GET_STATUS1() CtreCanNode::recMsg rx = GetRx(STATUS_1,EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS2() CtreCanNode::recMsg rx = GetRx(STATUS_2,EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS3() CtreCanNode::recMsg rx = GetRx(STATUS_3,EXPECTED_RESPONSE_TIMEOUT_MS) + +/* encoder/decoders */ +typedef struct _PdpStatus1_t{ + unsigned chan1_h8:8; + unsigned chan2_h6:6; + unsigned chan1_l2:2; + unsigned chan3_h4:4; + unsigned chan2_l4:4; + unsigned chan4_h2:2; + unsigned chan3_l6:6; + unsigned chan4_l8:8; + unsigned chan5_h8:8; + unsigned chan6_h6:6; + unsigned chan5_l2:2; + unsigned reserved4:4; + unsigned chan6_l4:4; +}PdpStatus1_t; +typedef struct _PdpStatus2_t{ + unsigned chan7_h8:8; + unsigned chan8_h6:6; + unsigned chan7_l2:2; + unsigned chan9_h4:4; + unsigned chan8_l4:4; + unsigned chan10_h2:2; + unsigned chan9_l6:6; + unsigned chan10_l8:8; + unsigned chan11_h8:8; + unsigned chan12_h6:6; + unsigned chan11_l2:2; + unsigned reserved4:4; + unsigned chan12_l4:4; +}PdpStatus2_t; +typedef struct _PdpStatus3_t{ + unsigned chan13_h8:8; + unsigned chan14_h6:6; + unsigned chan13_l2:2; + unsigned chan15_h4:4; + unsigned chan14_l4:4; + unsigned chan16_h2:2; + unsigned chan15_l6:6; + unsigned chan16_l8:8; + unsigned internalResBattery_mOhms:8; + unsigned busVoltage:8; + unsigned temp:8; +}PdpStatus3_t; + +PDP::PDP(UINT8 deviceNumber): CtreCanNode(deviceNumber) { - memset(&_status1, 0, sizeof(_status1)); - memset(&_status2, 0, sizeof(_status2)); - memset(&_status3, 0, sizeof(_status3)); - memset(&PDP_Settings, 0, sizeof PDP_Settings); - /* setup arbids */ - SetDeviceNumber(deviceNumber); - /* clear error info */ - _timeSinceLastRx = 0; - _numFailedRxs = 0; - /* start thread */ - _threadIsRunning = 1; - _threadErr = pthread_create( &_thread, NULL, ThreadFunc, (void*) this); + RegisterRx(STATUS_1 | deviceNumber ); + RegisterRx(STATUS_2 | deviceNumber ); + RegisterRx(STATUS_3 | deviceNumber ); } /* PDP D'tor */ -PDP::~PDP() { - /* wait for thread to finish */ - _threadIsRunning = 0; - pthread_join( _thread, NULL); - _thread = 0; +PDP::~PDP() +{ } -CTR_Code PDP::GetChannelCurrent(UINT8 idx, double ¤t){ - /* atomically copy out our data */ - PdpStatus1_t status1 = _status1; - PdpStatus2_t status2 = _status2; - PdpStatus3_t status3 = _status3; + +CTR_Code PDP::GetChannelCurrent(UINT8 idx, double ¤t) +{ + CTR_Code retval = CTR_InvalidParamValue; uint32_t raw = 0; - if(idx <= 6) - { - switch(idx) - { - case 0: raw = 0; break; - case 1: raw = ((uint32_t)status1.chan1_h8 << 2) | status1.chan1_l2; break; - case 2: raw = ((uint32_t)status1.chan2_h6 << 4) | status1.chan2_l4; break; - case 3: raw = ((uint32_t)status1.chan3_h4 << 6) | status1.chan3_l6; break; - case 4: raw = ((uint32_t)status1.chan4_h2 << 8) | status1.chan4_l8; break; - case 5: raw = ((uint32_t)status1.chan5_h8 << 2) | status1.chan5_l2; break; - case 6: raw = ((uint32_t)status1.chan6_h6 << 4) | status1.chan6_l4; break; + + if(idx <= 5){ + GET_STATUS1(); + retval = rx.err; + switch(idx){ + case 0: raw = ((uint32_t)rx->chan1_h8 << 2) | rx->chan1_l2; break; + case 1: raw = ((uint32_t)rx->chan2_h6 << 4) | rx->chan2_l4; break; + case 2: raw = ((uint32_t)rx->chan3_h4 << 6) | rx->chan3_l6; break; + case 3: raw = ((uint32_t)rx->chan4_h2 << 8) | rx->chan4_l8; break; + case 4: raw = ((uint32_t)rx->chan5_h8 << 2) | rx->chan5_l2; break; + case 5: raw = ((uint32_t)rx->chan6_h6 << 4) | rx->chan6_l4; break; + default: retval = CTR_InvalidParamValue; break; } - } - else if(idx <= 12) - { - switch(idx) - { - case 7: raw = ((uint32_t)status2.chan7_h8 << 2) | status2.chan7_l2; break; - case 8: raw = ((uint32_t)status2.chan8_h6 << 4) | status2.chan8_l4; break; - case 9: raw = ((uint32_t)status2.chan9_h4 << 6) | status2.chan9_l6; break; - case 10: raw = ((uint32_t)status2.chan10_h2 << 8) | status2.chan10_l8; break; - case 11: raw = ((uint32_t)status2.chan11_h8 << 2) | status2.chan11_l2; break; - case 12: raw = ((uint32_t)status2.chan12_h6 << 4) | status2.chan12_l4; break; + }else if(idx <= 11){ + GET_STATUS2(); + retval = rx.err; + switch(idx){ + case 6: raw = ((uint32_t)rx->chan7_h8 << 2) | rx->chan7_l2; break; + case 7: raw = ((uint32_t)rx->chan8_h6 << 4) | rx->chan8_l4; break; + case 8: raw = ((uint32_t)rx->chan9_h4 << 6) | rx->chan9_l6; break; + case 9: raw = ((uint32_t)rx->chan10_h2 << 8) | rx->chan10_l8; break; + case 10: raw = ((uint32_t)rx->chan11_h8 << 2) | rx->chan11_l2; break; + case 11: raw = ((uint32_t)rx->chan12_h6 << 4) | rx->chan12_l4; break; + default: retval = CTR_InvalidParamValue; break; } - } - else if(idx <= 16) - { - switch(idx) - { - case 13: raw = ((uint32_t)status3.chan13_h8 << 2) | status3.chan13_l2; break; - case 14: raw = ((uint32_t)status3.chan14_h6 << 4) | status3.chan14_l4; break; - case 15: raw = ((uint32_t)status3.chan15_h4 << 6) | status3.chan15_l6; break; - case 16: raw = ((uint32_t)status3.chan16_h2 << 8) | status3.chan16_l8; break; + }else if(idx <= 15){ + GET_STATUS3(); + retval = rx.err; + switch(idx){ + case 12: raw = ((uint32_t)rx->chan13_h8 << 2) | rx->chan13_l2; break; + case 13: raw = ((uint32_t)rx->chan14_h6 << 4) | rx->chan14_l4; break; + case 14: raw = ((uint32_t)rx->chan15_h4 << 6) | rx->chan15_l6; break; + case 15: raw = ((uint32_t)rx->chan16_h2 << 8) | rx->chan16_l8; break; + default: retval = CTR_InvalidParamValue; break; } } /* convert to amps */ current = 0.06724511900000001*raw + 1.527114967; /* signal caller with success */ - if(GetTimeSinceLastRx()>=50) - return CTR_RxTimeout; - return CTR_OKAY; + return retval; } -CTR_Code PDP::GetVoltage(double &voltage){ - uint32_t raw = _status3.busVoltage; +CTR_Code PDP::GetVoltage(double &voltage) +{ + GET_STATUS3(); + uint32_t raw = rx->busVoltage; voltage = 0.0554413328606877 * raw; - if(GetTimeSinceLastRx()>=50) - return CTR_RxTimeout; - return CTR_OKAY; + return rx.err; } - -CTR_Code PDP::GetTemperature(double &tempC){ - uint32_t raw = _status3.temp; +CTR_Code PDP::GetTemperature(double &tempC) +{ + GET_STATUS3(); + uint32_t raw = rx->temp; tempC = ((double)raw-67.8564500484966)*1.03250836957542; - if(GetTimeSinceLastRx()>=50) - return CTR_RxTimeout; - return CTR_OKAY; -} -void PDP::SetDeviceNumber(UINT8 deviceNumber){ - PDP_Settings.deviceNumber = deviceNumber; - PDP_Settings.frameIDs[0] = 0x8041400 + (deviceNumber) + (UINT32) (0 * BIT6); - PDP_Settings.frameIDs[1] = 0x8041400 + (deviceNumber) + (UINT32) (1 * BIT6); - PDP_Settings.frameIDs[2] = 0x8041400 + (deviceNumber) + (UINT32) (2 * BIT6); -} -void PDP::GetErrorInfo( uint32_t * timeSinceLastRx, - uint32_t * numFailedRxs) -{ - if(timeSinceLastRx) *timeSinceLastRx = _timeSinceLastRx; - if(numFailedRxs) *numFailedRxs = _numFailedRxs; -} -//------------------ CAN interface and thread --------------------------------------------// -/* Search for PCM Status Frame on CAN bus */ -uint64_t PDP::ReadCurrents(uint8_t api) -{ - uint64_t frame = 0; - UINT8 size = 0; - INT32 status = 0; - UINT32 timeStamp = 0; - - FRC_NetworkCommunication_CANSessionMux_receiveMessage(&PDP_Settings.frameIDs[api], kFullMessageIDMask, (uint8_t *)&frame, &size, &timeStamp, &status); - if (status == 0) { - _timeSinceLastRx = 0; - } else { - ++_numFailedRxs; - } - return frame; -} -void * PDP::ThreadFunc() -{ - while(_threadIsRunning){ - /* reads */ - uint64_t frame1 = ReadCurrents(0); - uint64_t frame2 = ReadCurrents(1); - uint64_t frame3 = ReadCurrents(2); - /* update stats */ - memcpy(&_status1,&frame1,8); - memcpy(&_status2,&frame2,8); - memcpy(&_status3,&frame3,8); - /* yield for 25ms */ - usleep(25e3); - /* timeouts */ - if(_timeSinceLastRx < 60000) - _timeSinceLastRx += 20; - } - return 0; -} -void * PDP::ThreadFunc( void *ptr ) -{ - return ((PDP*)ptr)->ThreadFunc(); + return rx.err; } //------------------ C interface --------------------------------------------// extern "C" { @@ -163,6 +148,5 @@ extern "C" { } void c_SetDeviceNumber_PDP(void * handle,UINT8 deviceNumber) { - return ((PDP*)handle)-> SetDeviceNumber(deviceNumber); } } diff --git a/hal/lib/Athena/ctre/PDP.h b/hal/lib/Athena/ctre/PDP.h index 4cf7f694bd..e840fc2177 100644 --- a/hal/lib/Athena/ctre/PDP.h +++ b/hal/lib/Athena/ctre/PDP.h @@ -1,60 +1,17 @@ #ifndef PDP_H_ #define PDP_H_ -#include "ctre.h" /* BIT Defines + Typedefs */ +#include "ctre.h" //BIT Defines + Typedefs #include //CAN Comm +#include "CtreCanNode.h" #include -/* encoder/decoders */ -typedef struct _PdpStatus1_t{ - unsigned chan1_h8:8; - unsigned chan2_h6:6; - unsigned chan1_l2:2; - unsigned chan3_h4:4; - unsigned chan2_l4:4; - unsigned chan4_h2:2; - unsigned chan3_l6:6; - unsigned chan4_l8:8; - unsigned chan5_h8:8; - unsigned chan6_h6:6; - unsigned chan5_l2:2; - unsigned reserved4:4; - unsigned chan6_l4:4; -}PdpStatus1_t; -typedef struct _PdpStatus2_t{ - unsigned chan7_h8:8; - unsigned chan8_h6:6; - unsigned chan7_l2:2; - unsigned chan9_h4:4; - unsigned chan8_l4:4; - unsigned chan10_h2:2; - unsigned chan9_l6:6; - unsigned chan10_l8:8; - unsigned chan11_h8:8; - unsigned chan12_h6:6; - unsigned chan11_l2:2; - unsigned reserved4:4; - unsigned chan12_l4:4; -}PdpStatus2_t; -typedef struct _PdpStatus3_t{ - unsigned chan13_h8:8; - unsigned chan14_h6:6; - unsigned chan13_l2:2; - unsigned chan15_h4:4; - unsigned chan14_l4:4; - unsigned chan16_h2:2; - unsigned chan15_l6:6; - unsigned chan16_l8:8; - unsigned internalResBattery_mOhms:8; - unsigned busVoltage:8; - unsigned temp:8; -}PdpStatus3_t; -class PDP +class PDP : public CtreCanNode { public: /* Get PDP Channel Current * * @Param - deviceNumber - Device ID for PDP. Factory default is 60. Function defaults to 60. */ - PDP(UINT8 deviceNumber=60); + PDP(UINT8 deviceNumber=0); ~PDP(); /* Get PDP Channel Current * @@ -81,40 +38,8 @@ public: * @Param - status - Temperature of PDP in Centigrade / Celcius (C) */ CTR_Code GetTemperature(double &status); - /* Set PDP Device Number - * - * @Return - void - * - * @Param - deviceNumber - Device number of PDP to control - */ - void SetDeviceNumber(UINT8 deviceNumber); - /* Get time since last received frame - * @Return - int - Returns time in milliseconds (ms) since last received PCM frame - */ - int GetTimeSinceLastRx(void) { return _timeSinceLastRx;} private: - /* frames to receive */ - PdpStatus1_t _status1; - PdpStatus2_t _status2; - PdpStatus3_t _status3; - /* tracking health and error info */ - uint32_t _timeSinceLastRx; - uint32_t _timeSinceLastTx; - uint32_t _numFailedRxs; - uint32_t _numFailedTxs; - /* threading */ - pthread_t _thread; - int _threadErr; - int _threadIsRunning; - /** arbids */ - struct PDPSettings{ - UINT8 deviceNumber; - UINT32 frameIDs[3]; - }PDP_Settings; uint64_t ReadCurrents(uint8_t api); - void GetErrorInfo( uint32_t * timeSinceLastRx,uint32_t * numFailedRxs); - static void * ThreadFunc(void *); - void * ThreadFunc(); }; extern "C" { void * c_PDP_Init(); diff --git a/hal/lib/Athena/ctre/ctre.h b/hal/lib/Athena/ctre/ctre.h index 5cd5e082ac..49dc2f6cf3 100644 --- a/hal/lib/Athena/ctre/ctre.h +++ b/hal/lib/Athena/ctre/ctre.h @@ -46,13 +46,15 @@ typedef enum { * the last 50ms. Function returns the latest received data * but may be STALE DATA. */ - CTR_TxTimeout /* + CTR_TxTimeout, /* * Transmission Timeout * * No module-specific CAN frames were transmitted in * the last 50ms. Parameters passed in by the user are loaded * for next transmission but have not sent. */ + CTR_InvalidParamValue, + CTR_UnexpectedArbId, }CTR_Code; #endif