代码中的res->angleFftIn[txAntIdx * DPParams->numRxAntennas + rxAntIdx]是否就是存储用于测角的各天线的原始相位呢?代码来源是industrialtoolbox4_11_0中traffic monitoring的aoaprocdsp.c
static inline uint32_t AoAProcDSP_processMultipleVirtualAntennas
(
AOADspObj *aoaDspObj,
uint32_t numObjsIn,
uint32_t *numObjsOut,
volatile uint32_t *waitTime
)
{
uint16_t idx, rxAntIdx, rangeIdx, txAntIdx, dopplerIdx;
uint16_t nextTransferRxIdx, nextTransferRangeIdx, nextTransferTxIdx;
DPU_AoAProcDSP_HW_Resources *res;
DPU_AoAProcDSP_StaticConfig *DPParams;
cmplx16ImRe_t *inpDoppFftBuf;
cmplx32ReIm_t elevationSymbols[SYS_COMMON_NUM_RX_CHANNEL];
uint32_t numObjsOutLocal = 0;
volatile uint32_t startTimeWait;
int32_t retVal = 0;
cmplx16ImRe_t *radarCubeBase;
uint32_t pingPongIdx, nextTransferIdx;
uint8_t channel;
cmplx32ReIm_t *windowingBuf;
cmplx32ReIm_t *azimuthFftOut;
cmplx32ReIm_t *twoDfftOut;
/* for extMaxVelocity feature: */
cmplx32ReIm_t *hypothesesSymbols;
cmplx32ReIm_t *azimuthFftOutTemp;
int32_t dopplerSignIdx;
int32_t hypIdx, maxHypIdx;
float32_t maxPow, maxPowTemp;
int32_t wrapStartInd;
cmplx32ReIm_t *angleFftIn_copy;
res = &aoaDspObj->res;
DPParams = &aoaDspObj->params;
radarCubeBase = (cmplx16ImRe_t *)res->radarCube.data;
/* Setup overlayed buffers */
windowingBuf = (cmplx32ReIm_t *)res->scratch1Buff;
azimuthFftOut = (cmplx32ReIm_t *)res->scratch1Buff;
twoDfftOut = (cmplx32ReIm_t *)res->scratch2Buff;
/* Setup overlayed buffers for extMaxVelocity feature */
hypothesesSymbols = (cmplx32ReIm_t *)res->scratch2Buff;
azimuthFftOutTemp = res->elevationFftOut;
/* Angle estimation for each object */
for (idx = 0; idx < numObjsIn; idx++)
{
rangeIdx = res->cfarRngDopSnrList[idx].rangeIdx;
dopplerIdx = res->cfarRngDopSnrList[idx].dopplerIdx;
/* Reset ping/pong index */
pingPongIdx = DPU_AOAPROCDSP_PING_IDX;
/* Trigger first DMA. First transfer is for [txAntIdx=0, rxAntIdx=0, rangeIdx=(Obj range from CFAR list)].
Note: EDMA ping/pong scheme must support #TX antennas = 1,2,3 #RX antennas = 2,4 */
retVal = EDMA_setSourceAddress(res->edmaHandle,
res->edmaPing.channel,
(uint32_t) &radarCubeBase[rangeIdx]);
if (retVal != 0)
{
goto exit;
}
EDMA_startDmaTransfer(res->edmaHandle, res->edmaPing.channel);
for (rxAntIdx = 0; rxAntIdx < DPParams->numRxAntennas; rxAntIdx++)
{
for (txAntIdx = 0; txAntIdx < DPParams->numTxAntennas; txAntIdx++)
{
/* verify that previous DMA has completed */
startTimeWait = Cycleprofiler_getTimeStamp();
retVal = AoAProcDSP_waitInData (res, pingPongIdx);
if(retVal != 0)
{
goto exit;
}
*waitTime += Cycleprofiler_getTimeStamp() - startTimeWait;
/*Find index in radar cube for next EDMA.*/
nextTransferTxIdx = txAntIdx + 1;
nextTransferRxIdx = rxAntIdx;
nextTransferRangeIdx = rangeIdx;
if(nextTransferTxIdx == DPParams->numTxAntennas)
{
nextTransferTxIdx = 0;
nextTransferRxIdx++;
if(nextTransferRxIdx == DPParams->numRxAntennas)
{
nextTransferRxIdx = 0;
nextTransferRangeIdx++;
}
}
nextTransferIdx = (nextTransferTxIdx * DPParams->numRxAntennas * DPParams->numDopplerChirps +
nextTransferRxIdx) * DPParams->numRangeBins + nextTransferRangeIdx;
/*Last computation happens when nextTransferRangeIdx reaches (rangeIdx + 1) was we are processing
only one range index. Therefore, do not trigger next EDMA.*/
if(nextTransferRangeIdx == rangeIdx)
{
/* kick off next DMA */
if (pingPongIdx == DPU_AOAPROCDSP_PONG_IDX)
{
channel = res->edmaPing.channel;
}
else
{
channel = res->edmaPong.channel;
}
retVal = EDMA_setSourceAddress(res->edmaHandle, channel,
(uint32_t) &radarCubeBase[nextTransferIdx]);
if (retVal != 0)
{
goto exit;
}
EDMA_startDmaTransfer(res->edmaHandle, channel);
}
inpDoppFftBuf = (cmplx16ImRe_t *) &res->pingPongBuf[pingPongIdx * DPParams->numDopplerChirps];
/* Remove static clutter? */
if (aoaDspObj->dynLocalCfg.staticClutterCfg.isEnabled)
{
AoAProcDSP_clutterRemoval(DPParams, inpDoppFftBuf);
}
/* The windowing output buffer is the input buffer for the Doppler FFT.
It needs to be padded with zeroes if number of Doppler chirps is less than
the number of Doppler bins.*/
if(DPParams->numDopplerBins > DPParams->numDopplerChirps)
{
memset((void*)(&windowingBuf[DPParams->numDopplerChirps]), 0,
(DPParams->numDopplerBins - DPParams->numDopplerChirps) * sizeof(cmplx32ReIm_t));
}
/*Up to this point samples are in ImRe format, which is the radar cube format.
The windowing function will do IQ swap and the Doppler FFT is computed in
ReIm format.*/
mmwavelib_windowing16x32_IQswap((int16_t *) inpDoppFftBuf,
res->windowCoeff,
(int32_t *) windowingBuf,
DPParams->numDopplerChirps);
/*From this point forward samples are in ReIm format. In particular, FFT, twiddle are all in ReIm format.*/
/*DSPLIB notes for DSP_fft32x32():
Minimum FFT size is 16. Size must be power of 2.
No scaling done in FFT computation.*/
DSP_fft32x32((int32_t *)res->twiddle32x32,
DPParams->numDopplerBins,
(int32_t *)windowingBuf,
(int32_t *)twoDfftOut);
/* Save the 2D doppler FFT output for the required doppler bin */
res->angleFftIn[txAntIdx * DPParams->numRxAntennas + rxAntIdx] = twoDfftOut[dopplerIdx];
angleFftIn_copy[txAntIdx * DPParams->numRxAntennas + rxAntIdx] = twoDfftOut[dopplerIdx];
pingPongIdx ^= 1;
}/*txAntIdx*/
}