Code:
/** @brief Transmits detection data over UART
*
* The following data is transmitted:
* 1. Header (size = 32bytes), including "Magic word", (size = 8 bytes)
* and including the number of TLV items
* TLV Items:
* 2. If detectedObjects flag is 1 or 2, DPIF_PointCloudCartesian structure containing
* X,Y,Z location and velocity for detected objects,
* size = sizeof(DPIF_PointCloudCartesian) * number of detected objects
* 3. If detectedObjects flag is 1, DPIF_PointCloudSideInfo structure containing SNR
* and noise for detected objects,
* size = sizeof(DPIF_PointCloudCartesian) * number of detected objects
* 4. If logMagRange flag is set, rangeProfile,
* size = number of range bins * sizeof(uint16_t)
* 5. If noiseProfile flag is set, noiseProfile,
* size = number of range bins * sizeof(uint16_t)
* 6. If rangeAzimuthHeatMap flag is set, the zero Doppler column of the
* range cubed matrix, size = number of Rx Azimuth virtual antennas *
* number of chirps per frame * sizeof(uint32_t)
* 7. If rangeDopplerHeatMap flag is set, the log magnitude range-Doppler matrix,
* size = number of range bins * number of Doppler bins * sizeof(uint16_t)
* 8. If statsInfo flag is set, the stats information
* @param[in] uartHandle UART driver handle
* @param[in] result Pointer to result from object detection DPC processing
* @param[in] timingInfo Pointer to timing information provided from core that runs data path
*/
staticvoid MmwDemo_transmitProcessedOutput
(
UART_Handle uartHandle,
DPC_ObjectDetection_ExecuteResult *result,
MmwDemo_output_message_stats *timingInfo
)
{
MmwDemo_output_message_header header;
MmwDemo_GuiMonSel *pGuiMonSel;
MmwDemo_SubFrameCfg *subFrameCfg;
uint32_t tlvIdx = 0;
uint32_t index;
uint32_t numPaddingBytes;
uint32_t packetLen;
uint8_t padding[MMWDEMO_OUTPUT_MSG_SEGMENT_LEN];
MmwDemo_output_message_tl tl[MMWDEMO_OUTPUT_MSG_MAX];
int32_t errCode;
uint16_t *detMatrix = (uint16_t *)result->detMatrix.data;
DPIF_PointCloudCartesian *objOut;
cmplx16ImRe_t *azimuthStaticHeatMap;
DPIF_PointCloudSideInfo *objOutSideInfo;
DPC_ObjectDetection_Stats *stats;
/* Get subframe configuration */
subFrameCfg = &gMmwMssMCB.subFrameCfg[result->subFrameIdx];
/* Get Gui Monitor configuration */
pGuiMonSel = &subFrameCfg->guiMonSel;
/* Clear message header */
memset((void *)&header, 0, sizeof(MmwDemo_output_message_header));
/******************************************************************
Send out data that is enabled, Since processing results are from DSP,
address translation is needed for buffer pointers
*******************************************************************/
{
detMatrix = (uint16_t *) SOC_translateAddress((uint32_t)detMatrix,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,
&errCode);
DebugP_assert ((uint32_t)detMatrix!= SOC_TRANSLATEADDR_INVALID);
objOut = (DPIF_PointCloudCartesian *) SOC_translateAddress((uint32_t)result->objOut,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,
&errCode);
DebugP_assert ((uint32_t)objOut != SOC_TRANSLATEADDR_INVALID);
objOutSideInfo = (DPIF_PointCloudSideInfo *) SOC_translateAddress((uint32_t)result->objOutSideInfo,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,
&errCode);
DebugP_assert ((uint32_t)objOutSideInfo != SOC_TRANSLATEADDR_INVALID);
stats = (DPC_ObjectDetection_Stats *) SOC_translateAddress((uint32_t)result->stats,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,
&errCode);
DebugP_assert ((uint32_t)stats != SOC_TRANSLATEADDR_INVALID);
result->radarCube.data = (void *) SOC_translateAddress((uint32_t) result->radarCube.data,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,
&errCode);
DebugP_assert ((uint32_t) result->radarCube.data!= SOC_TRANSLATEADDR_INVALID);
}
/* Header: */
header.platform = 0xA6843;
header.magicWord[0] = 0x0102;
header.magicWord[1] = 0x0304;
header.magicWord[2] = 0x0506;
header.magicWord[3] = 0x0708;
header.numDetectedObj = result->numObjOut;
header.version = MMWAVE_SDK_VERSION_BUILD |
(MMWAVE_SDK_VERSION_BUGFIX << 8) |
(MMWAVE_SDK_VERSION_MINOR << 16) |
(MMWAVE_SDK_VERSION_MAJOR << 24);
packetLen = sizeof(MmwDemo_output_message_header);
if ((pGuiMonSel->detectedObjects == 1) || (pGuiMonSel->detectedObjects == 2) &&
(result->numObjOut > 0))
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_DETECTED_POINTS;
tl[tlvIdx].length = sizeof(DPIF_PointCloudCartesian) * result->numObjOut;
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
/* Side info */
if ((pGuiMonSel->detectedObjects == 1) && (result->numObjOut > 0))
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_DETECTED_POINTS_SIDE_INFO;
tl[tlvIdx].length = sizeof(DPIF_PointCloudSideInfo) * result->numObjOut;
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
if (pGuiMonSel->logMagRange)
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_RANGE_PROFILE;
tl[tlvIdx].length = sizeof(uint16_t) * subFrameCfg->numRangeBins;
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
if (pGuiMonSel->noiseProfile)
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_NOISE_PROFILE;
tl[tlvIdx].length = sizeof(uint16_t) * subFrameCfg->numRangeBins;
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
if (pGuiMonSel->rangeAzimuthHeatMap)
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_AZIMUT_STATIC_HEAT_MAP;
tl[tlvIdx].length = result->azimuthStaticHeatMapSize * sizeof(cmplx16ImRe_t);
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
if (pGuiMonSel->rangeDopplerHeatMap)
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_RANGE_DOPPLER_HEAT_MAP;
tl[tlvIdx].length = subFrameCfg->numRangeBins * subFrameCfg->numDopplerBins * sizeof(uint16_t);
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
if (pGuiMonSel->statsInfo)
{
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_STATS;
tl[tlvIdx].length = sizeof(MmwDemo_output_message_stats);
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
MmwDemo_getTemperatureReport();
tl[tlvIdx].type = MMWDEMO_OUTPUT_MSG_TEMPERATURE_STATS;
tl[tlvIdx].length = sizeof(MmwDemo_temperatureStats);
packetLen += sizeof(MmwDemo_output_message_tl) + tl[tlvIdx].length;
tlvIdx++;
}
header.numTLVs = tlvIdx;
/* Round up packet length to multiple of MMWDEMO_OUTPUT_MSG_SEGMENT_LEN */
header.totalPacketLen = MMWDEMO_OUTPUT_MSG_SEGMENT_LEN *
((packetLen + (MMWDEMO_OUTPUT_MSG_SEGMENT_LEN-1))/MMWDEMO_OUTPUT_MSG_SEGMENT_LEN);
header.timeCpuCycles = Pmu_getCount(0);
header.frameNumber = stats->frameStartIntCounter;
header.subFrameNumber = result->subFrameIdx;
UART_writePolling (uartHandle,
(uint8_t*)&header,
sizeof(MmwDemo_output_message_header));
tlvIdx = 0;
/* Send detected Objects */
if ((pGuiMonSel->detectedObjects == 1) || (pGuiMonSel->detectedObjects == 2) &&
(result->numObjOut > 0))
{
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
/*Send array of objects */
UART_writePolling (uartHandle, (uint8_t*)objOut,
sizeof(DPIF_PointCloudCartesian) * result->numObjOut);
tlvIdx++;
}
/* Send detected Objects Side Info */
if ((pGuiMonSel->detectedObjects == 1) && (result->numObjOut > 0))
{
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
UART_writePolling (uartHandle, (uint8_t*)objOutSideInfo,
sizeof(DPIF_PointCloudSideInfo) * result->numObjOut);
tlvIdx++;
}
/* Send Range profile */
if (pGuiMonSel->logMagRange)
{
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
for(index = 0; index < subFrameCfg->numRangeBins; index++)
{
UART_writePolling (uartHandle,
(uint8_t*)&detMatrix[index*subFrameCfg->numDopplerBins],
sizeof(uint16_t));
}
tlvIdx++;
}
/* Send noise profile */
if (pGuiMonSel->noiseProfile)
{
uint32_t maxDopIdx = subFrameCfg->numDopplerBins/2 -1;
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
for(index = 0; index < subFrameCfg->numRangeBins; index++)
{
UART_writePolling (uartHandle,
(uint8_t*)&detMatrix[index*subFrameCfg->numDopplerBins + maxDopIdx],
sizeof(uint16_t));
}
tlvIdx++;
}
/* Send data for static azimuth heatmap */
if (pGuiMonSel->rangeAzimuthHeatMap)
{
azimuthStaticHeatMap = (cmplx16ImRe_t *) SOC_translateAddress((uint32_t)result->azimuthStaticHeatMap,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,
&errCode);
DebugP_assert ((uint32_t)azimuthStaticHeatMap!= SOC_TRANSLATEADDR_INVALID);
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
UART_writePolling (uartHandle,
(uint8_t *)azimuthStaticHeatMap,
result->azimuthStaticHeatMapSize * sizeof(cmplx16ImRe_t));
tlvIdx++;
}
/* Send data for range/Doppler heatmap */
if (pGuiMonSel->rangeDopplerHeatMap == 1)
{
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
UART_writePolling (uartHandle,
(uint8_t*)detMatrix,
tl[tlvIdx].length);
tlvIdx++;
}
/* Send stats information */
if (pGuiMonSel->statsInfo == 1)
{
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
/* Address translation is done when buffer is received*/
UART_writePolling (uartHandle,
(uint8_t*)timingInfo,
tl[tlvIdx].length);
tlvIdx++;
UART_writePolling (uartHandle,
(uint8_t*)&tl[tlvIdx],
sizeof(MmwDemo_output_message_tl));
UART_writePolling (uartHandle,
(uint8_t*)&gMmwMssMCB.temperatureStats,
tl[tlvIdx].length);
tlvIdx++;
}
/* Send padding bytes */
numPaddingBytes = MMWDEMO_OUTPUT_MSG_SEGMENT_LEN - (packetLen & (MMWDEMO_OUTPUT_MSG_SEGMENT_LEN-1));
if (numPaddingBytes<MMWDEMO_OUTPUT_MSG_SEGMENT_LEN)
{
UART_writePolling (uartHandle,
(uint8_t*)padding,
numPaddingBytes);
}
}