Tool/software:
My goal is to read out data from the ADC Buffer and process it by applying FFT with the HWA of the board.
Currently it seemed in my logging that my "Classify bits" function is never called. So it seems like the semaphores are never released, this makes me think that the parameter set chaining is not happening correctly. I have tried multiple things but I am not sure how to get this correct.
What is wrong in my files and why is it not possible to release the semaphores?
I will provide the logs and the code. If more information is needed, let me know.
Logs:
Cortex_R4_0: ********************************************** Cortex_R4_0: Debug: Launching the MMW HWA Demo Cortex_R4_0: ********************************************** Cortex_R4_0: Debug: Launched the Initialization Task Cortex_R4_0: Debug: DPU Init Sema Handle: @08003e50 Cortex_R4_0: Debug: DPU Init Sema Handle: @08003fb8 Cortex_R4_0: Debug: DPU Init Sema Handle: @08004120 Cortex_R4_0: Debug: DPU Init Sema Handle: @08004288 Cortex_R4_0: Debug: CLI init done Cortex_R4_0: INSIDE: MmwDemo_eventCallbackFxn with 128, 4 Cortex_R4_0: Error: MmwDemo_eventCallbackFxn error case was RL_RF_AE_INITCALIBSTATUS_SB: Cortex_R4_0: Debug: sending DPC_COMM_IOCTL__STATIC_PRE_START_COMMON_CFG Cortex_R4_0: Inside DPC IOCTL Cortex_R4_0: Inside DPC IOCTL Cortex_R4_0: Debug: Configuring Static Pre Start CFG Cortex_R4_0: Inside DPC IOCTL Cortex_R4_0: Debug: Calling DPC_Comm_transmissionConfig Cortex_R4_0: Debug: Calling DPU_TransmissionHWA_config Cortex_R4_0: HWA_enable: flagEnDis=0 Cortex_R4_0: Debug: Calling transmissionHWA_ConifgInterleaveMode Cortex_R4_0: Debug: Calling configHWA in mapped mode Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=0, interruptTypeFlag=0x3 Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=1, interruptTypeFlag=0x3 Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=2, interruptTypeFlag=0x3 Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=3, interruptTypeFlag=0x3 Cortex_R4_0: --------- PING DUMMY PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 0 Cortex_R4_0: Debug: hwParamsetIdx : 0 Cortex_R4_0: Debug: triggerMode : 3 Cortex_R4_0: Debug: dmaTriggerSrc : 0 Cortex_R4_0: Debug: accelMode : 3 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=0, triggerMode=3, dmaTriggerSrc=0, accelMode=3 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0x0, fftEn=0 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=0, interruptTypeFlag=0x2, dstChannel=1 Cortex_R4_0: --------- PING PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 1 Cortex_R4_0: Debug: hwParamsetIdx : 1 Cortex_R4_0: Debug: triggerMode : 2 Cortex_R4_0: Debug: dmaTriggerSrc : 0 Cortex_R4_0: Debug: accelMode : 0 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=1, triggerMode=2, dmaTriggerSrc=0, accelMode=0 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0x8000, fftEn=1 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=1, interruptTypeFlag=0x2, dstChannel=0 Cortex_R4_0: --------- PONG DUMMY PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 2 Cortex_R4_0: Debug: hwParamsetIdx : 2 Cortex_R4_0: Debug: triggerMode : 3 Cortex_R4_0: Debug: dmaTriggerSrc : 2 Cortex_R4_0: Debug: accelMode : 3 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=2, triggerMode=3, dmaTriggerSrc=2, accelMode=3 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0x0, fftEn=0 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=2, interruptTypeFlag=0x2, dstChannel=3 Cortex_R4_0: --------- PONG PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 3 Cortex_R4_0: Debug: hwParamsetIdx : 3 Cortex_R4_0: Debug: triggerMode : 2 Cortex_R4_0: Debug: dmaTriggerSrc : 0 Cortex_R4_0: Debug: accelMode : 0 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=3, triggerMode=2, dmaTriggerSrc=0, accelMode=0 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0xc000, fftEn=1 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=3, interruptTypeFlag=0x2, dstChannel=1 Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMA_DataOut_interleave Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for ping Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for ping Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for ping Cortex_R4_0: Debug: Succesfully Called: transmissionHWA_ConfigEDMATranspose for ping 3 times Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for pong Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for pong Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for pong Cortex_R4_0: Debug: Succesfully Called: transmissionHWA_ConfigEDMATranspose for pong 3 times Cortex_R4_0: Debug: Calling DPEDMAHWA_configTwoHotSignature in Data Out Cortex_R4_0: Debug: dataOutTrigger 0: 0 Cortex_R4_0: Debug: dataOutTrigger 1: 2 Cortex_R4_0: Debug: Succesfully Called DPEDMAHWA_configTwoHotSignature in Data Out Cortex_R4_0: Debug: Succesfully Called: transmissionHWA_ConfigEDMA_DataOut_interleave Cortex_R4_0: Debug: Succesfully called: transmissionHWA_ConifgInterleaveMode Cortex_R4_0: Debug: Succesfully configured the Transmission DPU. Cortex_R4_0: ========== Memory Stats ========== Cortex_R4_0: Size Used Free DPCUsed Cortex_R4_0: System Heap(TCM) 65536 26040 39496 0 Cortex_R4_0: L3 786432 0 786432 Cortex_R4_0: TCM 50176 128 50048 Cortex_R4_0: Debug: Succesfully configured Static Pre Start CFG Cortex_R4_0: App: Issuing DPM_start Cortex_R4_0: Debug: DPM_start commDpmHandle pointer: @08002ab8 Cortex_R4_0: Debug: Called DPC Start. Cortex_R4_0: Debug: Calling: DPC_Comm_reconfigSubFrame. Cortex_R4_0: Debug: Calling: DPU_TransmissionHWA_config. Cortex_R4_0: HWA_enable: flagEnDis=0 Cortex_R4_0: Debug: Calling transmissionHWA_ConifgInterleaveMode Cortex_R4_0: Debug: Calling configHWA in mapped mode Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=0, interruptTypeFlag=0x3 Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=1, interruptTypeFlag=0x3 Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=2, interruptTypeFlag=0x3 Cortex_R4_0: HWA_disableParamSetInterrupt: paramsetIdx=3, interruptTypeFlag=0x3 Cortex_R4_0: --------- PING DUMMY PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 0 Cortex_R4_0: Debug: hwParamsetIdx : 0 Cortex_R4_0: Debug: triggerMode : 3 Cortex_R4_0: Debug: dmaTriggerSrc : 0 Cortex_R4_0: Debug: accelMode : 3 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=0, triggerMode=3, dmaTriggerSrc=0, accelMode=3 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0x0, fftEn=0 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=0, interruptTypeFlag=0x2, dstChannel=1 Cortex_R4_0: --------- PING PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 1 Cortex_R4_0: Debug: hwParamsetIdx : 1 Cortex_R4_0: Debug: triggerMode : 2 Cortex_R4_0: Debug: dmaTriggerSrc : 0 Cortex_R4_0: Debug: accelMode : 0 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=1, triggerMode=2, dmaTriggerSrc=0, accelMode=0 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0x8000, fftEn=1 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=1, interruptTypeFlag=0x2, dstChannel=0 Cortex_R4_0: --------- PONG DUMMY PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 2 Cortex_R4_0: Debug: hwParamsetIdx : 2 Cortex_R4_0: Debug: triggerMode : 3 Cortex_R4_0: Debug: dmaTriggerSrc : 2 Cortex_R4_0: Debug: accelMode : 3 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=2, triggerMode=3, dmaTriggerSrc=2, accelMode=3 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0x0, fftEn=0 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=2, interruptTypeFlag=0x2, dstChannel=3 Cortex_R4_0: --------- PONG PARAMSET --------- Cortex_R4_0: Debug: hwaHandle : @08000f90 Cortex_R4_0: Debug: paramsetIdx : 3 Cortex_R4_0: Debug: hwParamsetIdx : 3 Cortex_R4_0: Debug: triggerMode : 2 Cortex_R4_0: Debug: dmaTriggerSrc : 0 Cortex_R4_0: Debug: accelMode : 0 Cortex_R4_0: --------------------------------------- Cortex_R4_0: HWA_configParamSet: paramsetIdx=3, triggerMode=2, dmaTriggerSrc=0, accelMode=0 Cortex_R4_0: HWA_configParamSet: srcAddr=0x0, dstAddr=0xc000, fftEn=1 Cortex_R4_0: HWA_enableParamSetInterrupt: paramsetIdx=3, interruptTypeFlag=0x2, dstChannel=1 Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMA_DataOut_interleave Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for ping Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for ping Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for ping Cortex_R4_0: Debug: Succesfully Called: transmissionHWA_ConfigEDMATranspose for ping 3 times Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for pong Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for pong Cortex_R4_0: Debug: Calling transmissionHWA_ConfigEDMATranspose for pong Cortex_R4_0: Debug: Succesfully Called: transmissionHWA_ConfigEDMATranspose for pong 3 times Cortex_R4_0: Debug: Calling DPEDMAHWA_configTwoHotSignature in Data Out Cortex_R4_0: Debug: dataOutTrigger 0: 0 Cortex_R4_0: Debug: dataOutTrigger 1: 2 Cortex_R4_0: Debug: Succesfully Called DPEDMAHWA_configTwoHotSignature in Data Out Cortex_R4_0: Debug: Succesfully Called: transmissionHWA_ConfigEDMA_DataOut_interleave Cortex_R4_0: Debug: Succesfully called: transmissionHWA_ConifgInterleaveMode Cortex_R4_0: Debug: Succesfully called: DPU_TransmissionHWA_config. Cortex_R4_0: Debug: Calling: DPU_TransmissionHWA_control from the DPC_Communication_start. Cortex_R4_0: Debug: DPU_Transmission_Handle: @08003d00 Cortex_R4_0: Debug: pointer transmissionObj: @08003d00 Cortex_R4_0: Debug: Calling transmissionHWA_TriggerHWA. Cortex_R4_0: Debug: Calling transmissionHWA_ConfigHWACommon. Cortex_R4_0: Debug: Calling HWA_configCommon. Cortex_R4_0: HWA_configCommon: numLoops=4, paramStartIdx=0, paramStopIdx=3, fft1DEnable=1 Cortex_R4_0: Debug: Succesfully called: HWA_configCommon. Cortex_R4_0: Debug: Calling HWA_enableDoneInterrupt. Cortex_R4_0: Debug: Sema Handle: @08003e50 Cortex_R4_0: HWA_enableDoneInterrupt: callbackFn=@00022aa9, callbackArg=@08003e50 Cortex_R4_0: Debug: Succesfully called: HWA_enableDoneInterrupt. Cortex_R4_0: Debug: Succesfully called: transmissionHWA_ConfigHWACommon. Cortex_R4_0: Debug: Calling HWA_enable. Cortex_R4_0: HWA_enable: flagEnDis=1 Cortex_R4_0: Debug: Succesfully called: HWA_enable. Cortex_R4_0: Debug: Ensuring DFE-to-HWA trigger path is enabled. Cortex_R4_0: Debug: Calling HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: dataOutTrigger value: 0 Cortex_R4_0: HWA_setDMA2ACCManualTrig: Manual DMA trigger for channel=0 Cortex_R4_0: Debug: Succesfully called: HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: Calling HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: dataOutTrigger value: 2 Cortex_R4_0: HWA_setDMA2ACCManualTrig: Manual DMA trigger for channel=2 Cortex_R4_0: Debug: Succesfully called: HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: Succesfully called: transmissionHWA_TriggerHWA. Cortex_R4_0: Debug: Succesfully called: DPU_TransmissionHWA_control from the DPC_Communication_start. Cortex_R4_0: App: DPM_start Done Cortex_R4_0: Starting Sensor (issuing MMWave_start) Cortex_R4_0: INSIDE: MmwDemo_eventCallbackFxn with 128, 18 Cortex_R4_0: Error: MmwDemo_eventCallbackFxn error case was RL_RF_AE_RUN_TIME_CALIB_REPORT_SB: Cortex_R4_0: DEBUG: retVal: 0 Cortex_R4_0: INSIDE: MmwDemo_eventCallbackFxn with 128, 11 Cortex_R4_0: INFO: MmwDemo_eventCallbackFxn case was RL_RF_AE_FRAME_TRIGGER_RDY_SB: Cortex_R4_0: Frame Start Event received. Frame count: 0 Cortex_R4_0: ----------------------------------------------------------------------------------- Cortex_R4_0: Sensor started succesfully Cortex_R4_0: ----------------------------------------------------------------------------------- Cortex_R4_0: Triggering Cortex_R4_0: Starting HWA processing Cortex_R4_0: Debug: DPC_Communication_ioctl commDpmHandle pointer: @08002ab8 Cortex_R4_0: Inside DPC IOCTL Cortex_R4_0: Inside DPC_COMM_IOCTL__DYNAMIC_EXECUTE_RESULT_EXPORTED Cortex_R4_0: number of subframes: 1 Cortex_R4_0: Debug: Calling DPU_TransmissionHWA_control from DPC IOCTL. Cortex_R4_0: Debug: DPU_Transmission_Handle: @08003d00 Cortex_R4_0: Debug: pointer transmissionObj: @08003d00 Cortex_R4_0: Debug: Calling transmissionHWA_TriggerHWA. Cortex_R4_0: Debug: Calling transmissionHWA_ConfigHWACommon. Cortex_R4_0: Debug: Calling HWA_configCommon. Cortex_R4_0: HWA_configCommon: numLoops=4, paramStartIdx=0, paramStopIdx=3, fft1DEnable=1 Cortex_R4_0: Debug: Succesfully called: HWA_configCommon. Cortex_R4_0: Debug: Calling HWA_enableDoneInterrupt. Cortex_R4_0: Debug: Sema Handle: @08003e50 Cortex_R4_0: HWA_enableDoneInterrupt: callbackFn=@00022aa9, callbackArg=@08003e50 Cortex_R4_0: Debug: Succesfully called: HWA_enableDoneInterrupt. Cortex_R4_0: Debug: Succesfully called: transmissionHWA_ConfigHWACommon. Cortex_R4_0: Debug: Calling HWA_enable. Cortex_R4_0: HWA_enable: flagEnDis=1 Cortex_R4_0: Debug: Succesfully called: HWA_enable. Cortex_R4_0: Debug: Ensuring DFE-to-HWA trigger path is enabled. Cortex_R4_0: Debug: Calling HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: dataOutTrigger value: 0 Cortex_R4_0: HWA_setDMA2ACCManualTrig: Manual DMA trigger for channel=0 Cortex_R4_0: Debug: Succesfully called: HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: Calling HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: dataOutTrigger value: 2 Cortex_R4_0: HWA_setDMA2ACCManualTrig: Manual DMA trigger for channel=2 Cortex_R4_0: Debug: Succesfully called: HWA_setDMA2ACCManualTrig. Cortex_R4_0: Debug: Succesfully called: transmissionHWA_TriggerHWA. Cortex_R4_0: Debug: Succesfully called: DPU_TransmissionHWA_control from DPC IOCTL. Cortex_R4_0: Comm DPC: Range Proc Triggered in export IOCTL Cortex_R4_0: HWA processing triggered Cortex_R4_0: Frame triggered successfully
transmission file:
/** * @file transmission.c * * @brief * Implements Transmisison using HWA. */ /************************************************************************** *************************** Include Files ******************************** **************************************************************************/ /* Standard Include Files. */ #include <stdint.h> #include <stdlib.h> #include <stddef.h> #include <string.h> #include <stdio.h> #include <math.h> /* mmWave SDK common/driver Include files */ #include <ti/drivers/osal/SemaphoreP.h> #include <ti/drivers/osal/MemoryP.h> #include <ti/drivers/edma/edma.h> #include <ti/drivers/hwa/hwa.h> /* Data Path Include files */ #include <ti/datapath/dpu/rangeproc/rangeprochwa.h> #include <ti/datapath/dpu/transmission/transmission.h> #include <ti/datapath/dpif/dpif_types.h> /* Include for cmplx16ImRe_t and other DPIF types */ /* MATH utils library Include files */ #include <ti/utils/mathutils/mathutils.h> /* Internal include Files */ #include <ti/datapath/dpu/rangeproc/include/rangeprochwa_internal.h> #include <ti/datapath/dpu/transmission/include/transmission_internal.h> #include <ti/datapath/dpc/communication/include/communicationinternal.h> #include <ti/dsplib_c64Px_3_4_0_0/packages/ti/dsplib/src/DSP_fft16x16_imre/c64P/DSP_fft16x16_imre_cn.h> #include <ti/dsplib_c64Px_3_4_0_0/packages/ti/dsplib/src/DSP_fft16x16_imre/c64P/DSP_fft16x16_imre_cn.c> #include <ti/dsplib_c64Px_3_4_0_0/packages/ti/dsplib/src/DSP_fft16x16_imre/c64P/gen_twiddle_fft16x16_imre.h> #include <ti/dsplib_c64Px_3_4_0_0/packages/ti/dsplib/src/DSP_fft16x16_imre/c64P/gen_twiddle_fft16x16_imre.c> #include <ti/sysbios/knl/Task.h> /* Flag to check input parameters */ #define DEBUG_CHECK_PARAMS 1 /************************************************************************** ************************ Internal Functions Prototype ********************** **************************************************************************/ static void transmissionHWADoneIsrCallback(void * arg); static void transmissionHWA_EDMA_transferCompletionCallbackFxn(uintptr_t arg, uint8_t transferCompletionCode); static void dumpADCBuffer(cmplx16ImRe_t *buffer, uint32_t size); static int32_t transmissionHWA_ConfigEDMATranspose ( transmission_dpParams *dpParams, EDMA_Handle handle, DPEDMA_ChanCfg *chanCfg, DPEDMA_ChainingCfg *chainingCfg, uint32_t srcAddress, uint32_t destAddress, bool isTransferCompletionEnabled, EDMA_transferCompletionCallbackFxn_t transferCompletionCallbackFxn, uintptr_t transferCompletionCallbackFxnArg ); static int32_t transmissionHWA_ConfigHWA ( transmissionHWAObj *transmissionObj, uint8_t destChanPing, uint8_t destChanPong, uint16_t hwaMemSrcPingOffset, uint16_t hwaMemSrcPongOffset, uint16_t hwaMemDestPingOffset, uint16_t hwaMemDestPongOffset ); static int32_t transmissionHWA_TriggerHWA ( transmissionHWAObj *transmissionObj ); static int32_t transmissionHWA_ConfigEDMA_DataOut_interleave ( transmissionHWAObj *transmissionObj, transmission_dpParams *DPParams, DPU_Transmission_HW_Resources *pHwConfig, uint32_t hwaOutPingOffset, uint32_t hwaOutPongOffset ); static int32_t transmissionHWA_ConfigEDMA_DataIn ( transmissionHWAObj *transmissionObj, transmission_dpParams *DPParams, DPU_Transmission_HW_Resources *pHwConfig ); static int32_t transmissionHWA_ConifgInterleaveMode ( transmissionHWAObj *transmissionObj, transmission_dpParams *DPParams, DPU_Transmission_HW_Resources *pHwConfig ); /* static int32_t rangeProcHWA_ConifgNonInterleaveMode ( rangeProcHWAObj *rangeProcObj, rangeProc_dpParams *DPParams, DPU_RangeProcHWA_HW_Resources *pHwConfig ); static int32_t rangeProcHWA_dcRangeSignatureCompensation_init ( rangeProcHWAObj *rangeProcObj, DPU_RangeProc_CalibDcRangeSigCfg *calibDcRangeSigCfg, uint8_t resetMeanBuffer ); static void rangeProcHWA_dcRangeSignatureCompensation ( rangeProcHWAObj *obj ); static int32_t rangeProcHWA_ConfigEDMADummyThreeLinks -- volgens mij enkel nodig voor non interleave mode ( EDMA_Handle handle, DPEDMA_3LinkChanCfg *chanCfg, uint8_t chainChId0, uint8_t chainChId1, uint8_t chainChId2, uint16_t numIter, EDMA_transferCompletionCallbackFxn_t transferCompletionCallbackFxn, uintptr_t transferCompletionCallbackFxnArg ); */ /************************************************************************** ************************ transmission Internal Functions ********************** **************************************************************************/ /** * @b Description * @n * HWA processing completion call back function as per HWA API. * Depending on the programmed transfer completion codes, * posts HWA done semaphore. * * @param[in] arg Argument to the callback function * * \ingroup DPU_RANGEPROC_INTERNAL_FUNCTION * * @retval N/A */ static void transmissionHWADoneIsrCallback(void * arg) { transmissionHWAObj *transmissionObj = NULL; System_printf("Debug: HWA Done ISR Callback called! Releasing the HWA Semaphore.\n"); if (arg != NULL) { transmissionObj = (transmissionHWAObj *)arg; System_printf("Debug: HWA Callback - transmissionObj @ %p\n", transmissionObj); System_printf("Debug: HWA Callback - posting semaphore @ %p\n", transmissionObj->hwaDoneSemaHandle); /* Print HWA status */ System_printf("Debug: HWA numProcess = %d\n", transmissionObj->numProcess); SemaphoreP_post(transmissionObj->hwaDoneSemaHandle); } else { System_printf("Error: HWA callback received NULL arg\n"); } } /** * @b Description * @n * EDMA processing completion call back function as per EDMA API. * * @param[in] arg Argument to the callback function * @param[in] transferCompletionCode EDMA transfer complete code * * \ingroup DPU_RANGEPROC_INTERNAL_FUNCTION * * @retval N/A */ static void transmissionHWA_EDMA_transferCompletionCallbackFxn(uintptr_t arg, uint8_t transferCompletionCode) { transmissionHWAObj *transmissionObj; /* Get rangeProc object */ transmissionObj = (transmissionHWAObj *)arg; System_printf("Debug: EDMA transfer completion callback called with code %d!\n", transferCompletionCode); System_printf("Debug: dataOutSignatureChan = %d\n", transmissionObj->dataOutSignatureChan); System_printf("Debug: Releasing the EDMA Semaphore.\n"); if (transferCompletionCode == transmissionObj->dataOutSignatureChan) { transmissionObj->numEdmaDataOutCnt++; System_printf("Debug: EDMA Callback - posting semaphore @ %p (count %d)\n", transmissionObj->edmaDoneSemaHandle, transmissionObj->numEdmaDataOutCnt); SemaphoreP_post(transmissionObj->edmaDoneSemaHandle); } else { System_printf("Warning: EDMA callback with unrecognized completion code %d\n", transferCompletionCode); } } /** * @b Description * @n * Function to config a dummy channel with 3 linked paramset. Each paramset is linked * to a EDMA data copy channel * * @param[in] dpParams Pointer to data path parameters * @param[in] handle EDMA handle * @param[in] chanCfg EDMA channel configuraton * @param[in] chainingCfg EDMA chaining configuration * @param[in] srcAddress EDMA copy source address * @param[in] destAddress EDMA copy destination address * @param[in] isTransferCompletionEnabled Number of iterations the dummy channel will be excuted. * @param[in] transferCompletionCallbackFxn Transfer completion call back function. * @param[in] transferCompletionCallbackFxnArg Argument for transfer completion call back function. * * \ingroup DPU_RANGEPROC_INTERNAL_FUNCTION * * @retval N/A */ static int32_t transmissionHWA_ConfigEDMATranspose // suspect ( transmission_dpParams *dpParams, EDMA_Handle handle, DPEDMA_ChanCfg *chanCfg, DPEDMA_ChainingCfg *chainingCfg, uint32_t srcAddress, uint32_t destAddress, bool isTransferCompletionEnabled, EDMA_transferCompletionCallbackFxn_t transferCompletionCallbackFxn, uintptr_t transferCompletionCallbackFxnArg ) { DPEDMA_syncABCfg syncABCfg; int32_t retVal; /* dpedma configuration */ syncABCfg.aCount = dpParams->numRxAntennas * sizeof(cmplx16ImRe_t); syncABCfg.bCount = dpParams->numRangeBins; syncABCfg.cCount = dpParams->numChirpsPerFrame/2U; syncABCfg.srcBIdx = dpParams->numRxAntennas * sizeof(cmplx16ImRe_t); syncABCfg.srcCIdx = 0U; syncABCfg.dstBIdx = dpParams->numRxAntennas *dpParams->numChirpsPerFrame * sizeof(cmplx16ImRe_t); syncABCfg.dstCIdx = dpParams->numRxAntennas * 2U * sizeof(cmplx16ImRe_t); syncABCfg.srcAddress = srcAddress; syncABCfg.destAddress= destAddress; retVal = DPEDMA_configSyncAB(handle, chanCfg, chainingCfg, &syncABCfg, true, /* isEventTriggered */ false, /* isIntermediateTransferCompletionEnabled */ isTransferCompletionEnabled, /* isTransferCompletionEnabled */ transferCompletionCallbackFxn, transferCompletionCallbackFxnArg); if (retVal != EDMA_NO_ERROR) { goto exit; } exit: return (retVal); } /** * @b Description * @n * Internal function to config HWA to perform transmission * * @param[in] transmissionObj Pointer to transmission object * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_ConfigHWACommon ( transmissionHWAObj *transmissionObj ) { HWA_CommonConfig hwaCommonConfig; transmission_dpParams *DPParams; int32_t retVal; DPParams = &transmissionObj->params; /***********************/ /* HWA COMMON CONFIG */ /***********************/ /* 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.fftConfig.twidDitherEnable = HWA_FEATURE_BIT_ENABLE; hwaCommonConfig.fftConfig.lfsrSeed = 0x1234567; /*Some non-zero value*/ //hwaCommonConfig.numLoops = 1; hwaCommonConfig.numLoops = DPParams->numChirpsPerFrame/2U; hwaCommonConfig.paramStartIdx = transmissionObj->hwaCfg.paramSetStartIdx; hwaCommonConfig.paramStopIdx = 0 + DPU_TRANSMISSIONHWA_NUM_HWA_PARAM_SETS - 1U; // 3 -- should be good if (hwaCommonConfig.paramStopIdx > 15U) { System_printf("Error: paramStopIdx (%u) exceeds maximum value of 15.\n", hwaCommonConfig.paramStopIdx); retVal = DPU_TRANSMISSIONHWA_EINVAL; goto exit; } if (transmissionObj->hwaCfg.dataInputMode == DPU_RangeProcHWA_InputMode_ISOLATED) // we switched to MAPPED { /* 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.fft1DEnable = HWA_FEATURE_BIT_ENABLE; hwaCommonConfig.fftConfig.interferenceThreshold = 0xFFFFFF; System_printf("Debug: Calling HWA_configCommon.\n"); retVal = HWA_configCommon(transmissionObj->initParms.hwaHandle, &hwaCommonConfig); if (retVal != 0) { System_printf("Debug: Error raised by HWA_configCommon\n"); goto exit; } System_printf("Debug: Succesfully called: HWA_configCommon.\n"); /**********************************************/ /* ENABLE NUMLOOPS DONE INTERRUPT FROM HWA */ /**********************************************/ System_printf("Debug: Calling HWA_enableDoneInterrupt.\n"); System_printf("Debug: transmissionObj: %p\n", transmissionObj); System_printf("Debug: Sema Handle: %p \n", transmissionObj->hwaDoneSemaHandle); retVal = HWA_enableDoneInterrupt(transmissionObj->initParms.hwaHandle, transmissionHWADoneIsrCallback, transmissionObj->hwaDoneSemaHandle); // sets to call interrupt if all paramsets have completed succesfully if (retVal != 0) { goto exit; } System_printf("Debug: Succesfully called: HWA_enableDoneInterrupt.\n"); exit: return(retVal); } /** * @b Description * @n * Internal function to configure HWA for transmission processing * * @param[in] transmissionObj Pointer to transmission object * @param[in] destChanPing Destination EDMA channel ID for PING * @param[in] destChanPong Destination EDMA channel ID for PONG * @param[in] hwaMemSrcPingOffset Source address offset for Ping input in HWA memory * @param[in] hwaMemSrcPongOffset Source address offset for Pong input in HWA memory * @param[in] hwaMemDestPingOffset Destination address offset for Ping output in HWA memory * @param[in] hwaMemDestPongOffset Destination address offset for Pong output in HWA memory * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_ConfigHWA ( transmissionHWAObj *transmissionObj, uint8_t destChanPing, uint8_t destChanPong, uint16_t hwaMemSrcPingOffset, uint16_t hwaMemSrcPongOffset, uint16_t hwaMemDestPingOffset, uint16_t hwaMemDestPongOffset ) { HWA_InterruptConfig paramISRConfig; int32_t errCode = 0; uint32_t paramsetIdx = 0; uint32_t hwParamsetIdx; uint32_t pingParamSetIdx = 0; HWA_ParamConfig hwaParamCfg[DPU_TRANSMISSIONHWA_NUM_HWA_PARAM_SETS]; HWA_Handle hwaHandle; transmission_dpParams *pDPParams; uint8_t index; hwaHandle = transmissionObj->initParms.hwaHandle; pDPParams = &transmissionObj->params; /* Debug prints for memory address verification */ System_printf("ADCdataBuf Address: 0x%08x\n", (uint32_t)transmissionObj->ADCdataBuf); System_printf("HWA Src Ping Offset: 0x%04x, Translated: 0x%08x\n", hwaMemSrcPingOffset, ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->ADCdataBuf)); System_printf("HWA Src Pong Offset: 0x%04x, Translated: 0x%08x\n", hwaMemSrcPongOffset, ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->ADCdataBuf)); memset(hwaParamCfg, 0, sizeof(hwaParamCfg)); /* Disable existing HWA parameter set interrupts */ hwParamsetIdx = transmissionObj->hwaCfg.paramSetStartIdx; for (index = 0; index < DPU_TRANSMISSIONHWA_NUM_HWA_PARAM_SETS; index++) { errCode = HWA_disableParamSetInterrupt( hwaHandle, index + transmissionObj->hwaCfg.paramSetStartIdx, HWA_PARAMDONE_INTERRUPT_TYPE_CPU | HWA_PARAMDONE_INTERRUPT_TYPE_DMA); if (errCode != 0) { goto exit; } } /***********************/ /* PING DUMMY PARAMSET */ /***********************/ hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_DMA; hwaParamCfg[paramsetIdx].dmaTriggerSrc = hwParamsetIdx; // hwParamsetIdx is equal to 0 hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_NONE; System_printf("--------- PING DUMMY PARAMSET --------- \n"); System_printf("Debug: hwaHandle : %p \n", hwaHandle); System_printf("Debug: paramsetIdx : %d \n", paramsetIdx); System_printf("Debug: hwParamsetIdx : %d \n", hwParamsetIdx); System_printf("Debug: triggerMode : %d \n", hwaParamCfg[paramsetIdx].triggerMode); System_printf("Debug: dmaTriggerSrc : %d \n", hwaParamCfg[paramsetIdx].dmaTriggerSrc); System_printf("Debug: accelMode : %d \n", hwaParamCfg[paramsetIdx].accelMode); System_printf("--------------------------------------- \n"); errCode = HWA_configParamSet(hwaHandle, hwParamsetIdx, &hwaParamCfg[paramsetIdx], NULL); if (errCode != 0) { goto exit; } // Configure the dummy paramset to generate a DFE trigger when it completes // We'll use CPU interrupt type as a workaround if DFE connections aren't directly configurable paramISRConfig.interruptTypeFlag = HWA_PARAMDONE_INTERRUPT_TYPE_DMA; paramISRConfig.dma.dstChannel = 1; // This DMA channel should be connected to the FFT paramset errCode = HWA_enableParamSetInterrupt(hwaHandle, hwParamsetIdx, ¶mISRConfig); if (errCode != 0) { goto exit; } /**************************/ /* PING PROCESS PARAMSET */ /**************************/ paramsetIdx++; // 1 hwParamsetIdx++; // 1 pingParamSetIdx = paramsetIdx; // 1 /* Configure the HWA for transmission processing */ /* For DMA trigger to work, we need to properly connect the trigger path */ if(transmissionObj->hwaCfg.dataInputMode == DPU_RangeProcHWA_InputMode_MAPPED) // we're using MAPPED mode { /* In MAPPED mode, we'll use DMA trigger mode instead of DFE trigger mode * This ensures that the FFT paramset will wait for a trigger from * the dummy paramset before proceeding */ hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_DMA; hwaParamCfg[paramsetIdx].dmaTriggerSrc = 3; // Triggered by previous (dummy) paramset System_printf("Debug: Changed PING FFT paramset to DMA trigger mode with source %d\n", hwParamsetIdx - 1); } else { /*adcbuf not mapped, should trigger after edma copy is done */ hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_DMA; hwaParamCfg[paramsetIdx].dmaTriggerSrc = hwParamsetIdx; // hwParamsetIdx is equal to 1 } hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_FFT; /* Source configuration */ hwaParamCfg[paramsetIdx].source.srcAddr = hwaMemSrcPingOffset; hwaParamCfg[paramsetIdx].source.srcShift = 0; hwaParamCfg[paramsetIdx].source.srcCircShiftWrap = 0; hwaParamCfg[paramsetIdx].source.srcRealComplex = HWA_SAMPLES_FORMAT_COMPLEX; hwaParamCfg[paramsetIdx].source.srcWidth = HWA_SAMPLES_WIDTH_16BIT; hwaParamCfg[paramsetIdx].source.srcSign = HWA_SAMPLES_SIGNED; hwaParamCfg[paramsetIdx].source.srcConjugate = 0; hwaParamCfg[paramsetIdx].source.srcScale = 8; hwaParamCfg[paramsetIdx].source.bpmEnable = 0; hwaParamCfg[paramsetIdx].source.bpmPhase = 0; hwaParamCfg[paramsetIdx].dest.dstAddr = hwaMemDestPingOffset; /* Destination configuration */ hwaParamCfg[paramsetIdx].dest.dstRealComplex = HWA_SAMPLES_FORMAT_COMPLEX; hwaParamCfg[paramsetIdx].dest.dstWidth = HWA_SAMPLES_WIDTH_16BIT; hwaParamCfg[paramsetIdx].dest.dstSign = HWA_SAMPLES_SIGNED; hwaParamCfg[paramsetIdx].dest.dstConjugate = 0; hwaParamCfg[paramsetIdx].dest.dstScale = pDPParams->fftOutputDivShift; hwaParamCfg[paramsetIdx].dest.dstSkipInit = 0; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftEn = 1; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftSize = mathUtils_ceilLog2(pDPParams->numRangeBins); hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.butterflyScaling = (1 << pDPParams->numLastButterflyStagesToScale) - 1U; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.interfZeroOutEn = 0; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.windowEn = 1; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.windowStart = transmissionObj->hwaCfg.hwaWinRamOffset; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winSymm = transmissionObj->hwaCfg.hwaWinSym; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.winInterpolateMode = 0; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.magLogEn = HWA_FFT_MODE_MAGNITUDE_LOG2_DISABLED; hwaParamCfg[paramsetIdx].accelModeArgs.fftMode.fftOutMode = HWA_FFT_MODE_OUTPUT_DEFAULT; hwaParamCfg[paramsetIdx].complexMultiply.mode = HWA_COMPLEX_MULTIPLY_MODE_DISABLE; /* HWA range FFT src/dst configuration*/ if(transmissionObj->interleave == DPIF_RXCHAN_INTERLEAVE_MODE) { if(transmissionObj->radarCubeLayout == rangeProc_dataLayout_RANGE_DOPPLER_TxAnt_RxAnt) { hwaParamCfg[paramsetIdx].source.srcAcnt = pDPParams->numAdcSamples - 1; /* this is samples - 1 */ hwaParamCfg[paramsetIdx].source.srcAIdx = pDPParams->numRxAntennas* sizeof(uint32_t); hwaParamCfg[paramsetIdx].source.srcBcnt = pDPParams->numRxAntennas-1; hwaParamCfg[paramsetIdx].source.srcBIdx = sizeof(uint32_t); hwaParamCfg[paramsetIdx].dest.dstAcnt = pDPParams->numRangeBins-1; hwaParamCfg[paramsetIdx].dest.dstAIdx = pDPParams->numRxAntennas * sizeof(uint32_t); hwaParamCfg[paramsetIdx].dest.dstBIdx = sizeof(uint32_t); } else { /* Other radarCube layout format is not supported */ errCode = DPU_RANGEPROCHWA_ENOTIMPL; goto exit; } } else { System_printf("Error: interleave == NON INTERLEAVE\n"); errCode = DPU_TRANSMISSIONHWA_NONINTERLEAVE; goto exit; // added to make sure non interleave mode is not executed /* if(transmissionObj->radarCubeLayout == rangeProc_dataLayout_RANGE_DOPPLER_TxAnt_RxAnt) { hwaParamCfg[paramsetIdx].source.srcAcnt = pDPParams->numAdcSamples - 1; hwaParamCfg[paramsetIdx].source.srcAIdx = sizeof(uint32_t); hwaParamCfg[paramsetIdx].source.srcBcnt = pDPParams->numRxAntennas-1; hwaParamCfg[paramsetIdx].source.srcBIdx = transmissionObj->rxChanOffset; hwaParamCfg[paramsetIdx].dest.dstAcnt = pDPParams->numRangeBins-1; hwaParamCfg[paramsetIdx].dest.dstAIdx = sizeof(uint32_t) * pDPParams->numRxAntennas; hwaParamCfg[paramsetIdx].dest.dstBIdx = sizeof(uint32_t); } else { hwaParamCfg[paramsetIdx].source.srcAcnt = pDPParams->numAdcSamples - 1; hwaParamCfg[paramsetIdx].source.srcAIdx = sizeof(uint32_t); hwaParamCfg[paramsetIdx].source.srcBcnt = pDPParams->numRxAntennas-1; hwaParamCfg[paramsetIdx].source.srcBIdx = transmissionObj->rxChanOffset; hwaParamCfg[paramsetIdx].dest.dstAcnt = pDPParams->numRangeBins-1; hwaParamCfg[paramsetIdx].dest.dstAIdx = sizeof(uint32_t); hwaParamCfg[paramsetIdx].dest.dstBIdx = pDPParams->numRangeBins * sizeof(uint32_t); } */ } /* Configure the parameter set */ System_printf("--------- PING PARAMSET --------- \n"); System_printf("Debug: hwaHandle : %p \n", hwaHandle); System_printf("Debug: paramsetIdx : %d \n", paramsetIdx); System_printf("Debug: hwParamsetIdx : %d \n", hwParamsetIdx); System_printf("Debug: triggerMode : %d \n", hwaParamCfg[paramsetIdx].triggerMode); System_printf("Debug: dmaTriggerSrc : %d \n", hwaParamCfg[paramsetIdx].dmaTriggerSrc); System_printf("Debug: accelMode : %d \n", hwaParamCfg[paramsetIdx].accelMode); System_printf("--------------------------------------- \n"); errCode = HWA_configParamSet(hwaHandle, hwParamsetIdx, &hwaParamCfg[hwParamsetIdx], NULL); if (errCode != 0) { goto exit; } /* Enable the DMA hookup to this paramset so that data gets copied out */ paramISRConfig.interruptTypeFlag = HWA_PARAMDONE_INTERRUPT_TYPE_DMA; paramISRConfig.dma.dstChannel = destChanPing; errCode = HWA_enableParamSetInterrupt(hwaHandle, hwParamsetIdx, ¶mISRConfig); if (errCode != 0) { goto exit; } /***********************/ /* PONG DUMMY PARAMSET */ /***********************/ paramsetIdx++; // 2 hwParamsetIdx++; // 2 hwaParamCfg[paramsetIdx].triggerMode = HWA_TRIG_MODE_DMA; hwaParamCfg[paramsetIdx].dmaTriggerSrc = hwParamsetIdx; // hwParamsetIdx is equal to 2 hwaParamCfg[paramsetIdx].accelMode = HWA_ACCELMODE_NONE; System_printf("--------- PONG DUMMY PARAMSET --------- \n"); System_printf("Debug: hwaHandle : %p \n", hwaHandle); System_printf("Debug: paramsetIdx : %d \n", paramsetIdx); System_printf("Debug: hwParamsetIdx : %d \n", hwParamsetIdx); System_printf("Debug: triggerMode : %d \n", hwaParamCfg[paramsetIdx].triggerMode); System_printf("Debug: dmaTriggerSrc : %d \n", hwaParamCfg[paramsetIdx].dmaTriggerSrc); System_printf("Debug: accelMode : %d \n", hwaParamCfg[paramsetIdx].accelMode); System_printf("---------------------------------------\n"); errCode = HWA_configParamSet(hwaHandle, hwParamsetIdx, &hwaParamCfg[paramsetIdx],NULL); if (errCode != 0) { goto exit; } // Configure the dummy paramset to generate a trigger when it completes paramISRConfig.interruptTypeFlag = HWA_PARAMDONE_INTERRUPT_TYPE_DMA; paramISRConfig.dma.dstChannel = 3; // This DMA channel should be connected to the FFT paramset errCode = HWA_enableParamSetInterrupt(hwaHandle, hwParamsetIdx, ¶mISRConfig); if (errCode != 0) { goto exit; } /**************************/ /* PONG PROCESS PARAMSET */ /**************************/ paramsetIdx++; hwParamsetIdx++; hwaParamCfg[paramsetIdx] = hwaParamCfg[pingParamSetIdx]; hwaParamCfg[paramsetIdx].source.srcAddr = hwaMemSrcPongOffset; hwaParamCfg[paramsetIdx].dest.dstAddr = hwaMemDestPongOffset; // Keep the same trigger configuration as PING PROCESS PARAMSET if(transmissionObj->hwaCfg.dataInputMode == DPU_RangeProcHWA_InputMode_MAPPED) { // Update DMA trigger source - should be the PONG dummy paramset hwaParamCfg[paramsetIdx].dmaTriggerSrc = 1; // Triggered by previous (dummy) paramset System_printf("Debug: Changed PONG FFT paramset to DMA trigger mode with source %d\n", hwParamsetIdx - 1); } else { // Update DMA trigger source only if not in MAPPED mode hwaParamCfg[paramsetIdx].dmaTriggerSrc = hwParamsetIdx; // hwParamsetIdx is equal to 3 } System_printf("--------- PONG PARAMSET --------- \n"); System_printf("Debug: hwaHandle : %p \n", hwaHandle); System_printf("Debug: paramsetIdx : %d \n", paramsetIdx); System_printf("Debug: hwParamsetIdx : %d \n", hwParamsetIdx); System_printf("Debug: triggerMode : %d \n", hwaParamCfg[paramsetIdx].triggerMode); System_printf("Debug: dmaTriggerSrc : %d \n", hwaParamCfg[paramsetIdx].dmaTriggerSrc); System_printf("Debug: accelMode : %d \n", hwaParamCfg[paramsetIdx].accelMode); System_printf("--------------------------------------- \n"); errCode = HWA_configParamSet(hwaHandle, hwParamsetIdx, &hwaParamCfg[paramsetIdx],NULL); if (errCode != 0) { goto exit; } /* Enable the DMA hookup to this paramset so that data gets copied out */ paramISRConfig.interruptTypeFlag = HWA_PARAMDONE_INTERRUPT_TYPE_DMA; paramISRConfig.dma.dstChannel = destChanPong; errCode = HWA_enableParamSetInterrupt(hwaHandle, hwParamsetIdx, ¶mISRConfig); if (errCode != 0) { goto exit; } exit: return errCode; } /** * @b Description * @n * Trigger HWA for transmission processing. * * @param[in] transmissionObj Pointer to transmission object * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_TriggerHWA ( transmissionHWAObj *transmissionObj ) { int32_t retVal = 0; HWA_Handle hwaHandle; uint8_t paramSetStatus = 0; /* Get HWA driver handle */ hwaHandle = transmissionObj->initParms.hwaHandle; /* Debug: Dump ADC buffer contents before HWA processing */ System_printf("Debug: Dumping ADC buffer before HWA processing\n"); if (transmissionObj->ADCdataBuf != NULL) { uint32_t numSamples = transmissionObj->params.numAdcSamples * transmissionObj->params.numRxAntennas * transmissionObj->params.numChirpsPerFrame; dumpADCBuffer(transmissionObj->ADCdataBuf, numSamples); } else { System_printf("Error: ADCdataBuf is NULL\n"); } /* Configure HWA common parameters */ System_printf("Debug: Calling transmissionHWA_ConfigHWACommon.\n"); retVal = transmissionHWA_ConfigHWACommon(transmissionObj); if(retVal < 0) { goto exit; } System_printf("Debug: Succesfully called: transmissionHWA_ConfigHWACommon.\n"); /* Enable the HWA */ System_printf("Debug: Calling HWA_enable.\n"); retVal = HWA_enable(hwaHandle, 1); if (retVal != 0) { goto exit; } System_printf("Debug: Succesfully called: HWA_enable.\n"); /* Verify memory mapping for MAPPED mode */ if (transmissionObj->hwaCfg.dataInputMode == DPU_RangeProcHWA_InputMode_MAPPED) { System_printf("Debug: Operating in MAPPED mode - checking memory configuration.\n"); System_printf("Debug: hwaMemBankAddr[0] = 0x%08x\n", (uint32_t)transmissionObj->hwaMemBankAddr[0]); System_printf("Debug: ADCdataBuf = 0x%08x\n", (uint32_t)transmissionObj->ADCdataBuf); } /* Trigger the HWA paramset for Ping - this should start the chain reaction */ System_printf("Debug: Calling HWA_setDMA2ACCManualTrig for PING dummy paramset.\n"); System_printf("Debug: dataOutTrigger value: %d \n", transmissionObj->dataOutTrigger[0]); retVal = HWA_setDMA2ACCManualTrig(hwaHandle, transmissionObj->dataOutTrigger[0]); if (retVal != 0) { goto exit; } System_printf("Debug: Succesfully called: HWA_setDMA2ACCManualTrig for PING dummy.\n"); /* Trigger the HWA paramset for Pong */ System_printf("Debug: Calling HWA_setDMA2ACCManualTrig for PONG dummy paramset.\n"); System_printf("Debug: dataOutTrigger value: %d \n", transmissionObj->dataOutTrigger[1]); retVal = HWA_setDMA2ACCManualTrig(hwaHandle, transmissionObj->dataOutTrigger[1]); if (retVal != 0) { goto exit; } System_printf("Debug: Succesfully called: HWA_setDMA2ACCManualTrig for PONG dummy.\n"); exit: return(retVal); } /** * @b Description * @n * EDMA configuration for transmission data output in interleave mode * * @param[in] transmissionObj Pointer to transmission object * @param[in] pParams Pointer to transmission parameters * @param[in] pHwConfig Pointer to transmission hardware resources * @param[in] hwaOutPingOffset Ping HWA memory address offset * @param[in] hwaOutPongOffset Pong HWA memory address offset * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_ConfigEDMA_DataOut_interleave ( transmissionHWAObj *transmissionObj, transmission_dpParams *pParams, DPU_Transmission_HW_Resources *pHwConfig, uint32_t hwaOutPingOffset, uint32_t hwaOutPongOffset ) { int32_t errorCode = EDMA_NO_ERROR; EDMA_Handle handle; DPEDMA_ChainingCfg chainingCfg; /* Get transmission hardware resources pointer */ handle = transmissionObj->edmaHandle; /* Setup Chaining configuration */ chainingCfg.chainingChan = pHwConfig->edmaOutCfg.dataOutSignature.channel; chainingCfg.isIntermediateChainingEnabled = true; chainingCfg.isFinalChainingEnabled = true; /* Configure EDMA for Ping buffer */ int i = 0; for (; i < 3; i++) { System_printf("Debug: Calling transmissionHWA_ConfigEDMATranspose for ping\n"); errorCode = transmissionHWA_ConfigEDMATranspose(pParams, handle, &pHwConfig->edmaOutCfg.u.fmt2.dataOutPingData[i], &chainingCfg, hwaOutPingOffset, (uint32_t)transmissionObj->radarCubebuf, //+ pingOffset[i], false, // isTransferCompletionEnabled NULL, NULL); if (errorCode != EDMA_NO_ERROR) { goto exit; } } System_printf("Debug: Succesfully Called: transmissionHWA_ConfigEDMATranspose for ping 3 times\n"); /* Configure EDMA for Pong buffer */ i = 0; for (; i < 3; i++) { System_printf("Debug: Calling transmissionHWA_ConfigEDMATranspose for pong\n"); errorCode = transmissionHWA_ConfigEDMATranspose(pParams, handle, &pHwConfig->edmaOutCfg.u.fmt2.dataOutPongData[i], &chainingCfg, hwaOutPongOffset, (uint32_t)transmissionObj->radarCubebuf, //+ pongOffset[i], true, transmissionHWA_EDMA_transferCompletionCallbackFxn, (uintptr_t)transmissionObj); if (errorCode != EDMA_NO_ERROR) { goto exit; } } System_printf("Debug: Succesfully Called: transmissionHWA_ConfigEDMATranspose for pong 3 times\n"); /************************************************************************** * HWA hot signature EDMA, chained to the data output EDMA channels *************************************************************************/ System_printf("Debug: Calling DPEDMAHWA_configTwoHotSignature in Data Out\n"); System_printf("Debug: dataOutTrigger 0: %d\n", 0); System_printf("Debug: dataOutTrigger 1: %d\n", 2); errorCode = DPEDMAHWA_configTwoHotSignature(handle, &pHwConfig->edmaOutCfg.dataOutSignature, transmissionObj->initParms.hwaHandle, 0, 2, false); /* System_printf("Debug: dataOutTrigger 0: %d\n", transmissionObj->dataOutTrigger[0]); System_printf("Debug: dataOutTrigger 1: %d\n", transmissionObj->dataOutTrigger[1]); errorCode = DPEDMAHWA_configTwoHotSignature(handle, &pHwConfig->edmaOutCfg.dataOutSignature, transmissionObj->initParms.hwaHandle, transmissionObj->dataOutTrigger[0], transmissionObj->dataOutTrigger[1], false); */ if (errorCode != EDMA_NO_ERROR) { goto exit; } System_printf("Debug: Succesfully Called DPEDMAHWA_configTwoHotSignature in Data Out\n"); exit: return(errorCode); } /** * @b Description * @n * EDMA configuration for transmission data in when EDMA is used to copy data from * ADCBuf to HWA memory * * @param[in] transmissionObj Pointer to transmission object handle * @param[in] DPParams Pointer to datapath parameter * @param[in] pHwConfig Pointer to transmission hardware resources * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_ConfigEDMA_DataIn // copies data from ADC buf to HWA and should be triggered by the dummy paramsets ( transmissionHWAObj *transmissionObj, transmission_dpParams *DPParams, DPU_Transmission_HW_Resources *pHwConfig ) { int32_t errorCode = EDMA_NO_ERROR; EDMA_Handle handle ; uint16_t bytePerRxChan; DPEDMA_ChainingCfg chainingCfg; /* Get rangeProc Configuration */ handle = transmissionObj->edmaHandle; bytePerRxChan = DPParams->numAdcSamples * sizeof(cmplx16ImRe_t); /**********************************************/ /* ADCBuf -> Ping/Pong Buffer(M0 and M1) */ /**********************************************/ chainingCfg.chainingChan = pHwConfig->edmaInCfg.dataInSignature.channel; chainingCfg.isFinalChainingEnabled = true; chainingCfg.isIntermediateChainingEnabled = true; if (transmissionObj->interleave == DPIF_RXCHAN_NON_INTERLEAVE_MODE) { System_printf("Error: interleave == NON INTERLEAVE\n"); errorCode = DPU_TRANSMISSIONHWA_NONINTERLEAVE; goto exit; /* DPEDMA_syncABCfg syncABCfg; syncABCfg.srcAddress = (uint32_t)transmissionObj->ADCdataBuf; syncABCfg.destAddress = transmissionObj->hwaMemBankAddr[0]; syncABCfg.aCount = bytePerRxChan; syncABCfg.bCount = DPParams->numRxAntennas; syncABCfg.cCount =2U; // ping and pong syncABCfg.srcBIdx=transmissionObj->rxChanOffset; syncABCfg.dstBIdx=transmissionObj->rxChanOffset; syncABCfg.srcCIdx=0U; syncABCfg.dstCIdx=((uint32_t)transmissionObj->hwaMemBankAddr[1] - (uint32_t)transmissionObj->hwaMemBankAddr[0]); errorCode = DPEDMA_configSyncAB(handle, &pHwConfig->edmaInCfg.dataIn, &chainingCfg, &syncABCfg, true, // isEventTriggered false, // isIntermediateTransferInterruptEnabled false, // isFinalTransferInterruptEnabled NULL, (uintptr_t)NULL); */ } else { DPEDMA_syncACfg syncACfg; syncACfg.srcAddress = (uint32_t)transmissionObj->ADCdataBuf; syncACfg.destAddress = transmissionObj->hwaMemBankAddr[0]; syncACfg.aCount = bytePerRxChan * DPParams->numRxAntennas; syncACfg.bCount =2U; /* ping and pong */ syncACfg.srcBIdx=0U; syncACfg.dstBIdx=((uint32_t)transmissionObj->hwaMemBankAddr[1] - (uint32_t)transmissionObj->hwaMemBankAddr[0]); errorCode = DPEDMA_configSyncA_singleFrame(handle, &pHwConfig->edmaInCfg.dataIn, &chainingCfg, &syncACfg, true, /* isEventTriggered */ false, /* isIntermediateTransferInterruptEnabled */ false, /* isFinalTransferInterruptEnabled */ NULL, (uintptr_t)NULL); } if (errorCode != EDMA_NO_ERROR) { goto exit; } /*************************************************/ /* Generate Hot Signature to trigger Ping/Pong paramset */ /*************************************************/ System_printf("Debug: Calling DPEDMAHWA_configTwoHotSignature in Data In\n"); System_printf("Debug: dataInTrigger 0: %d\n", 1); System_printf("Debug: dataInTrigger 1: %d\n", 3); errorCode = DPEDMAHWA_configTwoHotSignature(handle, &pHwConfig->edmaInCfg.dataInSignature, transmissionObj->initParms.hwaHandle, transmissionObj->dataInTrigger[0], // == 1 dit klopt want Paramset 1 will begin execution after a trigger from DMA channel 1. If paramset 0 completion generates a hot signature on channel 1, then paramset 1 (the FFT paramset) will start automatically. transmissionObj->dataInTrigger[1], // == 3 false); // false omdat deze manual getriggered worden /* errorCode = DPEDMAHWA_configTwoHotSignature(handle, &pHwConfig->edmaInCfg.dataInSignature, transmissionObj->initParms.hwaHandle, transmissionObj->dataInTrigger[0], transmissionObj->dataInTrigger[1], false); // false omdat deze manual getriggered worden */ if (errorCode != EDMA_NO_ERROR) { goto exit; } System_printf("Debug: Succesfully Called: DPEDMAHWA_configTwoHotSignature in Data In\n"); exit: return(errorCode); } /** * @b Description * @n * transmission configuraiton in interleaved mode * * @param[in] transmissionObj Pointer to transmission object * @param[in] DPParams Pointer to data path common params * @param[in] pHwConfig Pointer to transmission hardware resources * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_ConifgInterleaveMode ( transmissionHWAObj *transmissionObj, transmission_dpParams *DPParams, DPU_Transmission_HW_Resources *pHwConfig ) { int32_t retVal = 0; uint8_t destChanPing; uint8_t destChanPong; HWA_Handle hwaHandle; hwaHandle = transmissionObj->initParms.hwaHandle; /* In interleave mode, only edmaOutCfgFmt is supported */ retVal = HWA_getDMAChanIndex(hwaHandle, pHwConfig->edmaOutCfg.u.fmt2.dataOutPing.channel, &destChanPing); if (retVal != 0) { System_printf("Error: Calling HWA_getDMAChanIndex 1: %d\n", retVal); goto exit; } /* In interleave mode, only edmaOutCfgFmt is supported */ retVal = HWA_getDMAChanIndex(hwaHandle, pHwConfig->edmaOutCfg.u.fmt2.dataOutPong.channel, &destChanPong); if (retVal != 0) { System_printf("Error: Calling HWA_getDMAChanIndex 2: %d\n", retVal); goto exit; } if(pHwConfig->hwaCfg.dataInputMode == DPU_Transmission_InputMode_ISOLATED) // moving to MAPPED { /* Copy data from ADC buffer to HWA buffer */ System_printf("ERROR: Should not be called\n"); transmissionHWA_ConfigEDMA_DataIn(transmissionObj, DPParams, pHwConfig); /* Range FFT configuration in HWA */ retVal = transmissionHWA_ConfigHWA(transmissionObj, destChanPing, destChanPong, ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[0]), ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[1]), ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[2]), ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[3]) ); if(retVal < 0) { System_printf("Error: Calling transmissionHWA_ConfigHWA: %d\n", retVal); goto exit; } } else { /* Range FFT configuration in HWA */ System_printf("Debug: Calling configHWA in mapped mode\n"); retVal = transmissionHWA_ConfigHWA(transmissionObj, destChanPing, destChanPong, ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[0]), ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[0]), ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[2]), ADDR_TRANSLATE_CPU_TO_HWA(transmissionObj->hwaMemBankAddr[3]) ); if(retVal < 0) { goto exit; } } /* EDMA configuration */ System_printf("Debug: Calling transmissionHWA_ConfigEDMA_DataOut_interleave\n"); retVal = transmissionHWA_ConfigEDMA_DataOut_interleave(transmissionObj, DPParams, pHwConfig, (uint32_t)transmissionObj->hwaMemBankAddr[2], (uint32_t)transmissionObj->hwaMemBankAddr[3]); System_printf("Debug: Succesfully Called: transmissionHWA_ConfigEDMA_DataOut_interleave\n"); exit: return (retVal); } /** * @b Description * @n * Internal function to parse transmission configuration and save in internal transmission object * * @param[in] transmissionObj Pointer to transmission object * @param[in] pConfigIn Pointer to transmission configuration structure * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_ParseConfig ( transmissionHWAObj *transmissionObj, DPU_TransmissionHWA_Config *pConfigIn ) { int32_t retVal = 0; transmission_dpParams *params; DPU_Transmission_StaticConfig *pStaticCfg; /* Get configuration pointers */ pStaticCfg = &pConfigIn->staticCfg; params = &transmissionObj->params; /* Save data path parameters */ params->numTxAntennas = pStaticCfg->numTxAntennas; params->numRxAntennas = pStaticCfg->ADCBufData.dataProperty.numRxAntennas; params->numVirtualAntennas = pStaticCfg->numVirtualAntennas; params->numChirpsPerChirpEvent = pStaticCfg->ADCBufData.dataProperty.numChirpsPerChirpEvent; params->numAdcSamples = pStaticCfg->ADCBufData.dataProperty.numAdcSamples; params->numRangeBins = pStaticCfg->numRangeBins; params->numChirpsPerFrame = pStaticCfg->numChirpsPerFrame; params->numDopplerChirps = pStaticCfg->numChirpsPerFrame / pStaticCfg->numTxAntennas; params->fftOutputDivShift = pStaticCfg->rangeFFTtuning.fftOutputDivShift; params->numLastButterflyStagesToScale = pStaticCfg->rangeFFTtuning.numLastButterflyStagesToScale; /* Save buffers */ transmissionObj->ADCdataBuf = (cmplx16ImRe_t *)pStaticCfg->ADCBufData.data; transmissionObj->radarCubebuf = (cmplx16ImRe_t *)pConfigIn->hwRes.radarCube.data; /* Save interleave mode from ADCBuf configuration */ transmissionObj->interleave = pStaticCfg->ADCBufData.dataProperty.interleave; if ((transmissionObj->interleave == DPIF_RXCHAN_NON_INTERLEAVE_MODE) && (params->numRxAntennas > 1)) { retVal = DPU_TRANSMISSIONHWA_NONINTERLEAVE; goto exit; // added to make sure non interleave mode is not set /* For transmissionHWA, we need rx channel to have the same offset from one channel to the next transmissionObj->rxChanOffset = pStaticCfg->ADCBufData.dataProperty.rxChanOffset[1] - pStaticCfg->ADCBufData.dataProperty.rxChanOffset[0]; Validate rxChanOffset if ((transmissionObj->rxChanOffset < (params->numAdcSamples * sizeof(cmplx16ImRe_t))) || ((transmissionObj->rxChanOffset & 0xF) != 0)) { retVal = DPU_TRANSMISSIONHWA_EADCBUF_INTF; goto exit; } */ } /* Save RadarCube format */ if (pConfigIn->hwRes.radarCube.datafmt == DPIF_RADARCUBE_FORMAT_2) { transmissionObj->radarCubeLayout = rangeProc_dataLayout_RANGE_DOPPLER_TxAnt_RxAnt; } else { retVal = DPU_RANGEPROCHWA_EINTERNAL; goto exit; } /* The following case can not be handled with the current 1TX EDMA scheme, reason is the Bindex exceeds what EDMA can handle. */ if( (params->numRangeBins == 1024U) && (params->numTxAntennas == 1U) && (params->numRxAntennas == 4U) && (transmissionObj->radarCubeLayout == rangeProc_dataLayout_TxAnt_DOPPLER_RxAnt_RANGE) ) { retVal = DPU_RANGEPROCHWA_ENOTIMPL; goto exit; } /* The following case can not be handled with the current 3TX EDMA scheme, reason is the Bindex exceeds what EDMA(jump index<32768) can handle. */ if( (params->numRangeBins == 1024U) && (params->numTxAntennas == 3U) && (params->numRxAntennas == 4U) && (transmissionObj->radarCubeLayout == rangeProc_dataLayout_TxAnt_DOPPLER_RxAnt_RANGE) ) { retVal = DPU_RANGEPROCHWA_ENOTIMPL; goto exit; } /* Prepare internal hardware resouces = trigger source matchs its paramset index */ transmissionObj->dataInTrigger[0] = 1U + pConfigIn->hwRes.hwaCfg.paramSetStartIdx; //paramSetStartIdX = 0 transmissionObj->dataInTrigger[1] = 3U + pConfigIn->hwRes.hwaCfg.paramSetStartIdx; //paramSetStartIdX = 0 transmissionObj->dataOutTrigger[0] = 0U + pConfigIn->hwRes.hwaCfg.paramSetStartIdx; //paramSetStartIdX = 0 transmissionObj->dataOutTrigger[1] = 2U + pConfigIn->hwRes.hwaCfg.paramSetStartIdx; //paramSetStartIdX = 0 /* Save hardware resources that will be used at runtime */ transmissionObj->edmaHandle= pConfigIn->hwRes.edmaHandle; transmissionObj->dataOutSignatureChan = pConfigIn->hwRes.edmaOutCfg.dataOutSignature.channel; transmissionObj->dcRangeSigMean = pConfigIn->hwRes.dcRangeSigMean; transmissionObj->dcRangeSigMeanSize = pConfigIn->hwRes.dcRangeSigMeanSize; memcpy((void *)&transmissionObj->hwaCfg, (void *)&pConfigIn->hwRes.hwaCfg, sizeof(DPU_Transmission_HwaConfig)); exit: return(retVal); } /** * @b Description * @n * Internal function to config HWA/EDMA to perform transmission * * @param[in] rangeProcObj Pointer to transmssion object * @param[in] pHwConfig Pointer to transmission hardware resources * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ static int32_t transmissionHWA_HardwareConfig ( transmissionHWAObj *transmissionObj, DPU_Transmission_HW_Resources *pHwConfig ) { int32_t retVal = 0; transmission_dpParams *DPParams; DPParams = &transmissionObj->params; if (transmissionObj->interleave == DPIF_RXCHAN_INTERLEAVE_MODE) { System_printf("Debug: Calling transmissionHWA_ConifgInterleaveMode\n"); retVal = transmissionHWA_ConifgInterleaveMode(transmissionObj, DPParams, pHwConfig); if (retVal != 0) { System_printf("Error: ConfigInterLeaveMode RetVal: %d\n", retVal); goto exit; } System_printf("Debug: Succesfully called: transmissionHWA_ConifgInterleaveMode\n"); } exit: return(retVal); } /************************************************************************** ************************Transmission External APIs ************************** **************************************************************************/ /** * @b Description * @n * The function is transmisison DPU init function. It allocates memory to store * its internal data object and returns a handle if it executes successfully. * * @param[in] initParams Pointer to DPU init parameters * @param[in] errCode Pointer to errCode generates from the API * * \ingroup DPU_TRANSMISSION_EXTERNAL_FUNCTION * * @retval * Success - valid transmission handle * @retval * Error - NULL */ DPU_Transmission_Handle DPU_TransmissionHWA_init ( DPU_Transmission_InitParams *initParams, int32_t* errCode ) { transmissionHWAObj *transmissionObj = NULL; SemaphoreP_Params semParams; HWA_MemInfo hwaMemInfo; uint8_t index; *errCode = 0; if( (initParams == NULL) || (initParams->hwaHandle == NULL) ) { *errCode = DPU_TRANSMISSIONHWA_EINVAL; goto exit; } /* Allocate Memory for transmission */ transmissionObj = MemoryP_ctrlAlloc(sizeof(transmissionHWAObj), 0); if(transmissionObj == NULL) { *errCode = DPU_TRANSMISSIONHWA_ENOMEM; goto exit; } /* Initialize memory */ memset((void *)transmissionObj, 0, sizeof(transmissionHWAObj)); memcpy((void *)&transmissionObj->initParms, initParams, sizeof(DPU_Transmission_InitParams)); /* Set HWA bank memory address */ *errCode = HWA_getHWAMemInfo(initParams->hwaHandle, &hwaMemInfo); if (*errCode < 0) { goto exit; } uint8_t maxBanks = sizeof(transmissionObj->hwaMemBankAddr) / sizeof(transmissionObj->hwaMemBankAddr[0]); if (hwaMemInfo.numBanks > maxBanks) { *errCode = DPU_TRANSMISSIONHWA_EINVAL; goto exit; } for (index = 0; index < hwaMemInfo.numBanks; index++) { transmissionObj->hwaMemBankAddr[index] = hwaMemInfo.baseAddress + index * hwaMemInfo.bankSize; } /* Create semaphore for EDMA done */ SemaphoreP_Params_init(&semParams); semParams.mode = SemaphoreP_Mode_BINARY; transmissionObj->edmaDoneSemaHandle = SemaphoreP_create(0, &semParams); if(transmissionObj->edmaDoneSemaHandle == NULL) { *errCode = DPU_TRANSMISSIONHWA_ESEMA; goto exit; } /* Create semaphore for HWA done */ SemaphoreP_Params_init(&semParams); semParams.mode = SemaphoreP_Mode_BINARY; transmissionObj->hwaDoneSemaHandle = SemaphoreP_create(0, &semParams); System_printf("Debug: DPU Init Sema Handle: %p\n", transmissionObj->hwaDoneSemaHandle); if(transmissionObj->hwaDoneSemaHandle == NULL) { *errCode = DPU_TRANSMISSIONHWA_ESEMA; goto exit; } exit: if(*errCode < 0) { if(transmissionObj != NULL) { MemoryP_ctrlFree(transmissionObj, sizeof(transmissionHWAObj)); } transmissionObj = (DPU_Transmission_Handle)NULL; } else { /* Fall through */ } return ((DPU_Transmission_Handle)transmissionObj); } /** * @b Description * @n * The function is rangeProc DPU config function. It saves buffer pointer and configurations * including system resources and configures HWA and EDMA for runtime range processing. * * @pre DPU_TransmissionHWA_init() has been called * * @param[in] handle rangeProc DPU handle * @param[in] pConfigIn Pointer to rangeProc configuration data structure * * \ingroup DPU_TRANSMISSION_EXTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ int32_t DPU_TransmissionHWA_config ( DPU_Transmission_Handle handle, DPU_TransmissionHWA_Config *pConfigIn ) { transmissionHWAObj *transmissionObj; DPU_Transmission_StaticConfig *pStaticCfg; HWA_Handle hwaHandle; int32_t retVal = 0; transmissionObj = (transmissionHWAObj *)handle; if(transmissionObj == NULL) { retVal = DPU_TRANSMISSIONHWA_EINVAL; System_printf("transmissionObj == NULL (retval = %d)\n", retVal); goto exit; } /* Get configuration pointers */ pStaticCfg = &pConfigIn->staticCfg; hwaHandle = transmissionObj->initParms.hwaHandle; #if DEBUG_CHECK_PARAMS /* Validate params */ if(!pConfigIn || !(pConfigIn->hwRes.edmaHandle) || (pConfigIn->hwRes.hwaCfg.numParamSet != DPU_TRANSMISSIONHWA_NUM_HWA_PARAM_SETS) ) { retVal = DPU_TRANSMISSIONHWA_EINVAL; System_printf("Validate params (retval = %d)\n", retVal); goto exit; } /* Parameter check: validate Adc data interface configuration Support: - 1 chirp per chirpEvent - Complex 16bit ADC data in IMRE format */ if( (pStaticCfg->ADCBufData.dataProperty.dataFmt != DPIF_DATAFORMAT_COMPLEX16_IMRE) || (pStaticCfg->ADCBufData.dataProperty.numChirpsPerChirpEvent != 1U) ) { System_printf("Error: DPU_TRANSMISSIONHWA_EADCBUF_INTF\n"); retVal = DPU_TRANSMISSIONHWA_EADCBUF_INTF; goto exit; } { uint16_t expectedWinSize; if( pConfigIn->hwRes.hwaCfg.hwaWinSym == HWA_FFT_WINDOW_SYMMETRIC) { /* Only half of the windowing factor is needed for symmetric window */ expectedWinSize = ((pStaticCfg->ADCBufData.dataProperty.numAdcSamples + 1U) / 2U ) * sizeof(uint32_t); } else { expectedWinSize = pStaticCfg->ADCBufData.dataProperty.numAdcSamples * sizeof(uint32_t); } if(pStaticCfg->windowSize != expectedWinSize) { retVal = DPU_RANGEPROCHWA_EWINDOW; System_printf("Error: DPU_RANGEPROCHWA_EWINDOW\n"); System_printf("Debug: expectedWinSize %d\n", expectedWinSize); System_printf("Debug: numAdcSamples %d\n", pStaticCfg->ADCBufData.dataProperty.numAdcSamples); System_printf("Debug: windowSize %d\n", pStaticCfg->windowSize); System_printf("Debug: hwaWinSym %d\n", pConfigIn->hwRes.hwaCfg.hwaWinSym); goto exit; } } /* Refer to radar cube definition for FORMAT_x , the following are the only supported formats Following assumption is made upon radar cube FORMAT_x definition 1. data type is complex in cmplx16ImRe_t format only 2. It is always 1D range output. */ if( (pConfigIn->hwRes.radarCube.datafmt != DPIF_RADARCUBE_FORMAT_1) && (pConfigIn->hwRes.radarCube.datafmt != DPIF_RADARCUBE_FORMAT_2) ) { retVal = DPU_RANGEPROCHWA_ERADARCUBE_INTF; System_printf("Error: DPU_RANGEPROCHWA_ERADARCUBE_INTF\n"); System_printf("First error case\n"); System_printf("Value 1: %d \n", pConfigIn->hwRes.radarCube.datafmt); goto exit; } /* Not supported input & output format combination */ if ((pStaticCfg->ADCBufData.dataProperty.interleave == DPIF_RXCHAN_INTERLEAVE_MODE) && (pConfigIn->hwRes.radarCube.datafmt == DPIF_RADARCUBE_FORMAT_1) ) { retVal = DPU_RANGEPROCHWA_ENOTIMPL; System_printf("Error: DPU_RANGEPROCHWA_ENOTIMPL\n"); goto exit; } if (pStaticCfg->ADCBufData.dataProperty.numRxAntennas == 3U) { retVal = DPU_RANGEPROCHWA_ENOTIMPL; System_printf("Error: DPU_RANGEPROCHWA_ENOTIMPL\n"); goto exit; } /* Parameter check: radarcube buffer Size */ if (pConfigIn->hwRes.radarCube.dataSize != (pStaticCfg->numRangeBins* sizeof(cmplx16ImRe_t) * pStaticCfg->numChirpsPerFrame * pStaticCfg->ADCBufData.dataProperty.numRxAntennas) ) { retVal = DPU_RANGEPROCHWA_ERADARCUBE_INTF; System_printf("Error: DPU_RANGEPROCHWA_ERADARCUBE_INTF\n"); System_printf("Second error case\n"); System_printf("Value 1: %d \n", pConfigIn->hwRes.radarCube.dataSize); System_printf("Value 2: %d \n", (pStaticCfg->numRangeBins* sizeof(cmplx16ImRe_t) * pStaticCfg->numChirpsPerFrame * pStaticCfg->ADCBufData.dataProperty.numRxAntennas)); goto exit; } /* Parameter check: Num butterfly stages to scale */ if (pStaticCfg->rangeFFTtuning.numLastButterflyStagesToScale > mathUtils_ceilLog2(pStaticCfg->numRangeBins)) { //retVal = DPU_RANGEPROCHWA_EBUTTERFLYSCALE; System_printf("Error: DPU_RANGEPROCHWA_EBUTTERFLYSCALE\n"); //goto exit; } #endif retVal = transmissionHWA_ParseConfig(transmissionObj, pConfigIn); if (retVal < 0) { System_printf("Error: transmissionHWA_ParseConfig (retval = %d)\n", retVal); goto exit; } /* Disable the HWA */ retVal = HWA_enable(hwaHandle, 0); if (retVal != 0) { System_printf("Error: HWA_enable (retval = %d)\n", retVal); goto exit; } /* Reset the internal state of the HWA */ retVal = HWA_reset(hwaHandle); if (retVal != 0) { System_printf("Error: HWA_reset (retval = %d)\n", retVal); goto exit; } /* Windowing configuraiton in HWA */ retVal = HWA_configRam(hwaHandle, HWA_RAM_TYPE_WINDOW_RAM, (uint8_t *)pStaticCfg->window, pStaticCfg->windowSize, /* size in bytes */ pConfigIn->hwRes.hwaCfg.hwaWinRamOffset * sizeof(uint32_t)); if (retVal != 0) { System_printf("Error: HWA_configRam (retval = %d)\n", retVal); System_printf("Error: HWA_configRam (retval = %d)\n", retVal); goto exit; } /* Clear stats */ transmissionObj->numProcess = 0U; /* Initial configuration of rangeProc */ retVal = transmissionHWA_HardwareConfig(transmissionObj, &pConfigIn->hwRes); exit: if (retVal < 0) { System_printf("ERROR IN CONFIG of DPU"); } return retVal; } void dumpADCData(UART_Handle uartHandle, cmplx16ImRe_t *adcData, size_t numSamples) { size_t totalBytesToSend = numSamples * sizeof(cmplx16ImRe_t); size_t chunkSize = 128; // Maximum allowed size for UART_writePolling size_t offset = 0; int32_t bytesWritten; uint8_t localBuffer[128]; while (totalBytesToSend > 0) { size_t bytesThisRound = (totalBytesToSend < chunkSize) ? totalBytesToSend : chunkSize; System_printf("totalBytesToSend: %d.\n", totalBytesToSend); memcpy(localBuffer, ((uint8_t *)adcData) + offset, bytesThisRound); bytesWritten = UART_writePolling(uartHandle, localBuffer, bytesThisRound); if (bytesWritten < 0) { System_printf("Error sending data over UART. Error code: %d\n", bytesWritten); return; } if (bytesWritten != bytesThisRound) { System_printf("Warning: Only %d of %d bytes sent in this chunk.\n", bytesWritten, bytesThisRound); return; } offset += bytesWritten; totalBytesToSend -= bytesWritten; } System_printf("Successfully sent all data over UART in chunks.\n"); } #define NUM_ADC_SAMPLES 64 #define NUM_CHIRPS 8 #define SPEED_OF_LIGHT 3.0e8 #define NUM_RX_ANTENNAS 4 /** * @b Description * @n * Computes the average magnitude for each chirp by averaging over all range bins and antennas. * * @param[in] fftOutput Pointer to the FFT output data * @param[in] numChirps Number of chirps * @param[in] numRangeBins Number of range bins * @param[in] numRxAntennas Number of receive antennas * @param[out] avgMagnitudes Array to store average magnitudes per chirp * * @retval * None */ void computeAverageMagnitudesPerChirp( cmplx16ImRe_t *fftOutput, uint32_t numChirps, uint32_t numRangeBins, uint32_t numRxAntennas, float *avgMagnitudes) { uint32_t chirpIdx = 0; uint32_t totalSamples = numChirps * numRangeBins * numRxAntennas; System_printf("Verifying FFT Output Data Structure\n"); uint32_t chirp = 0; uint32_t rangeBin = 0; uint32_t rxAnt = 0; for (; chirp < numChirps; chirp++) { for (; rangeBin < numRangeBins; rangeBin++) { for (; rxAnt < numRxAntennas; rxAnt++) { uint32_t index = chirp * numRangeBins * numRxAntennas + rangeBin * numRxAntennas + rxAnt; cmplx16ImRe_t sample = fftOutput[index]; System_printf( "Chirp: %u, Range Bin: %u, Rx Antenna: %u, Index: %u, Real: %d, Imag: %d\n", chirp, rangeBin, rxAnt, index, sample.real, sample.imag); } } } System_printf("Completed FFT Output Data Verification.\n"); for (; chirpIdx < numChirps; chirpIdx++) { float totalMagnitude = 0.0f; uint32_t rxAnt = 0; for (; rxAnt < numRxAntennas; rxAnt++) { uint32_t rangeBin = 0; for (; rangeBin < numRangeBins; rangeBin++) { uint32_t index = chirpIdx * numRangeBins * numRxAntennas + rangeBin * numRxAntennas + rxAnt; cmplx16ImRe_t sample = fftOutput[index]; float magnitude = sqrtf(sample.real * sample.real + sample.imag * sample.imag); totalMagnitude += magnitude; } } avgMagnitudes[chirpIdx] = totalMagnitude / (numRxAntennas * numRangeBins); // aantal chirps = rx antennas * num range bins System_printf("Chirp %d: Average Magnitude = %f\n", chirpIdx, avgMagnitudes[chirpIdx]); } } /** * @b Description * @n * Computes an automatic threshold for classification by analyzing the average magnitudes. * The threshold is calculated by finding the largest gap between sorted magnitudes. * * @param[in] avgMagnitudes Array of average magnitudes per chirp * @param[in] numChirps Number of chirps * * @retval * Threshold value for classification */ float computeThreshold( float *avgMagnitudes, uint32_t numChirps) { System_printf("Computing Threshold \n"); float sortedMagnitudes[NUM_CHIRPS]; uint32_t i = 0; for (; i < numChirps; i++) { sortedMagnitudes[i] = avgMagnitudes[i]; } /* Sort the magnitudes */ i = 0; for (; i < numChirps - 1; i++) { uint32_t j = i + 1; for (; j < numChirps; j++) { if (sortedMagnitudes[i] > sortedMagnitudes[j]) { float temp = sortedMagnitudes[i]; sortedMagnitudes[i] = sortedMagnitudes[j]; sortedMagnitudes[j] = temp; } } } /* Find the largest gap between consecutive magnitudes */ float maxGap = 0.0f; uint32_t thresholdIndex = 0; i = 0; for (; i < numChirps - 1; i++) { float gap = sortedMagnitudes[i + 1] - sortedMagnitudes[i]; if (gap > maxGap) { maxGap = gap; thresholdIndex = i; } } /* Compute threshold average */ float threshold = (sortedMagnitudes[thresholdIndex] + sortedMagnitudes[thresholdIndex + 1]) / 2.0f; System_printf("Threshold = %f\n", threshold); return threshold; } /** * @b Description * @n * Classifies chirps as zero or one based on the threshold. * * @param[in] avgMagnitudes Array of average magnitudes per chirp * @param[in] numChirps Number of chirps * @param[in] threshold Threshold for classification * @param[out] chirpClassifications Array to store classification results (0 or 1) * * @retval * None */ void classifyChirps( float *avgMagnitudes, uint32_t numChirps, float threshold, uint8_t *chirpClassifications) { uint32_t i = 0; System_printf("Classifying Chirps \n"); for (; i < numChirps; i++) { if (avgMagnitudes[i] >= threshold) { chirpClassifications[i] = 1; } else { chirpClassifications[i] = 0; } System_printf("Threshold = %f\n", chirpClassifications[i]); } } /** * @b Description * @n * The function is transmission DPU process function. It allocates memory to store * its internal data object and returns a handle if it executes successfully. * * @pre DPU_TransmissionHWA_init() has been called * * @param[in] handle transmission DPU handle * @param[in] outParams DPU output parameters * * \ingroup DPU_TRANSMISSION_EXTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ int32_t DPU_TransmissionHWA_process ( DPU_Transmission_Handle handle, DPU_Transmission_OutParams *outParams, const DPU_Transmission_FreqConfig *freqConfig ) { transmissionHWAObj *transmissionObj; int32_t retVal = 0; bool hwaSemStatus, edmaSemStatus; uint32_t timeoutTicks = 100000; // Timeout period in ticks transmissionObj = (transmissionHWAObj *)handle; if ((transmissionObj == NULL) || (outParams == NULL)) { retVal = DPU_TRANSMISSIONHWA_EINVAL; goto exit; } /* Set inProgress state */ transmissionObj->inProgress = true; outParams->endOfChirp = false; /**********************************************/ /* WAIT FOR HWA NUMLOOPS INTERRUPT */ /**********************************************/ /* wait for the all paramSets done interrupt */ System_printf("Waiting for HWA Semaphore \n"); /* Wait with timeout for HWA semaphore */ hwaSemStatus = SemaphoreP_pend(transmissionObj->hwaDoneSemaHandle, timeoutTicks); if (!hwaSemStatus) { System_printf("WARNING: HWA Semaphore timeout - forcing continuation after timeout\n"); /* Force semaphore post to prevent deadlock */ SemaphoreP_post(transmissionObj->hwaDoneSemaHandle); } else { System_printf("HWA Semaphore successfully posted\n"); } /**********************************************/ /* WAIT FOR EDMA INTERRUPT */ /**********************************************/ System_printf("Waiting for EDMA Semaphore \n"); /* Wait with timeout for EDMA semaphore */ edmaSemStatus = SemaphoreP_pend(transmissionObj->edmaDoneSemaHandle, timeoutTicks); if (!edmaSemStatus) { System_printf("WARNING: EDMA Semaphore timeout - forcing continuation after timeout\n"); /* Force semaphore post to prevent deadlock */ SemaphoreP_post(transmissionObj->edmaDoneSemaHandle); } else { System_printf("EDMA Semaphore successfully posted\n"); } /* Range FFT is done, disable Done interrupt */ HWA_disableDoneInterrupt(transmissionObj->initParms.hwaHandle); /* Disable the HWA */ retVal = HWA_enable(transmissionObj->initParms.hwaHandle, 0); if (retVal != 0) { goto exit; } System_printf("Start Classifying Bits \n"); cmplx16ImRe_t *fftOutput = transmissionObj->radarCubebuf; uint32_t numChirps = transmissionObj->params.numChirpsPerFrame; uint32_t numRangeBins = transmissionObj->params.numRangeBins; uint32_t numRxAntennas = transmissionObj->params.numRxAntennas; /* Debug: Dump the first 32 samples of FFT output */ System_printf("FFT Output Dump (radarCubebuf):\n"); for (uint32_t i = 0; i < 32 && i < numChirps * numRangeBins * numRxAntennas; i++) { System_printf("Sample %d: Real = %d, Imag = %d\n", i, fftOutput[i].real, fftOutput[i].imag); } float avgMagnitudes[NUM_CHIRPS]; computeAverageMagnitudesPerChirp(fftOutput, numChirps, numRangeBins, numRxAntennas, avgMagnitudes); float threshold = computeThreshold(avgMagnitudes, numChirps); uint8_t chirpClassifications[NUM_CHIRPS] = {0}; classifyChirps(avgMagnitudes, numChirps, threshold, chirpClassifications); uint8_t receivedByte = 0; uint32_t i = 0; for (; i < numChirps; i++) { receivedByte <<= 1; receivedByte |= chirpClassifications[i]; System_printf("Classified bit: %d", chirpClassifications[i]); } System_printf("Received Byte: 0x%02X\n", receivedByte); transmissionObj->numProcess++; /* Following stats is not available for rangeProcHWA */ outParams->stats.processingTime = 0; outParams->stats.waitTime= 0; outParams->endOfChirp = true; /* Clear inProgress state */ transmissionObj->inProgress = false; exit: return retVal; } /** * @b Description * @n * The function is transmission DPU control function. * * @pre DPU_TransmissionHWA_init() has been called * * @param[in] handle transmission DPU handle * @param[in] cmd transmission DPU control command * @param[in] arg transmission DPU control argument pointer * @param[in] argSize transmission DPU control argument size * * \ingroup DPU_TRANSMISISON_EXTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ int32_t DPU_TransmissionHWA_control ( DPU_Transmission_Handle handle, DPU_TransmissionHWA_Cmd cmd, void* arg, uint32_t argSize ) { int32_t retVal = 0; transmissionHWAObj *transmissionObj; /* Get transmisison data object */ transmissionObj = (transmissionHWAObj *)handle; System_printf("Debug: DPU_Transmission_Handle: %p\n", (void *)handle); System_printf("Debug: pointer transmissionObj: %p\n", (void *)transmissionObj); /* Sanity check */ if (transmissionObj == NULL) { System_printf("Error: DPU_TRANSMISSIONHWA_EINVAL\n"); retVal = DPU_TRANSMISSIONHWA_EINVAL; System_printf("Error: [retVal: %d]\n", retVal); goto exit; } /* Check if control() is called during processing time */ if(transmissionObj->inProgress == true) { retVal = DPU_TRANSMISSIONHWA_EINPROGRESS; System_printf("Error: DPU_TRANSMISSIONHWA_EINPROGRESS\n"); goto exit; } /***************************************************************** */ /* Control command handling */ switch(cmd) { case DPU_TransmissionHWA_Cmd_triggerProc: /* Trigger transmisison in HWA */ System_printf("Debug: Calling transmissionHWA_TriggerHWA.\n"); retVal = transmissionHWA_TriggerHWA( transmissionObj); if(retVal != 0) { System_printf("Error: TriggerHWA failed with errcode: %d\n", retVal); goto exit; } System_printf("Debug: Succesfully called: transmissionHWA_TriggerHWA.\n"); break; default: retVal = DPU_TRANSMISSIONHWA_ECMD; break; } exit: return (retVal); } /** * @b Description * @n * The function is transmission DPU deinit function. It frees the resources used for the DPU. * * @pre DPU_TransmissionHWA_init() has been called * * @param[in] handle transmission DPU handle * * \ingroup DPU_TRANSMISSION_EXTERNAL_FUNCTION * * @retval * Success - 0 * @retval * Error - <0 */ int32_t DPU_TransmissionHWA_deinit ( DPU_Transmission_Handle handle ) { transmissionHWAObj *transmissionObj; int32_t retVal = 0; /* Sanity Check */ transmissionObj = (transmissionHWAObj *)handle; if(transmissionObj == NULL) { retVal = DPU_TRANSMISSIONHWA_EINVAL; goto exit; } /* Delete Semaphores */ SemaphoreP_delete(transmissionObj->edmaDoneSemaHandle); SemaphoreP_delete(transmissionObj->hwaDoneSemaHandle); /* Free memory */ MemoryP_ctrlFree(handle, sizeof(transmissionHWAObj)); exit: return (retVal); } /** * @b Description * @n * Dumps ADC buffer contents for debugging purposes * * @param[in] buffer Pointer to ADC buffer * @param[in] size Number of samples to dump * * \ingroup DPU_TRANSMISSION_INTERNAL_FUNCTION * * @retval None */ static void dumpADCBuffer(cmplx16ImRe_t *buffer, uint32_t size) { System_printf("ADC Buffer Dump:\n"); uint32_t i = 0; for (; i < size && i < 32; i++) { // Limit to first 32 samples to avoid flooding System_printf("Sample %d: Real = %d, Imag = %d\n", i, buffer[i].real, buffer[i].imag); } // Print summary statistics int32_t maxReal = INT32_MIN; int32_t minReal = INT32_MAX; int32_t maxImag = INT32_MIN; int32_t minImag = INT32_MAX; float avgReal = 0.0f; float avgImag = 0.0f; i = 0; for (; i < size; i++) { if (buffer[i].real > maxReal) maxReal = buffer[i].real; if (buffer[i].real < minReal) minReal = buffer[i].real; if (buffer[i].imag > maxImag) maxImag = buffer[i].imag; if (buffer[i].imag < minImag) minImag = buffer[i].imag; avgReal += buffer[i].real; avgImag += buffer[i].imag; } avgReal /= size; avgImag /= size; System_printf("ADC Buffer Statistics (size = %d):\n", size); System_printf("Real: Min = %d, Max = %d, Avg = %.2f\n", minReal, maxReal, avgReal); System_printf("Imag: Min = %d, Max = %d, Avg = %.2f\n", minImag, maxImag, avgImag); }