[hal] Add capability to read power distribution data as a stream (#4983)

This commit is contained in:
Thad House
2023-11-30 21:09:14 -08:00
committed by GitHub
parent 51eecef2bd
commit ca684ac207
7 changed files with 592 additions and 0 deletions

View File

@@ -281,4 +281,19 @@ void HAL_ReadCANPacketTimeout(HAL_CANHandle handle, int32_t apiId,
}
}
}
uint32_t HAL_StartCANStream(HAL_CANHandle handle, int32_t apiId, int32_t depth,
int32_t* status) {
auto can = canHandles->Get(handle);
if (!can) {
*status = HAL_HANDLE_ERROR;
return 0;
}
uint32_t messageId = CreateCANId(can.get(), apiId);
uint32_t session = 0;
HAL_CAN_OpenStreamSession(&session, messageId, 0x1FFFFFFF, depth, status);
return session;
}
} // extern "C"

View File

@@ -10,6 +10,7 @@
#include "HALInitializer.h"
#include "HALInternal.h"
#include "PortsInternal.h"
#include "hal/CAN.h"
#include "hal/CANAPI.h"
#include "hal/Errors.h"
#include "hal/handles/IndexedHandleResource.h"
@@ -107,6 +108,8 @@ namespace {
struct PDP {
HAL_CANHandle canHandle;
std::string previousAllocation;
bool streamHandleAllocated{false};
uint32_t streamSessionHandles[3];
};
} // namespace
@@ -523,4 +526,241 @@ void HAL_ClearPDPStickyFaults(HAL_PDPHandle handle, int32_t* status) {
HAL_WriteCANPacket(pdp->canHandle, pdpControl, 1, Control1, status);
}
uint32_t HAL_StartCANStream(HAL_CANHandle handle, int32_t apiId, int32_t depth,
int32_t* status);
void HAL_StartPDPStream(HAL_PDPHandle handle, int32_t* status) {
auto pdp = pdpHandles->Get(handle);
if (pdp == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
if (pdp->streamHandleAllocated) {
*status = RESOURCE_IS_ALLOCATED;
return;
}
pdp->streamSessionHandles[0] =
HAL_StartCANStream(pdp->canHandle, Status1, 50, status);
if (*status != 0) {
return;
}
pdp->streamSessionHandles[1] =
HAL_StartCANStream(pdp->canHandle, Status2, 50, status);
if (*status != 0) {
HAL_CAN_CloseStreamSession(pdp->streamSessionHandles[0]);
return;
}
pdp->streamSessionHandles[2] =
HAL_StartCANStream(pdp->canHandle, Status3, 50, status);
if (*status != 0) {
HAL_CAN_CloseStreamSession(pdp->streamSessionHandles[0]);
HAL_CAN_CloseStreamSession(pdp->streamSessionHandles[1]);
return;
}
pdp->streamHandleAllocated = true;
}
HAL_PowerDistributionChannelData* HAL_GetPDPStreamData(HAL_PDPHandle handle,
int32_t* count,
int32_t* status) {
auto pdp = pdpHandles->Get(handle);
if (pdp == nullptr) {
*status = HAL_HANDLE_ERROR;
return nullptr;
}
if (!pdp->streamHandleAllocated) {
*status = RESOURCE_OUT_OF_RANGE;
return nullptr;
}
*count = 0;
// 3 streams, 6 channels per stream, 50 depth per stream
HAL_PowerDistributionChannelData* retData =
new HAL_PowerDistributionChannelData[3 * 6 * 50];
HAL_CANStreamMessage messages[50];
uint32_t messagesRead = 0;
HAL_CAN_ReadStreamSession(pdp->streamSessionHandles[0], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PdpStatus1 pdpStatus;
std::memcpy(pdpStatus.data, messages[i].data, sizeof(messages[i].data));
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan1_h8) << 2) |
pdpStatus.bits.chan1_l2) *
0.125;
retData[*count].channel = 1;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan2_h6) << 4) |
pdpStatus.bits.chan2_l4) *
0.125;
retData[*count].channel = 2;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan3_h4) << 6) |
pdpStatus.bits.chan3_l6) *
0.125;
retData[*count].channel = 3;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan4_h2) << 8) |
pdpStatus.bits.chan4_l8) *
0.125;
retData[*count].channel = 4;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan5_h8) << 2) |
pdpStatus.bits.chan5_l2) *
0.125;
retData[*count].channel = 5;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan6_h6) << 4) |
pdpStatus.bits.chan6_l4) *
0.125;
retData[*count].channel = 6;
retData[*count].timestamp = timestamp;
(*count)++;
}
messagesRead = 0;
HAL_CAN_ReadStreamSession(pdp->streamSessionHandles[1], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PdpStatus2 pdpStatus;
std::memcpy(pdpStatus.data, messages[i].data, sizeof(messages[i].data));
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan7_h8) << 2) |
pdpStatus.bits.chan7_l2) *
0.125;
retData[*count].channel = 7;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan8_h6) << 4) |
pdpStatus.bits.chan8_l4) *
0.125;
retData[*count].channel = 8;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan9_h4) << 6) |
pdpStatus.bits.chan9_l6) *
0.125;
retData[*count].channel = 9;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan10_h2) << 8) |
pdpStatus.bits.chan10_l8) *
0.125;
retData[*count].channel = 10;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan11_h8) << 2) |
pdpStatus.bits.chan11_l2) *
0.125;
retData[*count].channel = 11;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan12_h6) << 4) |
pdpStatus.bits.chan12_l4) *
0.125;
retData[*count].channel = 12;
retData[*count].timestamp = timestamp;
(*count)++;
}
messagesRead = 0;
HAL_CAN_ReadStreamSession(pdp->streamSessionHandles[2], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PdpStatus3 pdpStatus;
std::memcpy(pdpStatus.data, messages[i].data, sizeof(messages[i].data));
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan13_h8) << 2) |
pdpStatus.bits.chan13_l2) *
0.125;
retData[*count].channel = 13;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan14_h6) << 4) |
pdpStatus.bits.chan14_l4) *
0.125;
retData[*count].channel = 14;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan15_h4) << 6) |
pdpStatus.bits.chan15_l6) *
0.125;
retData[*count].channel = 15;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
((static_cast<uint32_t>(pdpStatus.bits.chan16_h2) << 8) |
pdpStatus.bits.chan16_l8) *
0.125;
retData[*count].channel = 16;
retData[*count].timestamp = timestamp;
(*count)++;
}
Exit:
if (*status < 0) {
delete[] retData;
retData = nullptr;
}
return retData;
}
void HAL_StopPDPStream(HAL_PDPHandle handle, int32_t* status) {
auto pdp = pdpHandles->Get(handle);
if (pdp == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
if (!pdp->streamHandleAllocated) {
*status = RESOURCE_OUT_OF_RANGE;
return;
}
HAL_CAN_CloseStreamSession(pdp->streamSessionHandles[0]);
HAL_CAN_CloseStreamSession(pdp->streamSessionHandles[1]);
HAL_CAN_CloseStreamSession(pdp->streamSessionHandles[2]);
pdp->streamHandleAllocated = false;
}
} // extern "C"

View File

@@ -6,6 +6,7 @@
#include <stdint.h>
#include "hal/PowerDistribution.h"
#include "hal/Types.h"
/**
@@ -130,6 +131,15 @@ void HAL_ResetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status);
* @param handle the module handle
*/
void HAL_ClearPDPStickyFaults(HAL_PDPHandle handle, int32_t* status);
void HAL_StartPDPStream(HAL_PDPHandle handle, int32_t* status);
HAL_PowerDistributionChannelData* HAL_GetPDPStreamData(HAL_PDPHandle handle,
int32_t* count,
int32_t* status);
void HAL_StopPDPStream(HAL_PDPHandle handle, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -273,4 +273,36 @@ void HAL_GetPowerDistributionStickyFaults(
}
}
void HAL_StartPowerDistributionStream(HAL_PowerDistributionHandle handle,
int32_t* status) {
if (IsCtre(handle)) {
HAL_StartPDPStream(handle, status);
} else {
HAL_StartREVPDHStream(handle, status);
}
}
HAL_PowerDistributionChannelData* HAL_GetPowerDistributionStreamData(
HAL_PowerDistributionHandle handle, int32_t* count, int32_t* status) {
if (IsCtre(handle)) {
return HAL_GetPDPStreamData(handle, count, status);
} else {
return HAL_GetREVPDHStreamData(handle, count, status);
}
}
void HAL_FreePowerDistributionStreamData(HAL_PowerDistributionChannelData* data,
int32_t count) {
delete[] data;
}
void HAL_StopPowerDistributionStream(HAL_PowerDistributionHandle handle,
int32_t* status) {
if (IsCtre(handle)) {
HAL_StopPDPStream(handle, status);
} else {
HAL_StopREVPDHStream(handle, status);
}
}
} // extern "C"

View File

@@ -4,6 +4,7 @@
#include "REVPDH.h"
#include <hal/CAN.h>
#include <hal/CANAPI.h>
#include <hal/CANAPITypes.h>
#include <hal/Errors.h>
@@ -37,6 +38,8 @@ struct REV_PDHObj {
HAL_CANHandle hcan;
std::string previousAllocation;
HAL_PowerDistributionVersion versionInfo;
bool streamHandleAllocated{false};
uint32_t streamSessionHandles[4];
};
} // namespace
@@ -636,4 +639,271 @@ void HAL_ClearREVPDHStickyFaults(HAL_REVPDHHandle handle, int32_t* status) {
PDH_CLEAR_FAULTS_FRAME_API, status);
}
uint32_t HAL_StartCANStream(HAL_CANHandle handle, int32_t apiId, int32_t depth,
int32_t* status);
void HAL_StartREVPDHStream(HAL_REVPDHHandle handle, int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
if (hpdh->streamHandleAllocated) {
*status = RESOURCE_IS_ALLOCATED;
return;
}
hpdh->streamSessionHandles[0] =
HAL_StartCANStream(hpdh->hcan, PDH_STATUS_0_FRAME_API, 50, status);
if (*status != 0) {
return;
}
hpdh->streamSessionHandles[1] =
HAL_StartCANStream(hpdh->hcan, PDH_STATUS_1_FRAME_API, 50, status);
if (*status != 0) {
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[0]);
return;
}
hpdh->streamSessionHandles[2] =
HAL_StartCANStream(hpdh->hcan, PDH_STATUS_2_FRAME_API, 50, status);
if (*status != 0) {
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[0]);
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[1]);
return;
}
hpdh->streamSessionHandles[3] =
HAL_StartCANStream(hpdh->hcan, PDH_STATUS_3_FRAME_API, 50, status);
if (*status != 0) {
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[0]);
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[1]);
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[3]);
return;
}
hpdh->streamHandleAllocated = true;
}
HAL_PowerDistributionChannelData* HAL_GetREVPDHStreamData(
HAL_REVPDHHandle handle, int32_t* count, int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return nullptr;
}
if (!hpdh->streamHandleAllocated) {
*status = RESOURCE_OUT_OF_RANGE;
return nullptr;
}
*count = 0;
// 4 streams, 6 channels per stream, 50 depth per stream
HAL_PowerDistributionChannelData* retData =
new HAL_PowerDistributionChannelData[4 * 6 * 50];
HAL_CANStreamMessage messages[50];
uint32_t messagesRead = 0;
HAL_CAN_ReadStreamSession(hpdh->streamSessionHandles[0], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PDH_status_0_t statusFrame0;
PDH_status_0_unpack(&statusFrame0, messages[i].data, PDH_STATUS_0_LENGTH);
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
PDH_status_0_channel_0_current_decode(statusFrame0.channel_0_current);
retData[*count].channel = 1;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_0_channel_1_current_decode(statusFrame0.channel_1_current);
retData[*count].channel = 2;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_0_channel_2_current_decode(statusFrame0.channel_2_current);
retData[*count].channel = 3;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_0_channel_3_current_decode(statusFrame0.channel_3_current);
retData[*count].channel = 4;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_0_channel_4_current_decode(statusFrame0.channel_4_current);
retData[*count].channel = 5;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_0_channel_5_current_decode(statusFrame0.channel_5_current);
retData[*count].channel = 6;
retData[*count].timestamp = timestamp;
(*count)++;
}
messagesRead = 0;
HAL_CAN_ReadStreamSession(hpdh->streamSessionHandles[1], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PDH_status_1_t statusFrame1;
PDH_status_1_unpack(&statusFrame1, messages[i].data, PDH_STATUS_1_LENGTH);
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
PDH_status_1_channel_6_current_decode(statusFrame1.channel_6_current);
retData[*count].channel = 7;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_1_channel_7_current_decode(statusFrame1.channel_7_current);
retData[*count].channel = 8;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_1_channel_8_current_decode(statusFrame1.channel_8_current);
retData[*count].channel = 9;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_1_channel_9_current_decode(statusFrame1.channel_9_current);
retData[*count].channel = 10;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_1_channel_10_current_decode(statusFrame1.channel_10_current);
retData[*count].channel = 11;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_1_channel_11_current_decode(statusFrame1.channel_11_current);
retData[*count].channel = 12;
retData[*count].timestamp = timestamp;
(*count)++;
}
messagesRead = 0;
HAL_CAN_ReadStreamSession(hpdh->streamSessionHandles[2], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PDH_status_2_t statusFrame2;
PDH_status_2_unpack(&statusFrame2, messages[i].data, PDH_STATUS_2_LENGTH);
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
PDH_status_2_channel_12_current_decode(statusFrame2.channel_12_current);
retData[*count].channel = 13;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_2_channel_13_current_decode(statusFrame2.channel_13_current);
retData[*count].channel = 14;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_2_channel_14_current_decode(statusFrame2.channel_14_current);
retData[*count].channel = 15;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_2_channel_15_current_decode(statusFrame2.channel_15_current);
retData[*count].channel = 16;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_2_channel_16_current_decode(statusFrame2.channel_16_current);
retData[*count].channel = 17;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_2_channel_17_current_decode(statusFrame2.channel_17_current);
retData[*count].channel = 18;
retData[*count].timestamp = timestamp;
(*count)++;
}
messagesRead = 0;
HAL_CAN_ReadStreamSession(hpdh->streamSessionHandles[3], messages, 50,
&messagesRead, status);
if (*status < 0) {
goto Exit;
}
for (uint32_t i = 0; i < messagesRead; i++) {
PDH_status_3_t statusFrame3;
PDH_status_3_unpack(&statusFrame3, messages[i].data, PDH_STATUS_3_LENGTH);
uint32_t timestamp = messages[i].timeStamp;
retData[*count].current =
PDH_status_3_channel_18_current_decode(statusFrame3.channel_18_current);
retData[*count].channel = 19;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_3_channel_19_current_decode(statusFrame3.channel_19_current);
retData[*count].channel = 20;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_3_channel_20_current_decode(statusFrame3.channel_20_current);
retData[*count].channel = 21;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_3_channel_21_current_decode(statusFrame3.channel_21_current);
retData[*count].channel = 22;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_3_channel_22_current_decode(statusFrame3.channel_22_current);
retData[*count].channel = 23;
retData[*count].timestamp = timestamp;
(*count)++;
retData[*count].current =
PDH_status_3_channel_23_current_decode(statusFrame3.channel_23_current);
retData[*count].channel = 24;
retData[*count].timestamp = timestamp;
(*count)++;
}
Exit:
if (*status < 0) {
delete[] retData;
retData = nullptr;
}
return retData;
}
void HAL_StopREVPDHStream(HAL_REVPDHHandle handle, int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
if (!hpdh->streamHandleAllocated) {
*status = RESOURCE_OUT_OF_RANGE;
return;
}
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[0]);
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[1]);
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[2]);
HAL_CAN_CloseStreamSession(hpdh->streamSessionHandles[3]);
hpdh->streamHandleAllocated = false;
}
} // extern "C"

View File

@@ -158,6 +158,13 @@ void HAL_GetREVPDHStickyFaults(HAL_REVPDHHandle handle,
*/
void HAL_ClearREVPDHStickyFaults(HAL_REVPDHHandle handle, int32_t* status);
void HAL_StartREVPDHStream(HAL_REVPDHHandle handle, int32_t* status);
HAL_PowerDistributionChannelData* HAL_GetREVPDHStreamData(
HAL_REVPDHHandle handle, int32_t* count, int32_t* status);
void HAL_StopREVPDHStream(HAL_REVPDHHandle handle, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -324,6 +324,24 @@ void HAL_GetPowerDistributionStickyFaults(
HAL_PowerDistributionHandle handle,
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status);
void HAL_StartPowerDistributionStream(HAL_PowerDistributionHandle handle,
int32_t* status);
typedef struct HAL_PowerDistributionChannelData {
float current;
int32_t channel;
uint32_t timestamp;
} HAL_PowerDistributionChannelData;
HAL_PowerDistributionChannelData* HAL_GetPowerDistributionStreamData(
HAL_PowerDistributionHandle handle, int32_t* count, int32_t* status);
void HAL_FreePowerDistributionStreamData(HAL_PowerDistributionChannelData* data,
int32_t count);
void HAL_StopPowerDistributionStream(HAL_PowerDistributionHandle handle,
int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif