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.

AM5728: DSP EDMA分配

Part Number: AM5728

SYS_EDMA_TPCC
DSP1_EDMA_TPCC
DSP2_EDMA_TPCC
DSP_EDMA_TPCC

其中,SYS_EDMA_TPCC是否可以被DSP使用?

DSP_EDMA_TPCC 和DSP1_EDMA_TPCC/DSP2_EDMA_TPCC 有什么区别?

  • SYS_EDMA_TPCC是否可以被DSP使用?

    可以,SYS_EDMA可以被所有的核使用。

    DSP_EDMA_TPCC 和DSP1_EDMA_TPCC/DSP2_EDMA_TPCC 有什么区别?

    各个核私有的。

  • 意思是2个DSP核都有DSP_EDMA_TPCC?DSP1和DSP2同时调用DSP_EDMA_TPCC不会造成冲突吗?

  • /* EDMA3 TPCC region. */
    #define EDMA3_CC_REGION                         (1U)
    /* EDMA3 Event queue number. */
    #define EVT_QUEUE_NUM                           (0U)
    
    uint32_t          edma_address = CSL_DSP_DSP_EDMA_CC_REGS;
    void uart_task(UArg a0, UArg a1)
    {
        /*Pad configuration and PRCM enable*/
        padConfig_prcmEnable();
    
        /*Configure the EDMA clock */
        PlatformEDMAWkupDepEnable();
    
        /* Do EDMA init Done once in the beginning of application */
        EDMAsetRegion(EDMA3_CC_REGION);
        EDMA3Init(edma_address, EVT_QUEUE_NUM); // SOC_EDMA_TPCC_BASE_VIRT  CSL_DSP_DSP_EDMA_CC_REGS
    	
    	...
    }
    
    //Table 16-6. Connection of The Device DREQs to The DMA_CROSSBAR Inputs
    #define DMA_XBAR_INST_TX                    (49U)
    #define DMA_XBAR_INST_RX                    (50U)
    
    //Table 5-7. DSP2_EDMA Default Request Mapping
    #define DMA_XBAR_INST_TX_SRC                CSL_XBAR_INST_DMA_DSP2_DREQ_16
    #define DMA_XBAR_INST_RX_SRC                CSL_XBAR_INST_DMA_DSP2_DREQ_17
    
    /*
    ** This function configures the DMA crossbar for UART TX and RX events.
    */
    static void EdmaEvtConfigure(void)
    {
        CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_DSP2_DMA, DMA_XBAR_INST_TX, 
                                DMA_XBAR_INST_TX_SRC);
        CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_DSP2_DMA, DMA_XBAR_INST_RX,
                                DMA_XBAR_INST_RX_SRC);
    }
    
    

    typedef enum
    {
    CSL_XBAR_DMA_CPU_ID_SYSTEM_DMA,
    CSL_XBAR_DMA_CPU_ID_EDMA,
    CSL_XBAR_DMA_CPU_ID_DSP1_DMA,
    CSL_XBAR_DMA_CPU_ID_DSP2_DMA
    } CSL_XbarDmaCpuId;

    问题1:DSP2的EDMA_TPCC访问 CSL_DSP_DSP_EDMA_CC_REGS ,若要触发UART1_TX 事件,使用CSL_xbarDmaConfigure()函数进行事件映射,

    void CSL_xbarDmaConfigure(CSL_XbarDmaCpuId dmaRegType, Uint32 dmaCrossbarInputNo, Uint32 dmaDreqToMapTo);

    其中第一个参数是配置 CSL_XBAR_DMA_CPU_ID_DSP2_DMA吗?

    问题2:CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_DSP2_DMA, DMA_XBAR_INST_TX,
    DMA_XBAR_INST_TX_SRC);

                DMA事件映射后,DMA通道是否必须为 CSL_xbarDmaConfigure(...)的第三个参数 dmaDreqToMapTo ?

  • 其中第一个参数是配置 CSL_XBAR_DMA_CPU_ID_DSP2_DMA吗?

    typedef enum
    {
    CSL_XBAR_DMA_CPU_ID_SYSTEM_DMA,
    CSL_XBAR_DMA_CPU_ID_EDMA,
    CSL_XBAR_DMA_CPU_ID_DSP1_DMA,
    CSL_XBAR_DMA_CPU_ID_DSP2_DMA
    } CSL_XbarDmaCpuId;

      DMA事件映射后,DMA通道是否必须为 CSL_xbarDmaConfigure(...)的第三个参数 dmaDreqToMapTo ?

    映射事件需一致。

  • /**
     * @file   bsp_uart_edma.c
     *
     * @brief  This file tests the UART driver APIs in EDMA mode.
     *
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Log.h>
    #include <xdc/runtime/Diags.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/hal/Hwi.h>
    
    /* TI-RTOS Header files */
    #include <ti/drv/gpio/GPIO.h>
    
    /* CSL Header files */
    #include <ti/csl/csl_chip.h>
    #include <ti/csl/arch/c66x/interrupt.h>
    #include <ti/csl/example/utils/uart_console/inc/uartConfig.h>
    
    #include <ti/csl/soc.h>
    #include <ti/csl/hw_types.h>
    #include <ti/csl/csl_uart.h>
    #include <ti/csl/csl_edma.h>
    #include <ti/csl/arch/csl_arch.h>
    
    /* OSAL Header files */
    #include <ti/osal/osal.h>
    
    /* UART Header files */
    #include <ti/drv/uart/UART.h>
    #include <ti/drv/uart/UART_stdio.h>
    #include <ti/drv/uart/src/UART_osal.h>
    #include <ti/drv/uart/soc/UART_soc.h>
    
    #include <ti/board/src/evmAM572x/include/evmam572x_pinmux.h>
    
    
    /****************************************************************************/
    /*                      INTERNAL MACROS                                     */
    /****************************************************************************/
    /* EDMA3 Event queue number. */
    #define EVT_QUEUE_NUM                           (0U)
    
    /* EDMA3 TPCC region. */
    #define EDMA3_CC_REGION                         (2U)
    
    /* PaRAM Set number for Dummy Transfer. */
    #define DUMMY_CH_NUM                        (5U)
    
    /* EDMA3 interrupt number. */
    /* EDMA3 error interrupt number. */
    //说明:Table 17-4. DSP2_INTC Default Interrupt Mapping 查看默认映射关系
    /*
    #if (EDMA3_CC_REGION==3)
    #define EDMA3_CC_XFER_COMPLETION_INT 20  //TPCC_INT3 - EDMA CC region3 interrupt
    #define EDMA3_CC_XFER_ERROR_INT 27
    #elif (EDMA3_CC_REGION==2)
    #define EDMA3_CC_XFER_COMPLETION_INT 19  //TPCC_INT2 - EDMA CC region2 interrupt
    #define EDMA3_CC_XFER_ERROR_INT 27
    #elif (EDMA3_CC_REGION == 1)
    #define EDMA3_CC_XFER_COMPLETION_INT 18  //TPCC_INT1 - EDMA CC region1 interrupt
    #define EDMA3_CC_XFER_ERROR_INT 27
    #elif (EDMA3_CC_REGION == 0)
    #define EDMA3_CC_XFER_COMPLETION_INT 17  //TPCC_INT0 - EDMA CC region0 interrupt
    #define EDMA3_CC_XFER_ERROR_INT 27
    #endif
    */
    
    /* EDMA3 interrupt number. */
    #define EDMA3_CC_XFER_COMPLETION_INT            (75U)
    #define XBAR_INST_CC_XFER_COMPLETION            (CSL_XBAR_INST_DSP2_IRQ_75)
    #define XBAR_INTR_SOURCE_CC_XFER_COMPLETION     (CSL_XBAR_EDMA_TPCC_IRQ_REGION1)
    /* EDMA3 error interrupt number. */
    #define EDMA3_CC_XFER_ERROR_INT                 (76U)
    #define XBAR_INST_CC_XFER_ERROR                 (CSL_XBAR_INST_DSP2_IRQ_76)
    #define XBAR_INTR_SOURCE_CC_XFER_ERROR          (CSL_XBAR_EDMA_TPCC_IRQ_REGION1)
    
    /* DSP2 EDMA3 transfer event number */
    
    /******************* Transmit related definitions  **************************/
    /*
    ** Transmit DMA Threshold Value. This is set in TX_DMA_THRESHOLD register.
    */
    #define TX_DMA_THRESHOLD                    (5U)
    
    /*
    ** Transmit Trigger Space value. Use this if TX Trigger Level granularity
    ** is selected to be 1.
    */
    #define TX_TRIGGER_SPACE_GRAN_1             (8U)
    
    /* Number of bytes transmitted by EDMA per TX event sent by UART. */
    #define TX_BYTES_PER_EVENT                  (8U)
    
    /******************* Receive related definitions  ***************************/
    /* Receiver Buffer Size. */
    #define RX_BUFFER_SIZE                      (50U)
    
    /* Receive DMA Threshold Value. */
    #define RX_DMA_THRESHOLD                    (8U)
    
    /* Number of bytes to be received from the user. */
    #define NUM_RX_BYTES              (8)
    
    /******************* DMA XBAR related definitions  ***************************/
    /* DMA XBAR Instance for UART1 Tx/RX. Refer TRM for DMA XBAR instance numbers.*/
    /* Wrapper Definitions. */
    #define EDMA3_UART_TX_CHA_NUM               (16U)
    #define EDMA3_UART_RX_CHA_NUM               (49U)
    
    //Table 16-6. Connection of The Device DREQs to The DMA_CROSSBAR Inputs
    #define DMA_XBAR_INST_TX                    (49U)
    #define DMA_XBAR_INST_RX                    (50U)
    
    //Table 16-89. EDMA Default Request Mapping
    //#define DMA_XBAR_INST_TX_SRC                CSL_XBAR_INST_DMA_EDMA_DREQ_48
    //#define DMA_XBAR_INST_RX_SRC                CSL_XBAR_INST_DMA_EDMA_DREQ_49
    
    //Table 5-7. DSP2_EDMA Default Request Mapping
    #define DMA_XBAR_INST_TX_SRC                CSL_XBAR_INST_DMA_DSP2_DREQ_16
    #define DMA_XBAR_INST_RX_SRC                CSL_XBAR_INST_DMA_DSP2_DREQ_17
    
    // EDMA3 参数
    #define MAX_ACNT            1
    #define MAX_CCNT            1
    
    /* OPT Field specific defines */
    #define OPT_SYNCDIM_SHIFT                   (0x00000002u)
    #define OPT_TCC_MASK                        (0x0003F000u)
    #define OPT_TCC_SHIFT                       (0x0000000Cu)
    #define OPT_ITCINTEN_SHIFT                  (0x00000015u)
    #define OPT_TCINTEN_SHIFT                   (0x00000014u)
    #define OPT_TCCMOD_SHIFT                    (0x0000000Bu)
    
    #define UART_EDMA3CC_OPT_FIFO_WIDTH         ((uint32_t)0xFFFFF8FFU)
    /**< Set FIFO Width for edma transfer                                         */
    
    #define UART_EDMA3CC_OPT_DAM_CONST_MODE         ((uint32_t)0x00000002U)
    /**< Set DAM in Constant Addressing Mode                                      */
    
    #define UART_EDMA3CC_OPT_SAM_INCR_MODE          ((uint32_t)0xFFFFFFFEU)
    /**< Set SAM in Increment Mode                                                */
    
    
    /****************************************************************************/
    /*                      GLOBAL VARIABLES                                    */
    /****************************************************************************/
    static void(*cb_Fxn[EDMA3_NUM_TCC]) (uint32_t tcc);
    unsigned char     intent[] =
        "The application echoes the characters that you type on the console.\r\n";
    unsigned char     welcome[]  = "StarterWare UART DMA application.\r\n";
    unsigned char     enter[]    = "Please Enter 08 bytes from keyboard.\r\n";
    volatile uint32_t clBackFlag = 0;
    
    unsigned char     rxBuffer[RX_BUFFER_SIZE];
    /*
    ** Transmit Trigger Space value. This is applicable only when UART FIFO mode
    ** is used. Refer to the comments of the API UARTFIFOConfig() to find the
    ** possible values of TX Trigger Space.
    */
    uint32_t          txTrigSpace = TX_TRIGGER_SPACE_GRAN_1;
    
    /*
    ** Number of bytes transmitted by EDMA per TX event sent by UART.
    ** In UART FIFO mode, this should be equal to the TX Trigger Space value.
    */
    uint32_t          txBytesPerEvent = TX_BYTES_PER_EVENT;
    
    /*
    ** Receive DMA Thresold Level. This applies to both UART FIFO and Non-FIFO
    ** modes of operation. For FIFO mode, refer to the comments of the API
    ** UARTFIFOConfig() to find the possible values of RX Trigger Level.
    ** For Non-FIFO mode, this value is 1.
    */
    uint32_t          rxTrigLevel = RX_DMA_THRESHOLD;
    
    /* Transmit DMA Threshold Level. This is set in TX_DMA_THRESHOLD register. */
    uint32_t          txThreshLevel = TX_DMA_THRESHOLD;
    uint32_t          uartBaseAddr = SOC_UART1_BASE;
    uint32_t          edma_address = CSL_DSP_DSP_EDMA_CC_REGS; //CSL_DSP_DSP_EDMA_CC_REGS  CSL_DSP_EDMA_CC_REGS  CSL_DSP_DSP2_EDMA_CC_REGS SOC_EDMA_TPCC_BASE_VIRT
    
    //#pragma DATA_ALIGN (local_arr, 32) //256位地址对齐,地址的低5位为0
    static uint8_t local_arr[256] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x11, 0x22, 0x33, 0x44, 0x66, 0xFF, 0xEE, 0xAA};
    /****************************************************************************/
    /*                   LOCAL FUNCTION DEFINITIONS                             */
    /****************************************************************************/
    
    static void edma_hwi_init(void);
    static void Edma3CompletionIsr(void);
    
    static void padConfig_prcmEnable()
    {
        uint32_t regVal = 0;
    
       /* uart1 pinmux initialization */
       CSL_FINS(regVal, CONTROL_CORE_PAD_IO_PAD_UART1_RXD_UART1_RXD_MUXMODE, 0x0U);        //0x0: uart1_rxd
       CSL_FINS(regVal, CONTROL_CORE_PAD_IO_PAD_UART1_RXD_UART1_RXD_SLEWCONTROL, 0x1U);    //0x1: Slow slew is selected
       CSL_FINS(regVal, CONTROL_CORE_PAD_IO_PAD_UART1_RXD_UART1_RXD_INPUTENABLE, 0x1U);    //0x1: Receive mode is enabled
       ((CSL_padRegsOvly) CSL_MPU_CORE_PAD_IO_REGISTERS_REGS)->PAD_UART1_RXD = regVal;     /* uart1_rxd.uart1_rxd */
    
       CSL_FINS(regVal, CONTROL_CORE_PAD_IO_PAD_UART1_TXD_UART1_TXD_MUXMODE, 0x0U);
       CSL_FINS(regVal, CONTROL_CORE_PAD_IO_PAD_UART1_TXD_UART1_TXD_SLEWCONTROL, 0x1U);
       CSL_FINS(regVal, CONTROL_CORE_PAD_IO_PAD_UART1_TXD_UART1_TXD_INPUTENABLE, 0x1U);
       ((CSL_padRegsOvly) CSL_MPU_CORE_PAD_IO_REGISTERS_REGS)->PAD_UART1_TXD = regVal;     /* uart1_txd.uart1_txd */
    }
    
    
    static void PlatformEDMAWkupDepEnable(void)
    {
        HW_WR_REG32(SOC_CORE_CM_CORE_BASE + PM_L3MAIN1_TPTC1_WKDEP, 0x1); //0x4a008700U + 0x78U = 0x4A00 8778U, CM_L3MAIN1_TPTC1_CLKCTRL
        while ((HW_RD_REG32(SOC_CORE_CM_CORE_BASE +
                            PM_L3MAIN1_TPTC1_WKDEP) & 0x00030000U) != 0x0)
        {
            ;
        }
    
        HW_WR_REG32(SOC_CORE_CM_CORE_BASE + PM_L3MAIN1_TPTC2_WKDEP, 0x1); //0x4A00 8780U,CM_L3MAIN1_TPTC2_CLKCTRL
        while ((HW_RD_REG32(SOC_CORE_CM_CORE_BASE +
                            PM_L3MAIN1_TPTC2_WKDEP) & 0x00030000U) != 0x0)
        {
            ;
        }
    
        HW_WR_REG32(SOC_CORE_CM_CORE_BASE + PM_L3MAIN1_TPCC_WKDEP, 0x1); //0x4A00 8770U,CM_L3MAIN1_TPCC_CLKCTRL
        while ((HW_RD_REG32(SOC_CORE_CM_CORE_BASE +
                            PM_L3MAIN1_TPCC_WKDEP) & 0x00030000U) != 0x0)
        {
            ;
        }
    }
    
    
    /*
    ** This function configures the AINTC to receive EDMA3 interrupts.
    */
    static void Edma3INTCConfigure(void)
    {
        //中断映射 -> 默认映射,无需重新映射
    //    CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP2,
    //                            XBAR_INST_CC_XFER_COMPLETION,
    //                            XBAR_INTR_SOURCE_CC_XFER_COMPLETION);
    //    CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP2,
    //                            XBAR_INST_CC_XFER_ERROR,
    //                            XBAR_INTR_SOURCE_CC_XFER_ERROR);
    
        edma_hwi_init();
    }
    
    
    /*
    ** A wrapper function performing FIFO configurations.
    */
    static void UartFIFOConfigure(void)
    {
        uint32_t fifoConfig = 0;
    
    #if 0
        /*
        ** Transmitter Trigger Level Granularity is 1.
        ** Receiver Trigger Level Granularity is 1.
        ** Transmit Trigger Space set 1.
        ** Receive Trigger level set 1.
        ** Clear the Trasnmit FIFO.
        ** Clear the Receive FIFO.
        ** DMA Mode enabling shall happen through SCR register.
        ** DMA Mode 1 is enabled.
        */
        fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_1,
                                      UART_TRIG_LVL_GRANULARITY_1,
                                      1,
                                      1,
                                      1,
                                      1,
                                      UART_DMA_EN_PATH_SCR,
                                      UART_DMA_MODE_3_ENABLE);
    #else
        /*
        ** Transmitter Trigger Level Granularity is 1.
        ** Receiver Trigger Level Granularity is 1.
        ** Transmit Trigger Space set using 'txTrigSpace'.
        ** Receive Trigger level set using 'rxTrigLevel'.
        ** Clear the Trasnmit FIFO.
        ** Clear the Receive FIFO.
        ** DMA Mode enabling shall happen through SCR register.
        ** DMA Mode 1 is enabled.
        */
        fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_1,
                                      UART_TRIG_LVL_GRANULARITY_1,
                                      txTrigSpace,                 //8
                                      rxTrigLevel,                 //8
                                      1,
                                      1,
                                      UART_DMA_EN_PATH_SCR,
                                      UART_DMA_MODE_3_ENABLE);
    #endif
        /* Configuring the FIFO settings. */
        fifoConfig = UARTFIFOConfig(uartBaseAddr, fifoConfig);
        Log_print1(Diags_ENTRY, "FCR: 0x%02x", fifoConfig);
    }
    
    
    /*
    ** A wrapper function performing Baud Rate settings.
    */
    static void UartBaudRateSet(void)
    {
        uint32_t divisorValue = 0;
    
        /* Computing the Divisor Value. */
        divisorValue = UARTDivisorValCompute(UART_MODULE_INPUT_CLK,
                                             BAUD_RATE_115200,
                                             UART16x_OPER_MODE,
                                             UART_MIR_OVERSAMPLING_RATE_42);
    
        /* Programming the Divisor Latches. */
        UARTDivisorLatchWrite(uartBaseAddr, divisorValue);
    }
    
    
    /*
    ** This function initializes the UART instance for use.
    */
    static void UartInitialize(void)
    {
        /* Performing a module reset. */
        //UARTModuleReset(uartBaseAddr);
    
        /* Performing FIFO configurations. */
        UartFIFOConfigure();
    
        /* Selecting the method of setting the Transmit DMA Threshold value. */
        UARTTxDMAThresholdControl(uartBaseAddr, UART_TX_DMA_THRESHOLD_REG); 
    
        /* Configuring the Transmit DMA Threshold value. */
        UARTTxDMAThresholdValConfig(uartBaseAddr, txThreshLevel); //txThreshLevel = 5
    
        /* Performing Baud Rate settings. */
        UartBaudRateSet();
    
        /* Switching to Configuration Mode B. */
        UARTRegConfigModeEnable(uartBaseAddr, UART_REG_CONFIG_MODE_B);
    
        /* Programming the Line Characteristics. */
        UARTLineCharacConfig(uartBaseAddr,
                             (UART_FRAME_WORD_LENGTH_8 | UART_FRAME_NUM_STB_1),
                             UART_PARITY_NONE);
    
        /* Disabling write access to Divisor Latches. */
        UARTDivisorLatchDisable(uartBaseAddr);
    
        /* Disabling Break Control. */
        UARTBreakCtl(uartBaseAddr, UART_BREAK_COND_DISABLE);
    
        /* Switching to UART16x operating mode. */
        UARTOperatingModeSelect(uartBaseAddr, UART16x_OPER_MODE);
    }
    
    /*
    ** This function configures the DMA crossbar for UART TX and RX events.
    */
    static void EdmaEvtConfigure(void)
    {
        CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_DSP2_DMA, DMA_XBAR_INST_TX,  //??
                                DMA_XBAR_INST_TX_SRC);
    //    CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_DSP2_DMA, DMA_XBAR_INST_RX,
    //                            DMA_XBAR_INST_RX_SRC);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              发送数据                                                    */
    /*                                                                          */
    /****************************************************************************/
    void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                             volatile char *buffer, unsigned int buffLength)
    {
        EDMA3CCPaRAMEntry paramSet;
    
        unsigned char *p = (unsigned char *)&paramSet;
        unsigned int icyc = 0;
    
        /* Clean-up the contents of structure variable. */
        for (icyc = 0; icyc < sizeof(paramSet); icyc++)
        {
            p[icyc] = 0;
        }
    
        // 配置参数 RAM
        paramSet.srcAddr = (unsigned int)buffer;
        // 接收缓存寄存器 / 发送保持寄存器 地址
        paramSet.destAddr = uartBaseAddr + 0;
        paramSet.aCnt = 1;
        paramSet.bCnt = (unsigned short)buffLength;
        paramSet.cCnt = 1;
    
        // 源索引自增系数 1 即一个字节
        paramSet.srcBIdx = (short)1u;
    
        // 目标索引自增系数
        paramSet.destBIdx = (short)0u;
    
        // AB同步传输模式
        paramSet.srcCIdx = (short)0u;
        paramSet.destCIdx = (short)0u;
        paramSet.linkAddr = (unsigned short)0xFFFFu;
        paramSet.bCntReload = (unsigned short)0u;
    
        /* OPT PaRAM entries. */
        paramSet.opt = (uint32_t) 0x0;
    
        /* Src is in INCR mode & Dest is in FIFO modes                            */
        paramSet.opt &= UART_EDMA3CC_OPT_SAM_INCR_MODE;  //[0]
        paramSet.opt |= UART_EDMA3CC_OPT_DAM_CONST_MODE; //[1]
    
        /* FIFO width is 8 bit                                                    */
        //paramSet.opt &= UART_EDMA3CC_OPT_FIFO_WIDTH;  //[10:8]
        paramSet.opt &= ((uint32_t)0xFFFFFCFFU);
    
        /* AB Synchronized Transfer. */
        paramSet.opt |= (1 << EDMA_TPCC_OPT_SYNCDIM_SHIFT);
    
        /* Setting the Transfer Complete Code(TCC). */
        paramSet.opt |=
           ((tccNum << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK); //[17:12]
    
        /* Enabling the Completion Interrupt. */
        paramSet.opt |= (1 << EDMA_TPCC_OPT_TCINTEN_SHIFT); //[20]
    
    
        Log_print2(Diags_ENTRY, "opt = 0x%02x, bCnt = 0x%02x", paramSet.opt, paramSet.bCnt); //0x110006
    
        // 写参数 RAM
        EDMA3SetPaRAM(edma_address, chNum, &paramSet);
    }
    
    /*
    ** This function is used as a callback from EDMA3 Completion Handler.
    */
    static void callback(uint32_t tccNum)
    {
        /* Disabling DMA Mode of operation in UART. */
        UARTDMADisable(uartBaseAddr);
    
        /* Disabling DMA transfer on the specified channel. */
        EDMA3DisableTransfer(edma_address, tccNum, EDMA3_TRIG_MODE_EVENT);
    
        clBackFlag = 1;
    }
    
    /*
    ** EDMA Completion Interrupt Service Routine(ISR).
    */
    static void Edma3CompletionIsr(void)
    {
        volatile uint32_t pendingIrqs;
        uint32_t          index = 1;
        uint32_t          count = 0;
    
        if (EDMA3GetIntrStatus(edma_address))
        {
            /*
            ** Wait for a finite time to monitor the EDMA Completion Interrupt
            ** status.
            */
            while ((count < EDMA3CC_COMPL_HANDLER_RETRY_COUNT) && (index != 0U))
            {
                index = 0;
    
                /* Get the Interrupt status. */
                pendingIrqs = EDMA3GetIntrStatus(edma_address);
                while (pendingIrqs)
                {
                    if ((pendingIrqs & 1U) == TRUE)
                    {
                        /* Clear the interrupt status. */
                        EDMA3ClrIntr(edma_address, index);
    
                        (*cb_Fxn[index])(index);
                    }
                    ++index;
                    pendingIrqs >>= 1U;
                }
                count++;
            }
        }
    
    #if 0
        if(EDMA3IntrStatusHighGet(edma_address))
        {
            Log_print1(Diags_ENTRY, "------------------> EDMA3IntrStatusHighGet: 0x%02x", EDMA3IntrStatusHighGet(edma_address));
    
            while ((count < EDMA3CC_COMPL_HANDLER_RETRY_COUNT) && (index != 0U))
            {
                index = 32;
    
                pendingIrqs = EDMA3IntrStatusHighGet(edma_address);
                while(pendingIrqs)
                {
                    if( (pendingIrqs & 1U) == TRUE )
                    {
                        EDMA3ClrIntr(edma_address, index);
    
                        if(cb_Fxn[index])
                        {
                            (*cb_Fxn[index])(index);
                        }
                    }
                }
            }
        }
    #endif
    }
    
    
    /*
    ** EDMA Error Interrupt Service Routine(ISR).
    */
    static void Edma3ErrorIsr(void)
    {
        volatile uint32_t pendingIrqs = 0;
        uint32_t          evtqueNum   = 0;
        uint32_t          index       = 1;
        uint32_t          Cnt         = 0;
    
        Log_print2(Diags_ENTRY, "EDMA3GetErrIntrStatus: 0x%02x, EDMA3GetCCErrStatus: 0x%02x", EDMA3GetErrIntrStatus(edma_address), EDMA3GetCCErrStatus(edma_address));
        Log_print1(Diags_ENTRY, "EDMA3ErrIntrHighStatusGet: 0x%02x", EDMA3ErrIntrHighStatusGet(edma_address));
    
        if ((0 != EDMA3GetErrIntrStatus(edma_address)) ||
            (0 != (EDMA3GetCCErrStatus(edma_address))))
        {
            /* Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time, breaks
             * when no pending interrupt is found */
            while ((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0U))
            {
                index       = 0U;
                pendingIrqs = EDMA3GetErrIntrStatus(edma_address);
    
                while (pendingIrqs)
                {
                    /*Process all the pending interrupts*/
                    if ((pendingIrqs & 1U) == TRUE)
                    {
                        /* Writing to EMCR to clear the corresponding EMR bits.
                         * Also clearing any Secondary events in SER. */
                        EDMA3ClrMissEvt(edma_address, index);
                    }
                    ++index;
                    pendingIrqs >>= 1U;
                }
    
                index = 0U;
                pendingIrqs = EDMA3GetCCErrStatus(edma_address);
                if (pendingIrqs != 0U)
                {
                    /* Process all the pending CC error interrupts. */
                    /* Queue threshold error for different event queues. */
                    for (evtqueNum = 0U; evtqueNum < EDMA3_0_NUM_EVTQUE;
                         evtqueNum++)
                    {
                        if ((pendingIrqs & (1U << evtqueNum)) != 0U)
                        {
                            /* Clear the error interrupt. */
                            EDMA3ClrCCErr(edma_address, (1U << evtqueNum));
                        }
                    }
    
                    /* Transfer completion code error. */
                    if ((pendingIrqs & (1 << EDMA_TPCC_CCERR_TCERR_SHIFT)) != 0U)
                    {
                        EDMA3ClrCCErr(edma_address,
                                      (0x01U << EDMA_TPCC_CCERR_TCERR_SHIFT));
                    }
                    ++index;
                }
    
                Cnt++;
            }
        }
    
        Log_print2(Diags_ENTRY, "EDMA3GetErrIntrStatus: 0x%02x, EDMA3GetCCErrStatus: 0x%02x", EDMA3GetErrIntrStatus(edma_address), EDMA3GetCCErrStatus(edma_address));
        Log_print1(Diags_ENTRY, "EDMA3ErrIntrHighStatusGet: 0x%02x", EDMA3ErrIntrHighStatusGet(edma_address));
    }
    
    #define DSP1_EDMA3_CC_XFER_COMPLETION_INT 19  //TPCC_INT2 - EDMA CC region2 interrupt
    #define DSP1_EDMA3_CC_ERROR_INT 27
    static void edma_cb_isr(UInt32 event_id)
    {
        switch(event_id) {
        case DSP1_EDMA3_CC_XFER_COMPLETION_INT:  /* Transfer completed successfully */
            Edma3CompletionIsr();
            break;
    
        case DSP1_EDMA3_CC_ERROR_INT: /* Transfer resulted in error. */
            Edma3ErrorIsr();
            break;
        default:
            break;
        };
    }
    
    static void edma_hwi_init(void)
    {
        Hwi_Params hwiParams;
        Error_Block eb;
    
        Hwi_Params_init(&hwiParams);
        Error_init(&eb);
    
        /* set the event id of the peripheral assigned to this interrupt */
        hwiParams.eventId = DSP1_EDMA3_CC_XFER_COMPLETION_INT;
    
        /* set the argument passed to ISR function */
        hwiParams.arg = DSP1_EDMA3_CC_XFER_COMPLETION_INT;
    
        hwiParams.maskSetting = Hwi_MaskingOption_SELF;
    
        Hwi_create(11, edma_cb_isr, &hwiParams, &eb);
        if (Error_check(&eb)) {
            Log_print0(Diags_INFO, "Hwi create failed \n");
            return ;
        }
    
        /* set the event id of the peripheral assigned to this interrupt */
        hwiParams.eventId = DSP1_EDMA3_CC_ERROR_INT;
    
        /* set the argument passed to ISR function */
        hwiParams.arg = DSP1_EDMA3_CC_ERROR_INT;
    
        hwiParams.maskSetting = Hwi_MaskingOption_SELF;
    
        Hwi_create(12, edma_cb_isr, &hwiParams, &eb);
        if (Error_check(&eb)) {
            Log_print0(Diags_INFO, "Hwi create failed \n");
            return ;
        }
    
    //    Hwi_enable();
    }
    
    void uart_task(UArg a0, UArg a1)
    {
        uint32_t icyc = 0;
        for(icyc=0; icyc<256; icyc++)
        {
            local_arr[icyc] = icyc+1;
        }
    
        Log_print0(Diags_ENTRY, "uart_task | edma | 20220401-V5.3.1");
    
    
        /*Pad configuration and PRCM enable*/
        padConfig_prcmEnable();
    
        /*Configure the EDMA clock */
        PlatformEDMAWkupDepEnable();
    
        /* Do EDMA init Done once in the beginning of application */
        EDMAsetRegion(EDMA3_CC_REGION);
        EDMA3Init(edma_address, EVT_QUEUE_NUM); // SOC_EDMA_TPCC_BASE_VIRT  CSL_DSP_DSP_EDMA_CC_REGS
    
        Edma3INTCConfigure();
    
        UartInitialize();
    
        EdmaEvtConfigure();
    
        /* Request DMA Channel and TCC for UART Transmit*/
        EDMA3RequestChannel(edma_address, EDMA3_CHANNEL_TYPE_DMA,
                            EDMA3_UART_TX_CHA_NUM, EDMA3_UART_TX_CHA_NUM,
                            EVT_QUEUE_NUM);
    
        /* Registering Callback Function for TX*/
        cb_Fxn[EDMA3_UART_TX_CHA_NUM] = &callback;
    
    
        icyc = 8;
        /* Configuring EDMA PaRAM sets to transmit 'welcome' message. */
        UartTransmitData(EDMA3_UART_TX_CHA_NUM,
                                     EDMA3_UART_TX_CHA_NUM,
                                     (volatile char *)local_arr,
                                     icyc++);
    
        // 使能 EDMA3 通道
        EDMA3EnableTransfer(edma_address, EDMA3_UART_TX_CHA_NUM, EDMA3_TRIG_MODE_EVENT); //EDMA3_TRIG_MODE_EVENT  EDMA3_TRIG_MODE_MANUAL
    
        /* Enabling DMA Mode 3. */
        UARTDMAEnable(uartBaseAddr, UART_DMA_MODE_3_ENABLE);
    
        while(1)
        {
            if(clBackFlag == 1)
            {
                clBackFlag = 0;
    
                /* Configuring EDMA PaRAM sets to transmit 'welcome' message. */
                UartTransmitData(EDMA3_UART_TX_CHA_NUM,
                                         EDMA3_UART_TX_CHA_NUM,
                                         (volatile char *)local_arr,
                                         icyc);
    
                // 使能 EDMA3 通道
                EDMA3EnableTransfer(edma_address, EDMA3_UART_TX_CHA_NUM, EDMA3_TRIG_MODE_EVENT); //EDMA3_TRIG_MODE_EVENT  EDMA3_TRIG_MODE_MANUAL
    
                /* Enabling DMA Mode 3. */
                UARTDMAEnable(uartBaseAddr, UART_DMA_MODE_3_ENABLE);
    
                icyc++;
    
                if(icyc == 70)
                {
                    icyc = 0;
                    break;
                }
            }
            Task_sleep(100);
        }
    	
    	    /******************* Freeing of allocated channels **********************/
    
        /* Free EDMA3 Channels for TX and RX */
    //    EDMA3FreeChannel(edma_address, EDMA3_CHANNEL_TYPE_DMA,
    //                     EDMA3_UART_TX_CHA_NUM, EDMA3_TRIG_MODE_MANUAL,
    //                     EDMA3_UART_TX_CHA_NUM, EVT_QUEUE_NUM);
    
    }
    
    
    

    目前,我已实现UART EDMA发送数据,但是存在BUG,只能发送8-65字节的数据,若发送数据长度小于8字节,则无法发送数据,发送数据长度大于65字节,则只能发送65字节,超出部分的数据丢失。能帮我看下我的配置哪里出问题吗?

    我怀疑是UART FIFO配置异常,还有就是,PaRAM参数的opt[DAM],应该设置为INCR还是FIFO,若设置为FIFO,则FWID应该设置为多少?

  • 跟这个帖子中的现象有点像,参考以下帖子的讨论看一下,可能是FIFO下EDMA配置的问题。

    https://e2echina.ti.com/support/processors/f/processors-forum/190473/c6678-dma/586483