mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
CAN isn't fully working yet, but this change is necessary to compile for the v9 image. Change-Id: Ife99686a7e7a9979c95ec7a395d597011090fa37
169 lines
5.2 KiB
C++
169 lines
5.2 KiB
C++
#include "PDP.h"
|
|
#include "NetworkCommunication/CANSessionMux.h" //CAN Comm
|
|
#include <string.h> // memset
|
|
#include <unistd.h> // usleep
|
|
|
|
#define kFullMessageIDMask 0x1fffffff
|
|
|
|
PDP::PDP(UINT8 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);
|
|
}
|
|
/* PDP D'tor
|
|
*/
|
|
PDP::~PDP() {
|
|
/* wait for thread to finish */
|
|
_threadIsRunning = 0;
|
|
pthread_join( _thread, NULL);
|
|
_thread = 0;
|
|
}
|
|
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;
|
|
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;
|
|
}
|
|
}
|
|
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 <= 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;
|
|
}
|
|
}
|
|
/* convert to amps */
|
|
current = 0.06724511900000001*raw + 1.527114967;
|
|
/* signal caller with success */
|
|
if(GetTimeSinceLastRx()>=50)
|
|
return CTR_RxTimeout;
|
|
return CTR_OKAY;
|
|
}
|
|
CTR_Code PDP::GetVoltage(double &voltage){
|
|
uint32_t raw = _status3.busVoltage;
|
|
voltage = 0.0554413328606877 * raw;
|
|
if(GetTimeSinceLastRx()>=50)
|
|
return CTR_RxTimeout;
|
|
return CTR_OKAY;
|
|
}
|
|
|
|
CTR_Code PDP::GetTemperature(double &tempC){
|
|
uint32_t raw = _status3.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();
|
|
}
|
|
//------------------ C interface --------------------------------------------//
|
|
extern "C" {
|
|
void * c_PDP_Init(void)
|
|
{
|
|
return new PDP();
|
|
}
|
|
CTR_Code c_GetChannelCurrent(void * handle,UINT8 idx, double *status)
|
|
{
|
|
return ((PDP*)handle)-> GetChannelCurrent(idx,*status);
|
|
}
|
|
CTR_Code c_GetVoltage(void * handle,double *status)
|
|
{
|
|
return ((PDP*)handle)-> GetVoltage(*status);
|
|
}
|
|
CTR_Code c_GetTemperature(void * handle,double *status)
|
|
{
|
|
return ((PDP*)handle)-> GetTemperature(*status);
|
|
}
|
|
void c_SetDeviceNumber_PDP(void * handle,UINT8 deviceNumber)
|
|
{
|
|
return ((PDP*)handle)-> SetDeviceNumber(deviceNumber);
|
|
}
|
|
}
|