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.

IWR6843AOP: HWA Paramsets for triggering FFT not working

Part Number: IWR6843AOP

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, &paramISRConfig);
    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, &paramISRConfig);
    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, &paramISRConfig);
    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,
                                           &paramISRConfig);
    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);
}