主题中讨论的其他器件:IWR1443
如下图所示、2048点回波数据的 FFT 振幅在右侧、相应的对数振幅在左侧;从左图可以看出、在2048点结束时、噪声等级显著增加。 这种现象的原因是什么?
谢谢你。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
如下图所示、2048点回波数据的 FFT 振幅在右侧、相应的对数振幅在左侧;从左图可以看出、在2048点结束时、噪声等级显著增加。 这种现象的原因是什么?
谢谢你。
以下是某个操作结果的屏幕截图、毫米波配置屏幕截图、HWA 配置、FFT 计算和日志计算以及项目执行频率扫描后的二进制原始数据包。 请根据我提供的信息提供有效的答案。 最好不要问我任何问题,除非我错了,否则我的问题永远无法解决。
回波数据的含义无关紧要。 请不要详述这一点。
一般情况下、我假定我是正确的、我将在此条件下搜索答案。
谢谢你。
static int32_t HWAUtil_Config1D( HWA_Handle handle, uint32_t paramSetStartIdx, uint32_t numAdcSamples, uint8_t numRxAnt, uint32_t windowOffsetBytes, uint8_t dmaTriggerSourcePing, uint8_t dmaTriggerSourcePong, uint8_t dmaDestChannelPing, uint8_t dmaDestChannelPong, uint16_t hwaMemAdcBufOffset, uint16_t hwaMemDestPingOffset, uint16_t hwaMemDestPongOffset, uint8_t hwaTriggerMode ) { int32_t errCode = 0; uint32_t paramsetIdx = paramSetStartIdx; uint32_t pingParamSetIdx1 = 0; uint32_t pingParamSetIdx2 = 0; HWA_InterruptConfig paramISRConfig; HWA_ParamConfig hwaParamCfg[HWAUTIL_NUM_PARAM_SETS_1D]; memset( hwaParamCfg, 0, sizeof( hwaParamCfg ) ); /***********************/ /* PING DUMMY PARAMSET */ /***********************/ hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_DMA; // Software triggered - in demo this will be HWA_TRIG_MODE_DMA hwaParamCfg[paramsetIdx].dmaTriggerSrc = dmaTriggerSourcePing; // in demo this will be first EDMA Src channel id hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_NONE; // dummy errCode = HWA_configParamSet( handle, paramsetIdx, &( hwaParamCfg[paramsetIdx] ), NULL ); if ( errCode != 0 ) { return errCode; } /***********************/ /* PING PROCESS PARAMSET */ /***********************/ paramsetIdx++; pingParamSetIdx1 = paramsetIdx; hwaParamCfg[paramsetIdx].triggerMode = hwaTriggerMode; hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_FFT; // do FFT hwaParamCfg[paramsetIdx].source.srcAddr = hwaMemAdcBufOffset; // address is relative to start of MEM0 hwaParamCfg[paramsetIdx].source.srcAcnt = numAdcSamples / MMWAVECFG_FFT_NUM - 1; // this is samples - 1 hwaParamCfg[paramsetIdx].source.srcAIdx = MMWAVECFG_FFT_NUM * numRxAnt * sizeof( uint32_t ); // 4Kstitching 16 bytes hwaParamCfg[paramsetIdx].source.srcBcnt = MMWAVECFG_FFT_NUM - 1; // 4Kstitching 4 back-to-back 1024 point fft hwaParamCfg[paramsetIdx].source.srcBIdx = sizeof( uint32_t ); // should be dont care hwaParamCfg[paramsetIdx].source.srcShift = 0; // no shift hwaParamCfg[paramsetIdx].source.srcCircShiftWrap = 0; // no shift hwaParamCfg[paramsetIdx].source.srcRealComplex = HWA_SAMPLES_FORMAT_COMPLEX; // complex data hwaParamCfg[paramsetIdx].source.srcWidth = HWA_SAMPLES_WIDTH_16BIT; // 16-bit hwaParamCfg[paramsetIdx].source.srcSign = HWA_SAMPLES_SIGNED; // signed hwaParamCfg[paramsetIdx].source.srcConjugate = 0; // no conjugate hwaParamCfg[paramsetIdx].source.srcScale = 8; hwaParamCfg[paramsetIdx].source.bpmEnable = 0; // bpm removal not enabled hwaParamCfg[paramsetIdx].source.bpmPhase = 0; // dont care hwaParamCfg[paramsetIdx].dest.dstAddr = ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_M3 ); // hwaMemDestPingOffset; // address is relative to start of MEM0 hwaParamCfg[paramsetIdx].dest.dstAcnt = MMWAVECFG_FFT_SIZE / MMWAVECFG_FFT_NUM - 1; // this is samples - 1 hwaParamCfg[paramsetIdx].dest.dstAIdx = MMWAVECFG_FFT_NUM * numRxAnt * sizeof( uint32_t ); // hwaParamCfg[paramsetIdx].dest.dstBIdx = sizeof( uint32_t ); // should be dont care hwaParamCfg[paramsetIdx].dest.dstRealComplex = HWA_SAMPLES_FORMAT_COMPLEX; // same as input - complex hwaParamCfg[paramsetIdx].dest.dstWidth = HWA_SAMPLES_WIDTH_16BIT; // same as input - 16 bit hwaParamCfg[paramsetIdx].dest.dstSign = HWA_SAMPLES_SIGNED; // same as input - signed hwaParamCfg[paramsetIdx].dest.dstConjugate = 0; // no conjugate hwaParamCfg[paramsetIdx].dest.dstScale = 0; hwaParamCfg[paramsetIdx].dest.dstSkipInit = 0; // no skipping hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftEn = 1; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftSize = Log2Approx( MMWAVECFG_FFT_SIZE / MMWAVECFG_FFT_NUM ); hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.butterflyScaling = 0x3; // LSB fftSize bits are relevant - revisit this for all FFT size and data size hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.interfZeroOutEn = 0; // disabled hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.windowEn = 1; // enabled hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.windowStart = windowOffsetBytes; // start of window RAM hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winSymm = 0; // non-symmetric - in demo do we make this symmetric hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winInterpolateMode = HWA_FFT_WINDOW_INTERPOLATE_MODE_2K; // 4Kstitching, enabling window interpolation hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.magLogEn = HWA_FFT_MODE_MAGNITUDE_LOG2_DISABLED; // disabled hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftOutMode = HWA_FFT_MODE_OUTPUT_DEFAULT; // output FFT samples hwaParamCfg[paramsetIdx].complexMultiply.mode = HWA_COMPLEX_MULTIPLY_MODE_DISABLE; errCode = HWA_configParamSet( handle, paramsetIdx, &( hwaParamCfg[paramsetIdx] ), NULL ); if ( errCode != 0 ) { return errCode; } /***********************/ /* PING PROCESS PARAMSET 4K stitching Step 2*/ /***********************/ paramsetIdx++; pingParamSetIdx2 = paramsetIdx; hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_IMMEDIATE; hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_FFT; // do FFT hwaParamCfg[paramsetIdx].source.srcAddr = ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_M3 ); // hwaMemDestPingOffset; // MEM2 (32KB) hwaParamCfg[paramsetIdx].source.srcAcnt = MMWAVECFG_FFT_NUM - 1; // 4 point FFT hwaParamCfg[paramsetIdx].source.srcAIdx = sizeof( uint32_t ); // adjacent samples are 4 bytes apart hwaParamCfg[paramsetIdx].source.srcBcnt = MMWAVECFG_FFT_SIZE / MMWAVECFG_FFT_NUM - 1; // 1024 4-point fft hwaParamCfg[paramsetIdx].source.srcBIdx = MMWAVECFG_FFT_NUM * sizeof( uint32_t ); // Each set of 4-point fft is spaced 16 bytes apart hwaParamCfg[paramsetIdx].source.srcShift = 0; // no shift hwaParamCfg[paramsetIdx].source.srcCircShiftWrap = 0; // no shift hwaParamCfg[paramsetIdx].source.srcRealComplex = HWA_SAMPLES_FORMAT_COMPLEX; // complex data hwaParamCfg[paramsetIdx].source.srcWidth = HWA_SAMPLES_WIDTH_16BIT; // 16-bit hwaParamCfg[paramsetIdx].source.srcSign = HWA_SAMPLES_SIGNED; // signed hwaParamCfg[paramsetIdx].source.srcConjugate = 0; // no conjugate hwaParamCfg[paramsetIdx].source.srcScale = 8; hwaParamCfg[paramsetIdx].source.bpmEnable = 0; // bpm removal not enabled hwaParamCfg[paramsetIdx].source.bpmPhase = 0; // dont care hwaParamCfg[paramsetIdx].dest.dstAddr = hwaMemDestPingOffset; // hwaMemAdcBufOffset; // MEM0 hwaParamCfg[paramsetIdx].dest.dstAcnt = MMWAVECFG_FFT_NUM - 1; // this is samples - 1 hwaParamCfg[paramsetIdx].dest.dstAIdx = MMWAVECFG_FFT_SIZE / MMWAVECFG_FFT_NUM * sizeof( uint32_t ); // hwaParamCfg[paramsetIdx].dest.dstBIdx = sizeof( uint32_t ); // should be dont care hwaParamCfg[paramsetIdx].dest.dstRealComplex = HWA_SAMPLES_FORMAT_COMPLEX; // same as input - complex hwaParamCfg[paramsetIdx].dest.dstWidth = HWA_SAMPLES_WIDTH_16BIT; // same as input - 16 bit hwaParamCfg[paramsetIdx].dest.dstSign = HWA_SAMPLES_SIGNED; // same as input - signed hwaParamCfg[paramsetIdx].dest.dstConjugate = 0; // no conjugate hwaParamCfg[paramsetIdx].dest.dstScale = 0; hwaParamCfg[paramsetIdx].dest.dstSkipInit = 0; // no skipping hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftEn = 1; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftSize = Log2Approx( MMWAVECFG_FFT_NUM ); hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.butterflyScaling = 0x1; // LSB fftSize bits are relevant - revisit this for all FFT size and data size hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.interfZeroOutEn = 0; // disabled hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.windowEn = 0; // enabled hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.windowStart = windowOffsetBytes; // start of window RAM hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winSymm = 0; // non-symmetric - in demo do we make this symmetric // hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winInterpolateMode = 0; //fftsize is less than 1K hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winInterpolateMode = 0; // 4Kstitching, enabling window interpolation hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.magLogEn = HWA_FFT_MODE_MAGNITUDE_LOG2_DISABLED; // disabled hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftOutMode = HWA_FFT_MODE_OUTPUT_DEFAULT; // output FFT samples hwaParamCfg[paramsetIdx].complexMultiply.mode = HWA_COMPLEX_MULTIPLY_MODE_FFT_STITCHING; hwaParamCfg[paramsetIdx].complexMultiply.cmpMulArgs.twidFactorPattern = 0; errCode = HWA_configParamSet( handle, paramsetIdx, &( hwaParamCfg[paramsetIdx] ), NULL ); if ( errCode != 0 ) { return errCode; } /* enable the DMA hookup to this paramset so that data gets copied out */ paramISRConfig.interruptTypeFlag = HWA_PARAMDONE_INTERRUPT_TYPE_DMA; paramISRConfig.dma.dstChannel = dmaDestChannelPing; // TODO sync this define EDMA channel to trigger to copy the data out // paramISRConfig.cpu.callbackArg = paramSetSem;//TODO check if NULL is required errCode = HWA_enableParamSetInterrupt( handle, paramsetIdx, ¶mISRConfig ); if ( errCode != 0 ) { return errCode; } /***********************/ /* PONG DUMMY PARAMSET */ /***********************/ paramsetIdx++; hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_DMA; hwaParamCfg[paramsetIdx].dmaTriggerSrc = dmaTriggerSourcePong; // in demo this will be second EDMA Src channel id hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_NONE; // dummy errCode = HWA_configParamSet( handle, paramsetIdx, &( hwaParamCfg[paramsetIdx] ), NULL ); if ( errCode != 0 ) { return errCode; } /***********************/ /* PONG PROCESS PARAMSET */ /***********************/ paramsetIdx++; hwaParamCfg[paramsetIdx] = hwaParamCfg[pingParamSetIdx1]; // hwaParamCfg[paramsetIdx].source.srcAddr = ADDR_TRANSLATE_CPU_TO_HWA(MMW_HWA_1D_OUT_PONG_M3_M1); hwaParamCfg[paramsetIdx].dest.dstAddr = ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_M2 ); // hwaMemDestPongOffset; errCode = HWA_configParamSet( handle, paramsetIdx, &( hwaParamCfg[paramsetIdx] ), NULL ); if ( errCode != 0 ) { return errCode; } /***********************/ /* PONG PROCESS PARAMSET Step 2*/ /***********************/ paramsetIdx++; hwaParamCfg[paramsetIdx] = hwaParamCfg[pingParamSetIdx2]; hwaParamCfg[paramsetIdx].source.srcAddr = ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_M2 ); hwaParamCfg[paramsetIdx].dest.dstAddr = hwaMemDestPongOffset; // hwaMemDestPongOffset; errCode = HWA_configParamSet( handle, paramsetIdx, &( hwaParamCfg[paramsetIdx] ), NULL ); if ( errCode != 0 ) { return errCode; } /* enable the DMA hookup to this paramset so that data gets copied out */ paramISRConfig.interruptTypeFlag = HWA_PARAMDONE_INTERRUPT_TYPE_DMA; paramISRConfig.dma.dstChannel = dmaDestChannelPong; // paramISRConfig.cpu.callbackArg = paramSetSem;//TODO check if NULL is required errCode = HWA_enableParamSetInterrupt( handle, paramsetIdx, ¶mISRConfig ); return errCode; } /** * @b Description * @n * Configure HWA for 1D processing. * @param[in] obj Pointer to data path obj. * @retval none. */ int32_t HWA_Config1D( MMWave_DataPathObj_t *obj, Bsp_Data_t *bsp ) { uint8_t hwaTriggerMode; int32_t errCode; uint32_t winLen; float phi; HWA_CommonConfig hwaCommonConfig; /* Disable the HWA */ errCode = HWA_enable( bsp->hpHwaHandle, 0 ); // set 1 to enable if ( errCode != 0 ) { return errCode; } /* Reset the internal state of the HWA */ errCode = HWA_reset( bsp->hpHwaHandle ); if ( errCode != 0 ) { return errCode; } /* if windowing is enabled, load the window coefficients in RAM */ // 1D-FFT window winLen = obj->ulNumAdcSamples / MMWAVECFG_FFT_NUM; phi = 2 * PI / ( (float)winLen - 1 ); HWA_GenTable( &( g_tDb.tRun.tFft.ulpWinBuf[0] ), winLen, phi ); errCode = HWA_configRam( bsp->hpHwaHandle, HWA_RAM_TYPE_WINDOW_RAM, (uint8_t *)&( g_tDb.tRun.tFft.ulpWinBuf[0] ), sizeof( uint32_t ) * winLen, // size in bytes 0 ); // offset in bytes if ( errCode != 0 ) { return errCode; } /**********************************************/ /* ENABLE NUMLOOPS DONE INTERRUPT FROM HWA */ /**********************************************/ errCode = HWA_enableDoneInterrupt( bsp->hpHwaHandle, HWA_DoneIsrCallback, obj->hHWA_done_semHandle ); if ( errCode != 0 ) { return errCode; } if ( obj->eDataPathMode == DATA_PATH_STANDALONE ) { /* trigger manually and immediately */ hwaTriggerMode = HWA_TRIG_MODE_SOFTWARE; } else { /* trigger done by ADC buffer */ hwaTriggerMode = HWA_TRIG_MODE_DFE; } HWAUtil_Config1D( bsp->hpHwaHandle, MMWAVE_HWA_START_POS_PARAMSETS_1D, obj->ulNumAdcSamples, obj->ulNumRxAntennas, MMWAVE_HWA_WINDOWRAM_1D_OFFSET, MMWAVE_HWA_DMA_TRIGGER_SOURCE_1D_PING, MMWAVE_HWA_DMA_TRIGGER_SOURCE_1D_PONG, MMWAVE_HWA_DMA_DEST_CHANNEL_1D_PING, MMWAVE_HWA_DMA_DEST_CHANNEL_1D_PONG, ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_1D_ADCBUF_INP ), ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_1D_OUT_PING ), ADDR_TRANSLATE_CPU_TO_HWA( MMWAVE_HWA_1D_OUT_PONG ), hwaTriggerMode ); /* Config Common Registers */ hwaCommonConfig.configMask = HWA_COMMONCONFIG_MASK_NUMLOOPS | HWA_COMMONCONFIG_MASK_PARAMSTARTIDX | HWA_COMMONCONFIG_MASK_PARAMSTOPIDX | HWA_COMMONCONFIG_MASK_FFT1DENABLE | HWA_COMMONCONFIG_MASK_INTERFERENCETHRESHOLD | HWA_COMMONCONFIG_MASK_TWIDDITHERENABLE | HWA_COMMONCONFIG_MASK_LFSRSEED; hwaCommonConfig.numLoops = obj->ulNumChirpsPerFrame / 2; hwaCommonConfig.paramStartIdx = MMWAVE_HWA_START_POS_PARAMSETS_1D; hwaCommonConfig.paramStopIdx = MMWAVE_HWA_START_POS_PARAMSETS_1D + HWAUTIL_NUM_PARAM_SETS_1D - 1; if ( obj->eDataPathMode == DATA_PATH_STANDALONE ) { /* HWA will input data from M0 memory*/ hwaCommonConfig.fftConfig.fft1DEnable = HWA_FEATURE_BIT_DISABLE; } else { /* HWA will input data from ADC buffer memory*/ hwaCommonConfig.fftConfig.fft1DEnable = HWA_FEATURE_BIT_ENABLE; } hwaCommonConfig.fftConfig.twidDitherEnable = HWA_FEATURE_BIT_ENABLE; hwaCommonConfig.fftConfig.lfsrSeed = 0x1234567; /*Some non-zero value*/ hwaCommonConfig.fftConfig.interferenceThreshold = 0xFFFFFF; errCode = HWA_configCommon( bsp->hpHwaHandle, &hwaCommonConfig ); return errCode; }
/******************************************************************************* * @func: calculate FFT power * @desc: * @param: * @return: *******************************************************************************/ static void Peak_CalcPower( const int16_t *src, float *dst ) { uint32_t i, j; int32_t temp; uint64_t num; for ( i = 0; i < MMWAVECFG_FFT_SIZE; i++ ) { num = 0; for ( j = 0; j < ( MMWAVECFG_NUM_CHIRPS_PERFRAME * 2 ); j++ ) { temp = ( *src ) >> 1; num += ( temp * temp ); src++; } dst[i] = (float)( num / MMWAVECFG_NUM_CHIRPS_PERFRAME ); } } /******************************************************************************* * @func: calculate log * @desc: * @param: a: 20 * @param: b: 70 * @return: *******************************************************************************/ static void Log_F32( const float *src, float *dst, uint32_t len, uint16_t a, uint16_t b ) { uint32_t i; for ( i = 0; i < len; i++ ) { dst[i] = a * log10f( src[i] ) / log10f( (float)b ); } }
我想问一下、日志计算前的 FFT 源数据是否基于 IWR1443硬件计算?
我的 ADC 和 FFT 源数据都基于 IWR1443、但 FFT 的振幅和对数是使用 MSS 计算得出的。 可从上一节中提供的信息中获取相关计算过程。
如果您通过软件计算从 ADC 数据中获得 FFT 源数据、则可以跳过此步骤、直接使用压缩包中的 FFT 二进制文件来绘制日志数据。 这可以分析 IWR1443的硬件 FFT 是否存在问题。 可以从上述信息获取相关的硬件 FFT 配置。
我建议您详细阅读和分析我在上一节中提供的信息、而不仅限于在您面前进行一次验证。
谢谢你。