From 0ef5c3adfa5b681f4d7ec598395d636a6254adfe Mon Sep 17 00:00:00 2001 From: Omar Zrien Date: Sun, 29 Jun 2014 16:49:00 -0400 Subject: [PATCH] PDP and PCM updated to rely on CtreCanNode parent class, which uses new CAN API. CtreCanNode registers the periodic tx messages and provides an rx function to child classes for easy getters and setters. Some template magic to make the PDP and PCM getters/setters easy to stamp out. Change-Id: Ibdd0745af070756a282df5074504491fadfde336 --- hal/lib/Athena/ctre/CtreCanNode.cpp | 99 ++++++ hal/lib/Athena/ctre/CtreCanNode.h | 116 +++++++ hal/lib/Athena/ctre/PCM.cpp | 508 +++++++++++++--------------- hal/lib/Athena/ctre/PCM.h | 157 +-------- hal/lib/Athena/ctre/PDP.cpp | 228 ++++++------- hal/lib/Athena/ctre/PDP.h | 83 +---- hal/lib/Athena/ctre/ctre.h | 4 +- 7 files changed, 580 insertions(+), 615 deletions(-) create mode 100644 hal/lib/Athena/ctre/CtreCanNode.cpp create mode 100644 hal/lib/Athena/ctre/CtreCanNode.h 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