大家好,
最近在看level_sensing就是高精度测距例程的代码,关于Zoom FFT的代码没有看明白,没有找到旋转因子抽取的规律,也就不明白提高距离精度或者分辨率的根本原因。请大家帮忙看看,感谢!
具体的代码从下面c文件的251行开始:
/*! * \file RADARDEMO_highAccuRangeProc_priv.c * * \brief Windowing functions for range processing. * * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "RADARDEMO_highAccuRangeProc_priv.h" #ifdef _TMS320C6X #include "c6x.h" #endif #ifdef ARMVERSION extern void dft(int size, float * input, float * output); #endif #ifndef ARMVERSION /*! \fn RADARDEMO_highAccuRangeProc_accumulateInput \brief Accumulate signals from all chirps and convert to floating-point format with 1D windowing. \param[in] nSamplesPerChirp Number of samples per chirp. \param[in] fftSize1D 1D FFT size. \param[in] nChirpPerFrame Number of chirps per frame. \param[in] fftWin1D Input pointer to 1D window function. \param[in] fftWin1DSize Number of ADC bits. \param[in] inputPtr Pointer to input signal. \param[in] chirpInd Flag to enable DC adjustment for ADC samples when set to 1. Otherwise, no preprocessing for ADC samples. \param[out] outputPtr Pointer to the output signal. \pre none \post none */ void RADARDEMO_highAccuRangeProc_accumulateInput( IN uint32_t nSamplesPerChirp, IN uint32_t fftSize1D, IN uint32_t nChirpPerFrame, IN float * RESTRICT fftWin1D, IN int16_t fftWin1DSize, IN cplx16_t * RESTRICT inputPtr, IN int32_t chirpInd, OUT float * outputPtr) { int32_t i, itemp; int64_t input; if (chirpInd == 0) { for( i = 0; i < ((int32_t)nSamplesPerChirp>> 1); i++) { input = _amem8(&inputPtr[2 * i]); _amem8_f2(&outputPtr[4*i]) = _ftof2((float)_ext(_loll(input), 16, 16), (float)_ext(_loll(input), 0, 16)); _amem8_f2(&outputPtr[4*i + 2]) = _ftof2((float)_ext(_hill(input), 16, 16), (float)_ext(_hill(input), 0, 16)); } if((int32_t)nSamplesPerChirp & 1) { itemp = _amem4(&inputPtr[nSamplesPerChirp - 1]); _amem8_f2(&outputPtr[2*(nSamplesPerChirp - 1)]) = _ftof2((float)_ext(itemp, 16, 16), (float)_ext(itemp, 0, 16)); } } else { for( i = 0; i < ((int32_t)nSamplesPerChirp>> 1); i++) { input = _amem8(&inputPtr[2 * i]); _amem8_f2(&outputPtr[4*i]) = _daddsp(_amem8_f2(&outputPtr[4*i]), _ftof2((float)_ext(_loll(input), 16, 16), (float)_ext(_loll(input), 0, 16))); _amem8_f2(&outputPtr[4*i + 2]) = _daddsp(_amem8_f2(&outputPtr[4*i + 2]), _ftof2((float)_ext(_hill(input), 16, 16), (float)_ext(_hill(input), 0, 16))); } if((int32_t)nSamplesPerChirp & 1) { itemp = _amem4(&inputPtr[nSamplesPerChirp - 1]); _amem8_f2(&outputPtr[2*(nSamplesPerChirp - 1)]) = _daddsp(_amem8_f2(&outputPtr[2*(nSamplesPerChirp - 1)]), _ftof2((float)_ext(itemp, 16, 16), (float)_ext(itemp, 0, 16))); } if (chirpInd == ((int32_t)nChirpPerFrame - 1)) { __float2_t f2win1D; for( i = 0; i < fftWin1DSize; i++) { f2win1D = _ftof2(fftWin1D[i], fftWin1D[i]); _amem8_f2(&outputPtr[2*i]) = _dmpysp(_amem8_f2(&outputPtr[2*i]), f2win1D); _amem8_f2(&outputPtr[2*(nSamplesPerChirp - i - 1)]) = _dmpysp(_amem8_f2(&outputPtr[2*(nSamplesPerChirp - i - 1)]), f2win1D); } if (((int32_t)fftSize1D - (int32_t)nSamplesPerChirp) > 0) { for( i = 0; i < ((int32_t)fftSize1D - (int32_t)nSamplesPerChirp); i++); { _amem8_f2(&outputPtr[2*nSamplesPerChirp + 2*i]) = _ftof2(0.f, 0.f); } } } } } /*! \fn RADARDEMO_highAccuRangeProc_rangeEst \brief Windowing function for 2D FFT and prepare for the input. \param[in] highAccuRangeHandle Handle to the module. \param[out] estRange Estimated range. \param[out] deltaPhaseEst Estimated delta phase. \param[out] estLinearSNR Estimated SNR. \pre none \post none */ void RADARDEMO_highAccuRangeProc_rangeEst( IN RADARDEMO_highAccuRangeProc_handle *highAccuRangeHandle, OUT float * estRange, OUT float * deltaPhaseEst, OUT float * estLinearSNR) { int32_t i, j, k, rad1D, coarseRangeInd; unsigned char * brev = NULL; float totalPower, max, ftemp, sigPower, * RESTRICT powerPtr; __float2_t f2input, * RESTRICT inputPtr, * RESTRICT inputPtr1; int32_t zoomStartInd, zoomEndInd, itemp, tempIndFine1, tempIndFine2, tempIndCoarse, indMask, shift; int32_t fineRangeInd, tempFineSearchIdx, tempCoarseSearchIdx; __float2_t *RESTRICT wncPtr, wncoarse, *RESTRICT wnfPtr, wnfine1, sigAcc, f2temp; double freqFineEst, fdelta, interpIndx; float currP, prevP, maxPrevP, maxNextP; j = 30 - _norm(highAccuRangeHandle->fft1DSize); if ((j & 1) == 0) rad1D = 4; else rad1D = 2; /* copy to scratch is needed because FFT function will corrupt the input. We need to preserve if for zoom-in FFT */ inputPtr = (__float2_t *) highAccuRangeHandle->inputSig; inputPtr1 = (__float2_t *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize]; for (i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ ) { f2input = _amem8_f2(inputPtr); _amem8_f2(inputPtr1++) = f2input; _amem8_f2(inputPtr) = _ftof2(_lof2(f2input), _hif2(f2input)); inputPtr++; } inputPtr1 = (__float2_t *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize]; DSPF_sp_fftSPxSP ( highAccuRangeHandle->fft1DSize, (float*) inputPtr1, (float *)highAccuRangeHandle->twiddle, highAccuRangeHandle->fft1DOutSig, brev, rad1D, 0, highAccuRangeHandle->fft1DSize); for( i = 0; i < (int32_t)highAccuRangeHandle->skipLeft; i++ ) { _amem8_f2(&highAccuRangeHandle->fft1DOutSig[2*i]) = _ftof2(0.f, 0.f); } for( i = (int32_t)highAccuRangeHandle->fft1DSize- (int32_t)highAccuRangeHandle->skipRight; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ ) { _amem8_f2(&highAccuRangeHandle->fft1DOutSig[2*i]) = _ftof2(0.f, 0.f); } max = 0.f; totalPower = 0.f; coarseRangeInd = 0; inputPtr = (__float2_t *)highAccuRangeHandle->fft1DOutSig; powerPtr = (float *)highAccuRangeHandle->scratchPad; for( i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ ) { f2input = _amem8_f2(inputPtr++); f2input = _dmpysp(f2input, f2input); ftemp = _hif2(f2input) + _lof2(f2input); powerPtr[i] = ftemp; totalPower += ftemp; if( max < ftemp ) { max = ftemp; coarseRangeInd = i; } } i = coarseRangeInd; sigPower = powerPtr[i-2] + powerPtr[i-1] + powerPtr[i] + powerPtr[i+1] + powerPtr[i+2]; *estLinearSNR = divsp((float)((int32_t)highAccuRangeHandle->fft1DSize - (int32_t)highAccuRangeHandle->skipLeft - (int32_t)highAccuRangeHandle->skipRight- 5) * sigPower, (totalPower - sigPower)); /* zoom in FFT: assuming always size of fft1DSize x fft1DSize */ zoomStartInd = coarseRangeInd - highAccuRangeHandle->numRangeBinZoomIn; zoomEndInd = coarseRangeInd + highAccuRangeHandle->numRangeBinZoomIn; indMask = highAccuRangeHandle->fft1DSize - 1; shift = 30 - _norm(highAccuRangeHandle->fft1DSize); inputPtr = (__float2_t *)highAccuRangeHandle->inputSig; wncPtr = (__float2_t *)highAccuRangeHandle->wnCoarse; wnfPtr = (__float2_t *)highAccuRangeHandle->wnFine; max = 0.f; itemp = 0; currP = 0.f; prevP = 0.f; maxNextP = 0.f; maxPrevP = 0.f; for( i = zoomStartInd; i < zoomEndInd; i++) { for( j = 0; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++) { tempFineSearchIdx = j; sigAcc = _ftof2(0.f, 0.f); tempCoarseSearchIdx = 0; #ifdef _TMS320C6X #pragma UNROLL(2); #endif for( k = 0; k < (int32_t)highAccuRangeHandle->nSamplesPerChirp; k ++) { #if 0 tempIndFine1 = tempFineSearchIdx & indMask; tempIndFine2 = tempFineSearchIdx >> shift; tempFineSearchIdx += j; tempIndCoarse = tempCoarseSearchIdx & indMask; tempCoarseSearchIdx += i; f2input = _amem8_f2(&inputPtr[k]); wncoarse = _amem8_f2(&wncPtr[tempIndCoarse]); wnfine1 = _amem8_f2(&wnfPtr[tempIndFine1]); wnfine2 = _amem8_f2(&wncPtr[tempIndFine2]); f2temp = _complex_mpysp(f2input, wnfine1); f2temp = _complex_mpysp(f2temp, wnfine2); f2temp = _complex_mpysp(f2temp, wncoarse); sigAcc = _daddsp(sigAcc, f2temp); #else tempIndFine1 = tempFineSearchIdx & indMask; tempIndFine2 = tempFineSearchIdx >> shift; tempFineSearchIdx += j; tempIndCoarse = (tempCoarseSearchIdx + tempIndFine2) & indMask; tempCoarseSearchIdx += i; f2input = _amem8_f2(&inputPtr[k]); wncoarse = _amem8_f2(&wncPtr[tempIndCoarse]); wnfine1 = _amem8_f2(&wnfPtr[tempIndFine1]); f2temp = _complex_mpysp(f2input, wnfine1); f2temp = _complex_mpysp(f2temp, wncoarse); sigAcc = _daddsp(sigAcc, f2temp); #endif } prevP = currP; f2temp = _dmpysp(sigAcc,sigAcc); ftemp = _hif2(f2temp) + _lof2(f2temp); currP = ftemp; if( max < ftemp) { max = ftemp; fineRangeInd = itemp; maxPrevP = prevP; } if(itemp == fineRangeInd + 1) maxNextP = currP; itemp++; } } interpIndx = 0.5 * divdp((double)maxPrevP - (double)maxNextP, (double)maxPrevP + (double)maxNextP -2.0 * (double) max); fdelta = divdp((double)highAccuRangeHandle->maxBeatFreq, (double)highAccuRangeHandle->fft1DSize * (double)highAccuRangeHandle->fft1DSize); freqFineEst = fdelta * ((double)(zoomStartInd * highAccuRangeHandle->fft1DSize + fineRangeInd) + interpIndx); *estRange = (float)divdp(freqFineEst * 3.0e8 * (double)highAccuRangeHandle->chirpRampTime, (2.0 * (double)highAccuRangeHandle->chirpBandwidth)); if (highAccuRangeHandle->enablePhaseEst) { float phaseCoarseEst1, phaseCoarseEst2, phaseInitial; double PI = 3.14159265358979323846f; double real, imag, denom, initReal, initImag, dtemp1, dtemp2, dtemp; float phaseEst, totalPhase = 0.f, phaseCorrection, rangePhaseCorrection; __float2_t demodSig, corrSig; inputPtr = (__float2_t *)highAccuRangeHandle->inputSig; phaseCoarseEst1 = 2 * (float)PI * highAccuRangeHandle->fc * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst); phaseCoarseEst2 = (float)PI * highAccuRangeHandle->chirpSlope * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst) * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst); phaseInitial = phaseCoarseEst1 - phaseCoarseEst2; denom = divdp(1.0, (double)highAccuRangeHandle->fft1DSize); #if 0 dtemp1 = cos((double)phaseInitial); dtemp2 = sin(-(double)phaseInitial); initReal = cos(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ; initImag = sin(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom); #else dtemp1 = cosdp_i((double)phaseInitial); dtemp2 = sindp_i(-(double)phaseInitial); initReal = cosdp_i(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ; initImag = sindp_i(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom); #endif //sample @ t = 0; corrSig = _ftof2((float)dtemp1, (float)dtemp2); demodSig = _complex_mpysp(_amem8_f2(inputPtr++), corrSig); RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst); totalPhase += phaseEst; if ((highAccuRangeHandle->enableFilter == 0) && (highAccuRangeHandle->enableLinearFit == 0)) { //sample @ t = 1; dtemp = dtemp1 * initReal - dtemp2 * initImag; imag = dtemp1 * initImag + dtemp2 * initReal; real = dtemp; corrSig = _ftof2((float)real, (float)imag); demodSig = _complex_mpysp(_amem8_f2(inputPtr++), corrSig); RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst); totalPhase += phaseEst; for( j = 2; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++) { dtemp = real * initReal - imag * initImag; imag = real * initImag + imag * initReal; real = dtemp; corrSig = _ftof2((float)real, (float)imag); demodSig = _complex_mpysp(_amem8_f2(inputPtr++), corrSig); RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst); totalPhase += phaseEst; } phaseCorrection = totalPhase * (float)denom; rangePhaseCorrection= divsp((phaseCorrection*(float)3e8), (4.f * (float) PI * highAccuRangeHandle->fc)); *estRange += rangePhaseCorrection; } else { //Not implemented yet } } return; } #endif /*! \fn RADARDEMO_highAccuRangeProc_accumulateInputGeneric \brief Accumulate signals from all chirps and convert to floating-point format with 1D windowing. \param[in] nSamplesPerChirp Number of samples per chirp. \param[in] fftSize1D 1D FFT size. \param[in] nChirpPerFrame Number of chirps per frame. \param[in] fftWin1D Input pointer to 1D window function. \param[in] fftWin1DSize Number of ADC bits. \param[in] inputPtr Pointer to input signal. \param[in] chirpInd Flag to enable DC adjustment for ADC samples when set to 1. Otherwise, no preprocessing for ADC samples. \param[out] outputPtr Pointer to the output signal. \pre none \post none */ void RADARDEMO_highAccuRangeProc_accumulateInputGeneric( IN uint32_t nSamplesPerChirp, IN uint32_t fftSize1D, IN uint32_t nChirpPerFrame, IN float * RESTRICT fftWin1D, IN int16_t fftWin1DSize, IN cplx16_t * RESTRICT inputPtr, IN int32_t chirpInd, OUT float * outputPtr) { int32_t i; float * tempOutputPtr; if (chirpInd == 0) { for( i = (int32_t)nSamplesPerChirp - 1; i >= 0; i--) { *outputPtr++ = (float)inputPtr->real; *outputPtr++ = (float)inputPtr->imag; inputPtr++; } } else { tempOutputPtr = outputPtr; for( i = (int32_t)nSamplesPerChirp - 1; i >= 0; i--) { *tempOutputPtr++ += (float)inputPtr->real; *tempOutputPtr++ += (float)inputPtr->imag; inputPtr++; } if (chirpInd == ((int32_t)nChirpPerFrame - 1)) { float fwin1D; float *tempOutputPtr; tempOutputPtr = &outputPtr[2*nSamplesPerChirp - 1]; for( i = fftWin1DSize - 1; i >= 0; i--) { fwin1D = *fftWin1D++; *outputPtr = *outputPtr * fwin1D; outputPtr++; *outputPtr = *outputPtr * fwin1D; outputPtr++; *tempOutputPtr = *tempOutputPtr * fwin1D; tempOutputPtr--; *tempOutputPtr = *tempOutputPtr * fwin1D; tempOutputPtr--; } if (((int32_t)fftSize1D - (int32_t)nSamplesPerChirp) > 0) { tempOutputPtr = &outputPtr[2*nSamplesPerChirp]; for( i = 0; i < ((int32_t)fftSize1D - (int32_t)nSamplesPerChirp); i++); { *tempOutputPtr++ = 0.f; *tempOutputPtr++ = 0.f; } } } } } /*! \fn RADARDEMO_highAccuRangeProc_rangeEstGeneric \brief Windowing function for 2D FFT and prepare for the input. \param[in] procStep processing step, if 1, do preprocessing of the estimation, up to coarse range estimation, if 2, do the rest of estimation (fine freq and phase). \param[in] highAccuRangeHandle Handle to the module. \param[out] estRange Estimated range. \param[out] deltaPhaseEst Estimated delta phase. \param[out] estLinearSNR Estimated SNR. \pre none \post none */ void RADARDEMO_highAccuRangeProc_rangeEstGeneric( IN int8_t procStep, IN RADARDEMO_highAccuRangeProc_handle *highAccuRangeHandle, OUT float * estRange, OUT float * deltaPhaseEst, OUT float * estLinearSNR) { if (procStep == 1) { int32_t i, j, rad1D, coarseRangeInd; unsigned char * brev = NULL; float totalPower, max, ftemp, sigPower, * RESTRICT powerPtr; float finput, * RESTRICT inputPtr, * RESTRICT inputPtr1; j = highAccuRangeHandle->log2fft1DSize; if ((j & 1) == 0) rad1D = 4; else rad1D = 2; /* copy to scratch is needed because FFT function will corrupt the input. We need to preserve if for zoom-in FFT */ inputPtr = (float *) highAccuRangeHandle->inputSig; inputPtr1 = (float *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize]; for (i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ ) { *inputPtr1++ = *inputPtr++; *inputPtr1++ = *inputPtr++; } inputPtr1 = (float *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize]; #if 0 DSPF_sp_fftSPxSP_cn ( highAccuRangeHandle->fft1DSize, (float*) inputPtr1, (float *)highAccuRangeHandle->twiddle, highAccuRangeHandle->fft1DOutSig, brev, rad1D, 0, highAccuRangeHandle->fft1DSize); #endif dft(highAccuRangeHandle->fft1DSize, (float*) inputPtr1, highAccuRangeHandle->fft1DOutSig); inputPtr1 = (float *) &highAccuRangeHandle->fft1DOutSig[0]; for( i = 0; i < (int32_t)highAccuRangeHandle->skipLeft; i++ ) { *inputPtr1++ = 0.f; *inputPtr1++ = 0.f; } inputPtr1 = (float *) &highAccuRangeHandle->fft1DOutSig[2*((int32_t)highAccuRangeHandle->fft1DSize- (int32_t)highAccuRangeHandle->skipRight)]; for( i = (int32_t)highAccuRangeHandle->fft1DSize- (int32_t)highAccuRangeHandle->skipRight; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ ) { *inputPtr1++ = 0.f; *inputPtr1++ = 0.f; } max = 0.f; totalPower = 0.f; coarseRangeInd = 0; inputPtr = (float *)highAccuRangeHandle->fft1DOutSig; powerPtr = (float *)highAccuRangeHandle->scratchPad; for( i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ ) { finput = (*inputPtr) * (*inputPtr); inputPtr++; finput += (*inputPtr) * (*inputPtr); inputPtr++; ftemp = finput; powerPtr[i] = ftemp; totalPower += ftemp; if( max < ftemp ) { max = ftemp; coarseRangeInd = i; } } highAccuRangeHandle->coarseRangeInd = coarseRangeInd; i = coarseRangeInd; sigPower = powerPtr[i-2] + powerPtr[i-1] + powerPtr[i] + powerPtr[i+1] + powerPtr[i+2]; *estLinearSNR = ((float)((int32_t)highAccuRangeHandle->fft1DSize - (int32_t)highAccuRangeHandle->skipLeft - (int32_t)highAccuRangeHandle->skipRight- 5) * sigPower) / (totalPower - sigPower); } else if (procStep == 2) { int32_t i, j, k, coarseRangeInd = highAccuRangeHandle->coarseRangeInd; float max, ftemp; int32_t zoomStartInd, zoomEndInd, itemp, tempIndFine1, tempIndFine2, tempIndCoarse, indMask, shift; int32_t fineRangeInd, tempFineSearchIdx, tempCoarseSearchIdx; float *RESTRICT inputPtr, *RESTRICT wncPtr, *RESTRICT wnfPtr, sigAccReal, sigAccImag; float freqFineEst, fdelta, finputReal, finputImag, tempReal, tempImag; /* zoom in FFT: assuming always size of fft1DSize x fft1DSize */ zoomStartInd = coarseRangeInd - highAccuRangeHandle->numRangeBinZoomIn; zoomEndInd = coarseRangeInd + highAccuRangeHandle->numRangeBinZoomIn; indMask = highAccuRangeHandle->fft1DSize - 1; shift = highAccuRangeHandle->log2fft1DSize; inputPtr = (float *)highAccuRangeHandle->inputSig; wncPtr = (float *)highAccuRangeHandle->wnCoarse; wnfPtr = (float *)highAccuRangeHandle->wnFine; max = 0.0; itemp = 0; for( i = zoomStartInd; i < zoomEndInd; i++) { for( j = 0; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++) { tempFineSearchIdx = j; sigAccReal = 0.f; sigAccImag = 0.f; tempCoarseSearchIdx = 0; for( k = 0; k < (int32_t)highAccuRangeHandle->nSamplesPerChirp; k ++) { tempIndFine1 = tempFineSearchIdx & indMask; tempIndFine2 = tempFineSearchIdx >> shift; tempFineSearchIdx += j; tempIndCoarse = (tempCoarseSearchIdx + tempIndFine2) & indMask; tempCoarseSearchIdx += i; finputReal = inputPtr[2 * k]; finputImag = inputPtr[2 * k + 1]; tempReal = wncPtr[2 * tempIndCoarse + 1] * finputReal - wncPtr[2 * tempIndCoarse] * finputImag; tempImag = wncPtr[2 * tempIndCoarse] * finputReal + wncPtr[2 * tempIndCoarse + 1] * finputImag; sigAccReal += wnfPtr[2 * tempIndFine1 + 1] * tempReal - wnfPtr[2 * tempIndFine1] * tempImag; sigAccImag += wnfPtr[2 * tempIndFine1] * tempReal + wnfPtr[2 * tempIndFine1 + 1] * tempImag; } ftemp = sigAccReal * sigAccReal + sigAccImag * sigAccImag; if( max < ftemp) { max = ftemp; fineRangeInd = itemp; } itemp++; } } fdelta = (highAccuRangeHandle->maxBeatFreq) / ((float)highAccuRangeHandle->fft1DSize * (float)highAccuRangeHandle->fft1DSize); freqFineEst = fdelta * (float)(zoomStartInd * highAccuRangeHandle->fft1DSize + fineRangeInd); *estRange = (freqFineEst * (float)3e8 * highAccuRangeHandle->chirpRampTime) / (2.f * highAccuRangeHandle->chirpBandwidth); #if 0 if (highAccuRangeHandle->enablePhaseEst) { float phaseCoarseEst1, phaseCoarseEst2, phaseInitial; double PI = 3.14159265358979323846f; double real, imag, denom, initReal, initImag, dtemp1, dtemp2, dtemp; float phaseEst, totalPhase = 0.f, phaseCorrection, rangePhaseCorrection; __float2_t demodSig, corrSig; inputPtr = (__float2_t *)highAccuRangeHandle->inputSig; phaseCoarseEst1 = 2 * (float)PI * highAccuRangeHandle->fc * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst); phaseCoarseEst2 = (float)PI * highAccuRangeHandle->chirpSlope * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst) * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst); phaseInitial = phaseCoarseEst1 - phaseCoarseEst2; denom = divdp(1.0, (double)highAccuRangeHandle->fft1DSize); #if 0 dtemp1 = cos((double)phaseInitial); dtemp2 = sin(-(double)phaseInitial); initReal = cos(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ; initImag = sin(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom); #else dtemp1 = cosdp_i((double)phaseInitial); dtemp2 = sindp_i(-(double)phaseInitial); initReal = cosdp_i(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ; initImag = sindp_i(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom); #endif //sample @ t = 0; corrSig = _ftof2((float)dtemp1, (float)dtemp2); demodSig = _complex_mpysp(_amem8_f2(inputPtr++), corrSig); RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst); totalPhase += phaseEst; if ((highAccuRangeHandle->enableFilter == 0) && (highAccuRangeHandle->enableLinearFit == 0)) { //sample @ t = 1; dtemp = dtemp1 * initReal - dtemp2 * initImag; imag = dtemp1 * initImag + dtemp2 * initReal; real = dtemp; corrSig = _ftof2((float)real, (float)imag); demodSig = _complex_mpysp(_amem8_f2(inputPtr++), corrSig); RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst); totalPhase += phaseEst; for( j = 2; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++) { dtemp = real * initReal - imag * initImag; imag = real * initImag + imag * initReal; real = dtemp; corrSig = _ftof2((float)real, (float)imag); demodSig = _complex_mpysp(_amem8_f2(inputPtr++), corrSig); RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst); totalPhase += phaseEst; } phaseCorrection = totalPhase * (float)denom; rangePhaseCorrection= divsp((phaseCorrection*(float)3e8), (4.f * (float) PI * highAccuRangeHandle->fc)); *estRange += rangePhaseCorrection; } else { //Not implemented yet } } #endif } return; }
请帮忙看看,十分感谢!