diff --git a/hal/include/HAL/PDP.hpp b/hal/include/HAL/PDP.hpp index af0b144535..3dde22b48f 100644 --- a/hal/include/HAL/PDP.hpp +++ b/hal/include/HAL/PDP.hpp @@ -11,4 +11,9 @@ extern "C" double getPDPTemperature(int32_t *status); double getPDPVoltage(int32_t *status); double getPDPChannelCurrent(uint8_t channel, int32_t *status); + double getPDPTotalCurrent(int32_t *status); + double getPDPTotalPower(int32_t *status); + double getPDPTotalEnergy(int32_t *status); + void resetPDPTotalEnergy(int32_t *status); + void clearPDPStickyFaults(int32_t *status); } diff --git a/hal/lib/Athena/PDP.cpp b/hal/lib/Athena/PDP.cpp index 8b66e0063b..6129c06ed5 100644 --- a/hal/lib/Athena/PDP.cpp +++ b/hal/lib/Athena/PDP.cpp @@ -26,3 +26,36 @@ double getPDPChannelCurrent(uint8_t channel, int32_t *status) { return current; } +double getPDPTotalCurrent(int32_t *status) { + double current; + + *status = pdp.GetTotalCurrent(current); + + return current; +} + +double getPDPTotalPower(int32_t *status) { + double power; + + *status = pdp.GetTotalPower(power); + + return power; +} + +double getPDPTotalEnergy(int32_t *status) { + double energy; + + *status = pdp.GetTotalEnergy(energy); + + return energy; +} + +void resetPDPTotalEnergy(int32_t *status) { + *status = pdp.ResetEnergy(); +} + +void clearPDPStickyFaults(int32_t *status) { + *status = pdp.ClearStickyFaults(); +} + + diff --git a/hal/lib/Athena/ctre/PDP.cpp b/hal/lib/Athena/ctre/PDP.cpp index 8c79c1d1cd..2fb4c8f2d4 100644 --- a/hal/lib/Athena/ctre/PDP.cpp +++ b/hal/lib/Athena/ctre/PDP.cpp @@ -6,11 +6,15 @@ #define STATUS_1 0x8041400 #define STATUS_2 0x8041440 #define STATUS_3 0x8041480 +#define STATUS_ENERGY 0x8041740 + +#define CONTROL_1 0x08041C00 /* PDP_Control_ClearStats */ #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) +#define GET_STATUS_ENERGY() CtreCanNode::recMsg rx = GetRx(STATUS_ENERGY,EXPECTED_RESPONSE_TIMEOUT_MS) /* encoder/decoders */ typedef struct _PdpStatus1_t{ @@ -56,6 +60,18 @@ typedef struct _PdpStatus3_t{ unsigned busVoltage:8; unsigned temp:8; }PdpStatus3_t; +typedef struct _PDP_Status_Energy_t { + unsigned TmeasMs_likelywillbe20ms_:8; + unsigned TotalCurrent_125mAperunit_h8:8; + unsigned Power_125mWperunit_h4:4; + unsigned TotalCurrent_125mAperunit_l4:4; + unsigned Power_125mWperunit_m8:8; + unsigned Energy_125mWPerUnitXTmeas_h4:4; + unsigned Power_125mWperunit_l4:4; + unsigned Energy_125mWPerUnitXTmeas_mh8:8; + unsigned Energy_125mWPerUnitXTmeas_ml8:8; + unsigned Energy_125mWPerUnitXTmeas_l8:8; +} PDP_Status_Energy_t ; PDP::PDP(UINT8 deviceNumber): CtreCanNode(deviceNumber) { @@ -128,6 +144,68 @@ CTR_Code PDP::GetTemperature(double &tempC) tempC = (double)raw * 1.03250836957542 - 67.8564500484966; return rx.err; } +CTR_Code PDP::GetTotalCurrent(double ¤tAmps) +{ + GET_STATUS_ENERGY(); + uint32_t raw; + raw = rx->TotalCurrent_125mAperunit_h8; + raw <<= 4; + raw |= rx->TotalCurrent_125mAperunit_l4; + currentAmps = 0.125 * raw; + return rx.err; +} +CTR_Code PDP::GetTotalPower(double &powerWatts) +{ + GET_STATUS_ENERGY(); + uint32_t raw; + raw = rx->Power_125mWperunit_h4; + raw <<= 8; + raw |= rx->Power_125mWperunit_m8; + raw <<= 4; + raw |= rx->Power_125mWperunit_l4; + powerWatts = 0.125 * raw; + return rx.err; +} +CTR_Code PDP::GetTotalEnergy(double &energyJoules) +{ + GET_STATUS_ENERGY(); + uint32_t raw; + raw = rx->Energy_125mWPerUnitXTmeas_h4; + raw <<= 8; + raw |= rx->Energy_125mWPerUnitXTmeas_mh8; + raw <<= 8; + raw |= rx->Energy_125mWPerUnitXTmeas_ml8; + raw <<= 8; + raw |= rx->Energy_125mWPerUnitXTmeas_l8; + energyJoules = 0.125 * raw; /* mW integrated every TmeasMs */ + energyJoules *= rx->TmeasMs_likelywillbe20ms_; /* multiplied by TmeasMs = joules */ + return rx.err; +} +/* Clear sticky faults. + * @Return - CTR_Code - Error code (if any) + */ +CTR_Code PDP::ClearStickyFaults() +{ + int32_t status = 0; + uint8_t pdpControl[] = { 0x80 }; /* only bit set is ClearStickyFaults */ + FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1 | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status); + if(status) + return CTR_TxFailed; + return CTR_OKAY; +} + +/* Reset Energy Signals + * @Return - CTR_Code - Error code (if any) + */ +CTR_Code PDP::ResetEnergy() +{ + int32_t status = 0; + uint8_t pdpControl[] = { 0x40 }; /* only bit set is ResetEnergy */ + FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1 | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status); + if(status) + return CTR_TxFailed; + return CTR_OKAY; +} //------------------ C interface --------------------------------------------// extern "C" { void * c_PDP_Init(void) diff --git a/hal/lib/Athena/ctre/PDP.h b/hal/lib/Athena/ctre/PDP.h index e840fc2177..a289d1a1fe 100644 --- a/hal/lib/Athena/ctre/PDP.h +++ b/hal/lib/Athena/ctre/PDP.h @@ -38,6 +38,19 @@ public: * @Param - status - Temperature of PDP in Centigrade / Celcius (C) */ CTR_Code GetTemperature(double &status); + + CTR_Code GetTotalCurrent(double ¤tAmps); + CTR_Code GetTotalPower(double &powerWatts); + CTR_Code GetTotalEnergy(double &energyJoules); + /* Clear sticky faults. + * @Return - CTR_Code - Error code (if any) + */ + CTR_Code ClearStickyFaults(); + + /* Reset Energy Signals + * @Return - CTR_Code - Error code (if any) + */ + CTR_Code ResetEnergy(); private: uint64_t ReadCurrents(uint8_t api); }; diff --git a/hal/lib/Athena/ctre/ctre.h b/hal/lib/Athena/ctre/ctre.h index 49dc2f6cf3..c2d3f69614 100644 --- a/hal/lib/Athena/ctre/ctre.h +++ b/hal/lib/Athena/ctre/ctre.h @@ -38,23 +38,13 @@ typedef unsigned int UINT; typedef unsigned long ULONG; typedef enum { - CTR_OKAY, //No Error - Function executed as expected - CTR_RxTimeout, /* - * Receive Timeout - * - * No module-specific CAN frames have been received in - * the last 50ms. Function returns the latest received data - * but may be STALE DATA. - */ - 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_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_Code; #endif diff --git a/wpilibc/wpilibC++Devices/include/PowerDistributionPanel.h b/wpilibc/wpilibC++Devices/include/PowerDistributionPanel.h index e94d3d784b..31e228ca06 100644 --- a/wpilibc/wpilibC++Devices/include/PowerDistributionPanel.h +++ b/wpilibc/wpilibC++Devices/include/PowerDistributionPanel.h @@ -21,6 +21,11 @@ class PowerDistributionPanel : public SensorBase { double GetVoltage(); double GetTemperature(); double GetCurrent(uint8_t channel); + double GetTotalCurrent(); + double GetTotalPower(); + double GetTotalEnergy(); + void ResetTotalEnergy(); + void ClearStickyFaults(); }; #endif /* __WPILIB_POWER_DISTRIBUTION_PANEL_H__ */ diff --git a/wpilibc/wpilibC++Devices/src/PowerDistributionPanel.cpp b/wpilibc/wpilibC++Devices/src/PowerDistributionPanel.cpp index fa434b1130..468ce7c648 100644 --- a/wpilibc/wpilibC++Devices/src/PowerDistributionPanel.cpp +++ b/wpilibc/wpilibC++Devices/src/PowerDistributionPanel.cpp @@ -69,3 +69,80 @@ PowerDistributionPanel::GetCurrent(uint8_t channel) { return current; } +/** + * @return The the total current drawn from the PDP channels in Amperes + */ +double +PowerDistributionPanel::GetTotalCurrent() { + int32_t status = 0; + + double current = getPDPTotalCurrent(&status); + + if(status) { + wpi_setWPIErrorWithContext(Timeout, ""); + } + + return current; +} + +/** + * @return The the total power drawn from the PDP channels in Joules + */ +double +PowerDistributionPanel::GetTotalPower() { + int32_t status = 0; + + double power = getPDPTotalPower(&status); + + if(status) { + wpi_setWPIErrorWithContext(Timeout, ""); + } + + return power; +} + +/** + * @return The the total energy drawn from the PDP channels in Watts + */ +double +PowerDistributionPanel::GetTotalEnergy() { + int32_t status = 0; + + double energy = getPDPTotalEnergy(&status); + + if(status) { + wpi_setWPIErrorWithContext(Timeout, ""); + } + + return energy; +} + +/** + * Reset the total energy drawn from the PDP + * @see PowerDistributionPanel#GetTotalEnergy + */ +void +PowerDistributionPanel::ResetTotalEnergy() { + int32_t status = 0; + + resetPDPTotalEnergy(&status); + + if(status) { + wpi_setWPIErrorWithContext(Timeout, ""); + } +} + +/** + * Remove all of the fault flags on the PDP + */ +void +PowerDistributionPanel::ClearStickyFaults() { + int32_t status = 0; + + clearPDPStickyFaults(&status); + + if(status) { + wpi_setWPIErrorWithContext(Timeout, ""); + } +} +