diff --git a/hal/include/HAL/CAN.hpp b/hal/include/HAL/CAN.hpp deleted file mode 100644 index 80b589ceee..0000000000 --- a/hal/include/HAL/CAN.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include "NetworkCommunication/CANSessionMux.h" - -void canTxSend(uint32_t arbID, uint8_t length, int32_t period = CAN_SEND_PERIOD_NO_REPEAT); - -void canTxPackInt8 (uint32_t arbID, uint8_t offset, uint8_t value); -void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value); -void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value); -void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value); -void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value); - -uint8_t canTxUnpackInt8 (uint32_t arbID, uint8_t offset); -uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset); -uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset); -double canTxUnpackFXP16(uint32_t arbID, uint8_t offset); -double canTxUnpackFXP32(uint32_t arbID, uint8_t offset); - -bool canRxReceive(uint32_t arbID); - -uint8_t canRxUnpackInt8 (uint32_t arbID, uint8_t offset); -uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset); -uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset); -double canRxUnpackFXP16(uint32_t arbID, uint8_t offset); -double canRxUnpackFXP32(uint32_t arbID, uint8_t offset); diff --git a/hal/include/HAL/HAL.hpp b/hal/include/HAL/HAL.hpp index b3771fb422..05a18cdfe9 100644 --- a/hal/include/HAL/HAL.hpp +++ b/hal/include/HAL/HAL.hpp @@ -14,7 +14,6 @@ #include "Accelerometer.hpp" #include "Analog.hpp" -#include "CAN.hpp" #include "Compressor.hpp" #include "Digital.hpp" #include "Solenoid.hpp" diff --git a/hal/lib/Athena/CAN.cpp b/hal/lib/Athena/CAN.cpp deleted file mode 100644 index c524996b7b..0000000000 --- a/hal/lib/Athena/CAN.cpp +++ /dev/null @@ -1,232 +0,0 @@ -#include "HAL/CAN.hpp" -#include - -struct CANMessage -{ - uint8_t data[8]; -}; - -static std::map outgoingMessages; -static std::map incomingMessages; - -static const uint32_t kFullMessageIDMask = 0x1fffffff; - -/** - * Gets the data from the outgoing hashmap and calls - * CANSessionMux...sendMessage. - */ -void canTxSend(uint32_t arbID, uint8_t length, int32_t period) -{ - CANMessage &message = outgoingMessages[arbID]; - - int32_t status; - - FRC_NetworkCommunication_CANSessionMux_sendMessage( - arbID, message.data, length, period, &status); -} - -/** - * Updates a field in the outgoing hashmap. - * - * This is called every time an single byte field changes in a message.data, - * such as when a setter on a CAN device is called. - */ -void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value) -{ - CANMessage &message = outgoingMessages[arbID]; - - message.data[offset] = value; -} - -/** - * Updates a field in the outgoing hashmap. - * - * This is called every time a short integer field changes in a message.data, - * such as when a setter on a CAN device is called. - */ -void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value) -{ - CANMessage &message = outgoingMessages[arbID]; - - *(uint16_t *)(message.data + offset) = value; -} - -/** - * Updates a field in the outgoing hashmap. - * - * This is called every time a long integer field changes in a message.data, - * such as when a setter on a CAN device is called. - */ -void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value) -{ - CANMessage &message = outgoingMessages[arbID]; - - *(uint32_t *)(message.data + offset) = value; -} - -/** - * Updates a field in the outgoing hashmap. - * - * This is called every time an 8.8 fixed point field changes in a message, - * such as when a setter on a CAN device is called. - */ -void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value) -{ - int16_t raw = value * 255.0; - - canTxPackInt16(arbID, offset, raw); -} - -/** - * Updates a field in the outgoing hashmap. - * - * This is called every time a 16.16 fixed point field changes in a message, - * such as when a setter on a CAN device is called. - */ -void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value) -{ - int32_t raw = value * 65535.0; - - canTxPackInt32(arbID, offset, raw); -} - -/** - * Unpack a field from the outgoing hashmap. - * - * This is called in getters for configuration data. - */ -uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset) -{ - CANMessage &message = outgoingMessages[arbID]; - - return message.data[offset]; -} - -/** - * Unpack a field from the outgoing hashmap. - * - * This is called in getters for configuration data. - */ -uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset) -{ - CANMessage &message = outgoingMessages[arbID]; - - return *reinterpret_cast(message.data + offset); -} - -/** - * Unpack a field from the outgoing hashmap. - * - * This is called in getters for configuration data. - */ -uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset) -{ - CANMessage &message = outgoingMessages[arbID]; - - return *reinterpret_cast(message.data + offset); -} - -/** - * Unpack a field from the outgoing hashmap. - * - * This is called in getters for configuration data. - */ -double canTxUnpackFXP16(uint32_t arbID, uint8_t offset) -{ - int16_t raw = canTxUnpackInt16(arbID, offset); - - return raw / 255.0; -} - -/** - * Unpack a field from the outgoing hashmap. - * - * This is called in getters for configuration data. - */ -double canTxUnpackFXP32(uint32_t arbID, uint8_t offset) -{ - int32_t raw = canTxUnpackInt32(arbID, offset); - - return raw / 65535.0; -} - -/** - * Get data from CANSessionMux (if it's available) and put it in the incoming - * hashmap. - * - * @return true if there's new data. Otherwise, the last received value should - * still be in the hashmap. - */ -bool canRxReceive(uint32_t arbID) -{ - CANMessage &message = incomingMessages[arbID]; - - uint8_t length; - uint32_t timestamp; - int32_t status; - - FRC_NetworkCommunication_CANSessionMux_receiveMessage( - &arbID, kFullMessageIDMask, message.data, &length, ×tamp, &status); - - return status != ERR_CANSessionMux_MessageNotFound; -} - -/** - * Unpack a field from the incoming hashmap. - * - * This is called in getters for status data. - */ -uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset) -{ - CANMessage &message = incomingMessages[arbID]; - - return message.data[offset]; -} - -/** - * Unpack a field from the incoming hashmap. - * - * This is called in getters for status data. - */ -uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset) -{ - CANMessage &message = incomingMessages[arbID]; - - return *reinterpret_cast(message.data + offset); -} - -/** - * Unpack a field from the incoming hashmap. - * - * This is called in getters for status data. - */ -uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset) -{ - CANMessage &message = incomingMessages[arbID]; - - return *reinterpret_cast(message.data + offset); -} - -/** - * Unpack a field from the incoming hashmap. - * - * This is called in getters for status data. - */ -double canRxUnpackFXP16(uint32_t arbID, uint8_t offset) -{ - int16_t raw = canRxUnpackInt16(arbID, offset); - - return raw / 255.0; -} - -/** - * Unpack a field from the incoming hashmap. - * - * This is called in getters for status data. - */ -double canRxUnpackFXP32(uint32_t arbID, uint8_t offset) -{ - int32_t raw = canRxUnpackInt32(arbID, offset); - - return raw / 65535.0; -} diff --git a/hal/lib/Athena/HAL.cpp b/hal/lib/Athena/HAL.cpp index 8512c1ae86..125bf79f1b 100644 --- a/hal/lib/Athena/HAL.cpp +++ b/hal/lib/Athena/HAL.cpp @@ -8,6 +8,7 @@ #include "NetworkCommunication/FRCComm.h" #include "NetworkCommunication/UsageReporting.h" #include "NetworkCommunication/LoadOut.h" +#include "NetworkCommunication/CANSessionMux.h" #include #include #include diff --git a/hal/lib/Athena/ctre/CanTalonSRX.cpp b/hal/lib/Athena/ctre/CanTalonSRX.cpp new file mode 100644 index 0000000000..befaddfde0 --- /dev/null +++ b/hal/lib/Athena/ctre/CanTalonSRX.cpp @@ -0,0 +1,608 @@ +/** + * auto generated using spreadsheet and WpiClassGen.csproj + * @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967 + */ +#include "CanTalonSRX.h" +#include "NetworkCommunication/CANSessionMux.h" //CAN Comm +#include // memset +#include // usleep + +#define STATUS_1 0x02041400 +#define STATUS_2 0x02041440 +#define STATUS_3 0x02041480 +#define STATUS_4 0x020414C0 +#define STATUS_5 0x02041500 +#define STATUS_6 0x02041540 +#define STATUS_7 0x02041580 + +#define CONTROL_1 0x02040000 + +#define EXPECTED_RESPONSE_TIMEOUT_MS (200) +#define GET_STATUS1() CtreCanNode::recMsg rx = GetRx(STATUS_1 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS2() CtreCanNode::recMsg rx = GetRx(STATUS_2 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS3() CtreCanNode::recMsg rx = GetRx(STATUS_3 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS4() CtreCanNode::recMsg rx = GetRx(STATUS_4 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS5() CtreCanNode::recMsg rx = GetRx(STATUS_5 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS6() CtreCanNode::recMsg rx = GetRx(STATUS_6 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) +#define GET_STATUS7() CtreCanNode::recMsg rx = GetRx(STATUS_7 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS) + +/* encoder/decoders */ +/** control */ +typedef struct _TALON_Control_1_General_10ms_t { + unsigned TokenH:8; + unsigned TokenL:8; + unsigned Demand24H:8; + unsigned Demand24M:8; + unsigned Demand24L:8; + unsigned CloseLoopCellSelect:1; + unsigned SelectlFeedbackDevice:4; + unsigned LimitSwitchEn:3; + unsigned RevEncoderPosAndVel:1; + unsigned RevMotDuringCloseLoopEn:1; + unsigned BrakeType:2; + unsigned ModeSelect:4; + unsigned RampThrottle:8; +} TALON_Control_1_General_10ms_t ; +typedef struct _TALON_Control_2_Rates_OneShot_t { + unsigned Status1Ms:8; + unsigned Status2Ms:8; + unsigned Status3Ms:8; + unsigned Status4Ms:8; +} TALON_Control_2_Rates_OneShot_t ; +typedef struct _TALON_Control_3_ClearFlags_OneShot_t { + unsigned ZeroFeedbackSensor:1; + unsigned ClearStickyFaults:1; +} TALON_Control_3_ClearFlags_OneShot_t ; + +/** status */ +typedef struct _TALON_Status_1_General_10ms_t { + unsigned CloseLoopErrH:8; + unsigned CloseLoopErrM:8; + unsigned CloseLoopErrL:8; + unsigned Throttle_h3:3; + unsigned Fault_RevSoftLim:1; + unsigned Fault_ForSoftLim:1; + unsigned TokLocked:1; + unsigned LimitSwitchClosedRev:1; + unsigned LimitSwitchClosedFor:1; + unsigned Throttle_l8:8; + unsigned ModeSelect_h1:1; + unsigned SelectlFeedbackDevice:4; + unsigned LimitSwitchEn:3; + unsigned Fault_HardwareFailure:1; + unsigned Fault_RevLim:1; + unsigned Fault_ForLim:1; + unsigned Fault_UnderVoltage:1; + unsigned Fault_OverTemp:1; + unsigned ModeSelect_b3:3; + unsigned TokenSeed:8; +} TALON_Status_1_General_10ms_t ; +typedef struct _TALON_Status_2_Feedback_20ms_t { + unsigned SensorPositionH:8; + unsigned SensorPositionM:8; + unsigned SensorPositionL:8; + unsigned SensorVelocityH:8; + unsigned SensorVelocityL:8; + unsigned Current_h8:8; + unsigned StckyFault_RevSoftLim:1; + unsigned StckyFault_ForSoftLim:1; + unsigned StckyFault_RevLim:1; + unsigned StckyFault_ForLim:1; + unsigned StckyFault_UnderVoltage:1; + unsigned StckyFault_OverTemp:1; + unsigned Current_l2:2; + unsigned reserved:6; + unsigned CloseLoopCellSelect:1; + unsigned BrakeIsEnabled:1; +} TALON_Status_2_Feedback_20ms_t ; +typedef struct _TALON_Status_3_Enc_100ms_t { + unsigned EncPositionH:8; + unsigned EncPositionM:8; + unsigned EncPositionL:8; + unsigned EncVelH:8; + unsigned EncVelL:8; + unsigned EncIndexRiseEventsH:8; + unsigned EncIndexRiseEventsL:8; + unsigned reserved:5; + unsigned QuadIdxpin:1; + unsigned QuadBpin:1; + unsigned QuadApin:1; +} TALON_Status_3_Enc_100ms_t ; +typedef struct _TALON_Status_4_AinTempVbat_100ms_t { + unsigned AnalogInWithOvH:8; + unsigned AnalogInWithOvM:8; + unsigned AnalogInWithOvL:8; + unsigned AnalogInVelH:8; + unsigned AnalogInVelL:8; + unsigned Temp:8; + unsigned BatteryV:8; + unsigned reserved:8; +} TALON_Status_4_AinTempVbat_100ms_t ; +typedef struct _TALON_Status_5_Startup_OneShot_t { + unsigned ResetCountH:8; + unsigned ResetCountL:8; + unsigned ResetFlagsH:8; + unsigned ResetFlagsL:8; + unsigned FirmVersH:8; + unsigned FirmVersL:8; +} TALON_Status_5_Startup_OneShot_t ; +typedef struct _TALON_Status_6_Eol_t { + unsigned currentAdcUncal_h2:2; + unsigned reserved1:5; + unsigned SpiCsPin_GadgeteerPin6:1; + unsigned currentAdcUncal_l8:8; + unsigned tempAdcUncal_h2:2; + unsigned reserved2:6; + unsigned tempAdcUncal_l8:8; + unsigned vbatAdcUncal_h2:2; + unsigned reserved3:6; + unsigned vbatAdcUncal_l8:8; + unsigned analogAdcUncal_h2:2; + unsigned reserved4:6; + unsigned analogAdcUncal_l8:8; +} TALON_Status_6_Eol_t ; +typedef struct _TALON_Status_7_Debug_200ms_t { + unsigned TokenizationFails_h8:8; + unsigned TokenizationFails_l8:8; + unsigned LastFailedToken_h8:8; + unsigned LastFailedToken_l8:8; + unsigned TokenizationSucceses_h8:8; + unsigned TokenizationSucceses_l8:8; +} TALON_Status_7_Debug_200ms_t ; +typedef struct _TALON_Config_SetGains0_1_t { + unsigned PH:8; + unsigned PM:8; + unsigned PL:8; + unsigned IH:8; + unsigned IM:8; + unsigned IL:8; + unsigned IZoneH:8; + unsigned IZoneL:8; +} TALON_Config_SetGains0_1_t ; +typedef struct _TALON_Config_SetGains0_2_t { + unsigned DH:8; + unsigned DM:8; + unsigned DL:8; + unsigned FH:8; + unsigned FM:8; + unsigned FL:8; + unsigned RampRateH:8; + unsigned RampRateL:8; +} TALON_Config_SetGains0_2_t ; +typedef struct _TALON_Config_SetGains1_1_t { + unsigned PH:8; + unsigned PM:8; + unsigned PL:8; + unsigned IH:8; + unsigned IM:8; + unsigned IL:8; + unsigned IZoneH:8; + unsigned IZoneL:8; +} TALON_Config_SetGains1_1_t ; +typedef struct _TALON_Config_SetGains1_2_t { + unsigned DH:8; + unsigned DM:8; + unsigned DL:8; + unsigned FH:8; + unsigned FM:8; + unsigned FL:8; + unsigned RampRateH:8; + unsigned RampRateL:8; +} TALON_Config_SetGains1_2_t ; +typedef struct _TALON_Config_SetSoftLimits_t { + unsigned LimitFH:8; + unsigned LimitFMH:8; + unsigned LimitFML:8; + unsigned LimitFL:8; + unsigned LimitRH:8; + unsigned LimitRMH:8; + unsigned LimitRML:8; + unsigned LimitRL:8; +} TALON_Config_SetSoftLimits_t ; +typedef struct _TALON_Param_Request_t { + unsigned ParamEnum:8; +} TALON_Param_Request_t ; +typedef struct _TALON_Param_Response_t { + unsigned ParamEnum:8; + unsigned ParamValueH:8; + unsigned ParamValueMH:8; + unsigned ParamValueML:8; + unsigned ParamValueL:8; +} TALON_Param_Response_t ; + + +CanTalonSRX::CanTalonSRX(UINT8 deviceNumber): CtreCanNode(deviceNumber) +{ + RegisterRx(STATUS_1 | deviceNumber ); + RegisterRx(STATUS_2 | deviceNumber ); + RegisterRx(STATUS_3 | deviceNumber ); + RegisterRx(STATUS_4 | deviceNumber ); + RegisterRx(STATUS_5 | deviceNumber ); + RegisterRx(STATUS_6 | deviceNumber ); + RegisterRx(STATUS_7 | deviceNumber ); + RegisterTx(CONTROL_1 | deviceNumber, 10); +} +/* CanTalonSRX D'tor + */ +CanTalonSRX::~CanTalonSRX() +{ +} +void CanTalonSRX::Set(double value) +{ + if(value > 1) + value = 1; + else if(value < -1) + value = -1; + value *= 1023; + SetDemand24(value); /* must be within [-1023,1023] */ +} +/*------------------------ auto generated ----------------------*/ + +CTR_Code CanTalonSRX::GetFault_OverTemp(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_OverTemp; + return rx.err; +} +CTR_Code CanTalonSRX::GetFault_UnderVoltage(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_UnderVoltage; + return rx.err; +} +CTR_Code CanTalonSRX::GetFault_ForLim(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_ForLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetFault_RevLim(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_RevLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetFault_HardwareFailure(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_HardwareFailure; + return rx.err; +} +CTR_Code CanTalonSRX::GetFault_ForSoftLim(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_ForSoftLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetFault_RevSoftLim(int ¶m) +{ + GET_STATUS1(); + param = rx->Fault_RevSoftLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetStckyFault_OverTemp(int ¶m) +{ + GET_STATUS2(); + param = rx->StckyFault_OverTemp; + return rx.err; +} +CTR_Code CanTalonSRX::GetStckyFault_UnderVoltage(int ¶m) +{ + GET_STATUS2(); + param = rx->StckyFault_UnderVoltage; + return rx.err; +} +CTR_Code CanTalonSRX::GetStckyFault_ForLim(int ¶m) +{ + GET_STATUS2(); + param = rx->StckyFault_ForLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetStckyFault_RevLim(int ¶m) +{ + GET_STATUS2(); + param = rx->StckyFault_RevLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetStckyFault_ForSoftLim(int ¶m) +{ + GET_STATUS2(); + param = rx->StckyFault_ForSoftLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetStckyFault_RevSoftLim(int ¶m) +{ + GET_STATUS2(); + param = rx->StckyFault_RevSoftLim; + return rx.err; +} +CTR_Code CanTalonSRX::GetAppliedThrottle11(int ¶m) +{ + GET_STATUS1(); + uint32_t raw = 0; + raw |= rx->Throttle_h3; + raw <<= 8; + raw |= rx->Throttle_l8; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetCloseLoopErr(int ¶m) +{ + GET_STATUS1(); + uint32_t raw = 0; + raw |= rx->CloseLoopErrH; + raw <<= 16; + raw |= rx->CloseLoopErrM; + raw <<= 8; + raw |= rx->CloseLoopErrL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetSelectlFeedbackDevice(int ¶m) +{ + GET_STATUS1(); + param = rx->SelectlFeedbackDevice; + return rx.err; +} +CTR_Code CanTalonSRX::GetModeSelect(int ¶m) +{ + GET_STATUS1(); + uint32_t raw = 0; + raw |= rx->ModeSelect_h1; + raw <<= 3; + raw |= rx->ModeSelect_b3; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetLimitSwitchEn(int ¶m) +{ + GET_STATUS1(); + param = rx->LimitSwitchEn; + return rx.err; +} +CTR_Code CanTalonSRX::GetLimitSwitchClosedFor(int ¶m) +{ + GET_STATUS1(); + param = rx->LimitSwitchClosedFor; + return rx.err; +} +CTR_Code CanTalonSRX::GetLimitSwitchClosedRev(int ¶m) +{ + GET_STATUS1(); + param = rx->LimitSwitchClosedRev; + return rx.err; +} +CTR_Code CanTalonSRX::GetCloseLoopCellSelect(int ¶m) +{ + GET_STATUS2(); + param = rx->CloseLoopCellSelect; + return rx.err; +} +CTR_Code CanTalonSRX::GetSensorPosition(int ¶m) +{ + GET_STATUS2(); + uint32_t raw = 0; + raw |= rx->SensorPositionH; + raw <<= 16; + raw |= rx->SensorPositionM; + raw <<= 8; + raw |= rx->SensorPositionL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetSensorVelocity(int ¶m) +{ + GET_STATUS2(); + uint32_t raw = 0; + raw |= rx->SensorVelocityH; + raw <<= 8; + raw |= rx->SensorVelocityL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetCurrent(double ¶m) +{ + GET_STATUS2(); + uint32_t raw = 0; + raw |= rx->Current_h8; + raw <<= 2; + raw |= rx->Current_l2; + param = (double)raw * 0.125 + 0; + return rx.err; +} +CTR_Code CanTalonSRX::GetBrakeIsEnabled(int ¶m) +{ + GET_STATUS2(); + param = rx->BrakeIsEnabled; + return rx.err; +} +CTR_Code CanTalonSRX::GetEncPosition(int ¶m) +{ + GET_STATUS3(); + uint32_t raw = 0; + raw |= rx->EncPositionH; + raw <<= 16; + raw |= rx->EncPositionM; + raw <<= 8; + raw |= rx->EncPositionL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetEncVel(int ¶m) +{ + GET_STATUS3(); + uint32_t raw = 0; + raw |= rx->EncVelH; + raw <<= 8; + raw |= rx->EncVelL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetEncIndexRiseEvents(int ¶m) +{ + GET_STATUS3(); + uint32_t raw = 0; + raw |= rx->EncIndexRiseEventsH; + raw <<= 8; + raw |= rx->EncIndexRiseEventsL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetQuadApin(int ¶m) +{ + GET_STATUS3(); + param = rx->QuadApin; + return rx.err; +} +CTR_Code CanTalonSRX::GetQuadBpin(int ¶m) +{ + GET_STATUS3(); + param = rx->QuadBpin; + return rx.err; +} +CTR_Code CanTalonSRX::GetQuadIdxpin(int ¶m) +{ + GET_STATUS3(); + param = rx->QuadIdxpin; + return rx.err; +} +CTR_Code CanTalonSRX::GetAnalogInWithOv(int ¶m) +{ + GET_STATUS4(); + uint32_t raw = 0; + raw |= rx->AnalogInWithOvH; + raw <<= 16; + raw |= rx->AnalogInWithOvM; + raw <<= 8; + raw |= rx->AnalogInWithOvL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetAnalogInVel(int ¶m) +{ + GET_STATUS4(); + uint32_t raw = 0; + raw |= rx->AnalogInVelH; + raw <<= 8; + raw |= rx->AnalogInVelL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetTemp(double ¶m) +{ + GET_STATUS4(); + uint32_t raw = rx->Temp; + param = (double)raw * 0.6451612903 + -50; + return rx.err; +} +CTR_Code CanTalonSRX::GetBatteryV(double ¶m) +{ + GET_STATUS4(); + uint32_t raw = rx->BatteryV; + param = (double)raw * 0.05 + 4; + return rx.err; +} +CTR_Code CanTalonSRX::GetResetCount(int ¶m) +{ + GET_STATUS5(); + uint32_t raw = 0; + raw |= rx->ResetCountH; + raw <<= 8; + raw |= rx->ResetCountL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetResetFlags(int ¶m) +{ + GET_STATUS5(); + uint32_t raw = 0; + raw |= rx->ResetFlagsH; + raw <<= 8; + raw |= rx->ResetFlagsL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::GetFirmVers(int ¶m) +{ + GET_STATUS5(); + uint32_t raw = 0; + raw |= rx->FirmVersH; + raw <<= 8; + raw |= rx->FirmVersL; + param = (int)raw; + return rx.err; +} +CTR_Code CanTalonSRX::SetDemand24(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->Demand24H = param>>16; + toFill->Demand24M = param>>8; + toFill->Demand24L = param>>0; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetLimitSwitchEn(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->LimitSwitchEn = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetSelectlFeedbackDevice(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->SelectlFeedbackDevice = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetRevMotDuringCloseLoopEn(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->RevMotDuringCloseLoopEn = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetBrakeType(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->BrakeType = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetModeSelect(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->ModeSelect = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetCloseLoopCellSelect(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->CloseLoopCellSelect = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetRampThrottle(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->RampThrottle = param; + FlushTx(toFill); + return CTR_OKAY; +} +CTR_Code CanTalonSRX::SetRevEncoderPosAndVel(int param) +{ + CtreCanNode::txTask toFill = GetTx(CONTROL_1 | GetDeviceNumber()); + if (toFill.IsEmpty()) return CTR_UnexpectedArbId; + toFill->RevEncoderPosAndVel = param; + FlushTx(toFill); + return CTR_OKAY; +} diff --git a/hal/lib/Athena/ctre/CanTalonSRX.h b/hal/lib/Athena/ctre/CanTalonSRX.h new file mode 100644 index 0000000000..549d04dec8 --- /dev/null +++ b/hal/lib/Athena/ctre/CanTalonSRX.h @@ -0,0 +1,67 @@ +/** + * auto generated using spreadsheet and WpiClassGen.csproj + * @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967 + */ +#ifndef CanTalonSRX_H_ +#define CanTalonSRX_H_ +#include "ctre.h" //BIT Defines + Typedefs +#include "CtreCanNode.h" +#include //CAN Comm +class CanTalonSRX : public CtreCanNode +{ +public: + CanTalonSRX(UINT8 deviceNumber=0); + ~CanTalonSRX(); + void Set(double value); + + /*------------------------ auto generated ----------------------*/ + CTR_Code GetFault_OverTemp(int ¶m); + CTR_Code GetFault_UnderVoltage(int ¶m); + CTR_Code GetFault_ForLim(int ¶m); + CTR_Code GetFault_RevLim(int ¶m); + CTR_Code GetFault_HardwareFailure(int ¶m); + CTR_Code GetFault_ForSoftLim(int ¶m); + CTR_Code GetFault_RevSoftLim(int ¶m); + CTR_Code GetStckyFault_OverTemp(int ¶m); + CTR_Code GetStckyFault_UnderVoltage(int ¶m); + CTR_Code GetStckyFault_ForLim(int ¶m); + CTR_Code GetStckyFault_RevLim(int ¶m); + CTR_Code GetStckyFault_ForSoftLim(int ¶m); + CTR_Code GetStckyFault_RevSoftLim(int ¶m); + CTR_Code GetAppliedThrottle11(int ¶m); + CTR_Code GetCloseLoopErr(int ¶m); + CTR_Code GetSelectlFeedbackDevice(int ¶m); + CTR_Code GetModeSelect(int ¶m); + CTR_Code GetLimitSwitchEn(int ¶m); + CTR_Code GetLimitSwitchClosedFor(int ¶m); + CTR_Code GetLimitSwitchClosedRev(int ¶m); + CTR_Code GetCloseLoopCellSelect(int ¶m); + CTR_Code GetSensorPosition(int ¶m); + CTR_Code GetSensorVelocity(int ¶m); + CTR_Code GetCurrent(double ¶m); + CTR_Code GetBrakeIsEnabled(int ¶m); + CTR_Code GetEncPosition(int ¶m); + CTR_Code GetEncVel(int ¶m); + CTR_Code GetEncIndexRiseEvents(int ¶m); + CTR_Code GetQuadApin(int ¶m); + CTR_Code GetQuadBpin(int ¶m); + CTR_Code GetQuadIdxpin(int ¶m); + CTR_Code GetAnalogInWithOv(int ¶m); + CTR_Code GetAnalogInVel(int ¶m); + CTR_Code GetTemp(double ¶m); + CTR_Code GetBatteryV(double ¶m); + CTR_Code GetResetCount(int ¶m); + CTR_Code GetResetFlags(int ¶m); + CTR_Code GetFirmVers(int ¶m); + CTR_Code SetDemand24(int param); + CTR_Code SetLimitSwitchEn(int param); + CTR_Code SetSelectlFeedbackDevice(int param); + CTR_Code SetRevMotDuringCloseLoopEn(int param); + CTR_Code SetBrakeType(int param); + CTR_Code SetModeSelect(int param); + CTR_Code SetCloseLoopCellSelect(int param); + CTR_Code SetRampThrottle(int param); + CTR_Code SetRevEncoderPosAndVel(int param); +}; +#endif + diff --git a/hal/lib/Athena/ctre/CtreCanNode.cpp b/hal/lib/Athena/ctre/CtreCanNode.cpp index 30a31a024a..b2e3620284 100644 --- a/hal/lib/Athena/ctre/CtreCanNode.cpp +++ b/hal/lib/Athena/ctre/CtreCanNode.cpp @@ -1,98 +1,101 @@ -#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; - 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); -} +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + +#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 index 263fcdb2fd..7a2d69054e 100644 --- a/hal/lib/Athena/ctre/CtreCanNode.h +++ b/hal/lib/Athena/ctre/CtreCanNode.h @@ -1,121 +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; - txJob_t() : arbId(0),periodMs(0) - { - for(unsigned i=0;i txJobs_t; - txJobs_t _txJobs; - - typedef std::map rxRxEvents_t; - rxRxEvents_t _rxRxEvents; -}; -#endif +#ifndef CtreCanNode_H_ +#define CtreCanNode_H_ +#include "ctre.h" //BIT Defines + Typedefs +#include //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, nullptr}; + txJobs_t::iterator i = _txJobs.find(arbId); + if(i != _txJobs.end()){ + retval.arbId = i->second.arbId; + retval.toSend = (T*)i->second.toSend; + } + return retval; + } + template 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/wpilibc/wpilibC++Devices/include/CANTalon.h b/wpilibc/wpilibC++Devices/include/CANTalon.h new file mode 100644 index 0000000000..1f17059dcd --- /dev/null +++ b/wpilibc/wpilibC++Devices/include/CANTalon.h @@ -0,0 +1,30 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2014. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ +/*----------------------------------------------------------------------------*/ +#pragma once + +#include "SafePWM.h" +#include "SpeedController.h" +#include "PIDOutput.h" + +class CanTalonSRX; + +/** + * CTRE Talon SRX Speed Controller + */ +class CANTalon : public MotorSafety, + public SpeedController, + public ErrorBase +{ +public: + explicit CANTalon(uint8_t deviceNumber); + virtual ~CANTalon(); + virtual void Set(float value, uint8_t syncGroup = 0) override; + virtual float Get() override; + virtual void Disable() override; + +private: + CanTalonSRX *m_impl; +}; diff --git a/wpilibc/wpilibC++Devices/include/WPILib.h b/wpilibc/wpilibC++Devices/include/WPILib.h index 6f75749d7a..dabdd2d057 100644 --- a/wpilibc/wpilibC++Devices/include/WPILib.h +++ b/wpilibc/wpilibC++Devices/include/WPILib.h @@ -23,6 +23,7 @@ #include "Buttons/JoystickButton.h" #include "Buttons/NetworkButton.h" #include "CANJaguar.h" +#include "CANTalon.h" #include "Commands/Command.h" #include "Commands/CommandGroup.h" #include "Commands/PIDCommand.h" diff --git a/wpilibc/wpilibC++Devices/include/ctre/CanTalonSRX.h b/wpilibc/wpilibC++Devices/include/ctre/CanTalonSRX.h new file mode 100644 index 0000000000..549d04dec8 --- /dev/null +++ b/wpilibc/wpilibC++Devices/include/ctre/CanTalonSRX.h @@ -0,0 +1,67 @@ +/** + * auto generated using spreadsheet and WpiClassGen.csproj + * @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967 + */ +#ifndef CanTalonSRX_H_ +#define CanTalonSRX_H_ +#include "ctre.h" //BIT Defines + Typedefs +#include "CtreCanNode.h" +#include //CAN Comm +class CanTalonSRX : public CtreCanNode +{ +public: + CanTalonSRX(UINT8 deviceNumber=0); + ~CanTalonSRX(); + void Set(double value); + + /*------------------------ auto generated ----------------------*/ + CTR_Code GetFault_OverTemp(int ¶m); + CTR_Code GetFault_UnderVoltage(int ¶m); + CTR_Code GetFault_ForLim(int ¶m); + CTR_Code GetFault_RevLim(int ¶m); + CTR_Code GetFault_HardwareFailure(int ¶m); + CTR_Code GetFault_ForSoftLim(int ¶m); + CTR_Code GetFault_RevSoftLim(int ¶m); + CTR_Code GetStckyFault_OverTemp(int ¶m); + CTR_Code GetStckyFault_UnderVoltage(int ¶m); + CTR_Code GetStckyFault_ForLim(int ¶m); + CTR_Code GetStckyFault_RevLim(int ¶m); + CTR_Code GetStckyFault_ForSoftLim(int ¶m); + CTR_Code GetStckyFault_RevSoftLim(int ¶m); + CTR_Code GetAppliedThrottle11(int ¶m); + CTR_Code GetCloseLoopErr(int ¶m); + CTR_Code GetSelectlFeedbackDevice(int ¶m); + CTR_Code GetModeSelect(int ¶m); + CTR_Code GetLimitSwitchEn(int ¶m); + CTR_Code GetLimitSwitchClosedFor(int ¶m); + CTR_Code GetLimitSwitchClosedRev(int ¶m); + CTR_Code GetCloseLoopCellSelect(int ¶m); + CTR_Code GetSensorPosition(int ¶m); + CTR_Code GetSensorVelocity(int ¶m); + CTR_Code GetCurrent(double ¶m); + CTR_Code GetBrakeIsEnabled(int ¶m); + CTR_Code GetEncPosition(int ¶m); + CTR_Code GetEncVel(int ¶m); + CTR_Code GetEncIndexRiseEvents(int ¶m); + CTR_Code GetQuadApin(int ¶m); + CTR_Code GetQuadBpin(int ¶m); + CTR_Code GetQuadIdxpin(int ¶m); + CTR_Code GetAnalogInWithOv(int ¶m); + CTR_Code GetAnalogInVel(int ¶m); + CTR_Code GetTemp(double ¶m); + CTR_Code GetBatteryV(double ¶m); + CTR_Code GetResetCount(int ¶m); + CTR_Code GetResetFlags(int ¶m); + CTR_Code GetFirmVers(int ¶m); + CTR_Code SetDemand24(int param); + CTR_Code SetLimitSwitchEn(int param); + CTR_Code SetSelectlFeedbackDevice(int param); + CTR_Code SetRevMotDuringCloseLoopEn(int param); + CTR_Code SetBrakeType(int param); + CTR_Code SetModeSelect(int param); + CTR_Code SetCloseLoopCellSelect(int param); + CTR_Code SetRampThrottle(int param); + CTR_Code SetRevEncoderPosAndVel(int param); +}; +#endif + diff --git a/wpilibc/wpilibC++Devices/include/ctre/CtreCanNode.h b/wpilibc/wpilibC++Devices/include/ctre/CtreCanNode.h new file mode 100644 index 0000000000..59e09398f0 --- /dev/null +++ b/wpilibc/wpilibC++Devices/include/ctre/CtreCanNode.h @@ -0,0 +1,116 @@ +#ifndef CtreCanNode_H_ +#define CtreCanNode_H_ +#include "ctre.h" //BIT Defines + Typedefs +#include //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/wpilibc/wpilibC++Devices/include/ctre/ctre.h b/wpilibc/wpilibC++Devices/include/ctre/ctre.h new file mode 100644 index 0000000000..49dc2f6cf3 --- /dev/null +++ b/wpilibc/wpilibC++Devices/include/ctre/ctre.h @@ -0,0 +1,60 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +//Bit Defines +#define BIT0 0x01 +#define BIT1 0x02 +#define BIT2 0x04 +#define BIT3 0x08 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 +#define BIT8 0x0100 +#define BIT9 0x0200 +#define BIT10 0x0400 +#define BIT11 0x0800 +#define BIT12 0x1000 +#define BIT13 0x2000 +#define BIT14 0x4000 +#define BIT15 0x8000 + +//Signed +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef signed long long INT64; + +//Unsigned +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef unsigned long long UINT64; + +//Other +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned int UINT; +typedef unsigned long ULONG; + +typedef enum { + CTR_OKAY, //No Error - Function executed as expected + CTR_RxTimeout, /* + * 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_Code; + +#endif diff --git a/wpilibc/wpilibC++Devices/src/CANTalon.cpp b/wpilibc/wpilibC++Devices/src/CANTalon.cpp new file mode 100644 index 0000000000..e8b5aecfbf --- /dev/null +++ b/wpilibc/wpilibC++Devices/src/CANTalon.cpp @@ -0,0 +1,30 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2014. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ +/*----------------------------------------------------------------------------*/ + +#include "CANTalon.h" +#include "ctre/CanTalonSRX.h" + +/** + * Constructor for the CANTalon device. + * @param deviceNumber The CAN ID of the Talon SRX + */ +CANTalon::CANTalon(uint8_t deviceNumber) { + m_impl = new CanTalonSRX(deviceNumber); +} + +CANTalon::~CANTalon() { + delete m_impl; +} + +void CANTalon::Set(float value, uint8_t syncGroup) { +} + +float CANTalon::Get() { + return 0.0f; +} + +void CANTalon::Disable() { +}