TI中文支持网
TI专业的中文技术问题搜集分享网站

AM5718: DSP核使用MCSPI无法触发EDMA中断

Part Number:AM5718

TI的工程师您好,我参考了TI的SPI EDMA传输例程,在使用轮询的方式下MCSPI1能够回环传输数据,但是在使用EDMA的时候,始终无法触发中断,SPI部分代码如下:

#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Diags.h>
#include <xdc/runtime/Log.h>
#include <xdc/runtime/Assert.h>
#include <xdc/runtime/Registry.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/ipc/Ipc.h>
#include <ti/ipc/MessageQ.h>
#include <ti/ipc/MultiProc.h>
#include <stdio.h>
#include <ti/csl/example/utils/common/inc/app_utils.h>
#include <ti/csl/soc.h>
#include <ti/csl/hw_types.h>
#include <ti/csl/csl_edma.h>
#include <ti/csl/arch/csl_arch.h>
#include <ti/drv/spi/SPI.h>
#include <ti/csl/csl_mcspi.h>
#include <ti/drv/spi/soc/SPI_soc.h>
#include <ti/drv/spi/src/SPI_osal.h>
//#include "bsp_spi.h"
//#include "edma_test.h"
#include <ti/osal/HwiP.h>
#include <ti/csl/arch/csl_arch.h>
#include <ti/csl/csl_types.h>
#include <ti/csl/csl_edma.h>
#include <ti/csl/arch/c66x/interrupt.h>
#include <ti/csl/soc/am571x/src/cslr_soc_dsp_baseaddress.h>
#include <ti/csl/src/ip/edma/V1/edma.h>
#include <ti/csl/src/ip/edma/V1/hw_edma_tpcc.h>

/* ========================================================================== */
/*Macros*/
/* ========================================================================== */

//#define McSPI_DATA_COUNT50U // Data Count Transaction
#define MCSPI_INSTANCE 0//0-spi1 1-spi2 2-spi3
#define MCSPI_POLLED_MODE0

#define HSI2C_EN_SPI2((uint8_t) 0x40U)
#define HSI2C_ZERO((uint8_t) 0x00U)

#define MCSPI_OUT_FREQ(48000000U)
#define MCSPI_IN_CLK(48000000U)
#define McSPI_DATA_COUNT256U // Data Count Transaction
#define MCSPI1_BASE_ADDRESS(CSL_MPU_MCSPI1_REGS)
#define MCSPI2_BASE_ADDRESS(CSL_MPU_MCSPI2_REGS)

/** \brief EDMA3 channel for SPI1 Channel 0 Tx and Rx*/
#define MCSPI1_TX_EVENT(34U)
#define MCSPI1_RX_EVENT(35U)

/** \brief EDMA3 channel for SPI2 Channel 0 Tx and Rx*/
#define MCSPI2_TX_EVENT(42U)
#define MCSPI2_RX_EVENT(43U)

/** \brief MCSPI Tx/Rx buffer base address */
#define MCSPI1_TX0_REG(SOC_MCSPI1_BASE + (0x138U))
#define MCSPI1_RX0_REG(SOC_MCSPI1_BASE + (0x13CU))

#define MCSPI2_TX0_REG(SOC_MCSPI2_BASE + (0x138U))
#define MCSPI2_RX0_REG(SOC_MCSPI2_BASE + (0x13CU))

/** \brief MCSPI Channel number*/
#define MCSPI_CH_NUM(0U)

#define EVT_QUEQUE_NUM(0U)
#define DUMMY_CH_NUM(5U)

#define EDMA_TDA2XX_U_BASE(CSL_DSP_DSP_EDMA_CC_REGS)

#define EDMA3CC_PaRAM_BASE(0x4000)
#define EDMA3CC_OPT(n)(EDMA3CC_PaRAM_BASE + 0x0 + (0x20 * n))

#define EDMA3_CC_XFER_COMPLETION_INT_A15(12U)
#define EDMA3_CC_XFER_COMPLETION_INT_M4(35U)

/* DSP1 EDMA3 transfer event number */
#define DSP1_EDMA3_CC_XFER_COMPLETION_INT 19
#define DSP1_EDMA3_CC_ERROR_INT 27

/* DSP1 EDAM3 region number */
#define DSP1_EDMA3_REGION 2

/* DSP1 EDMA3 channel number */
#define DSP1_EDMA3_CHANNEL 0

/* DSP1 EDMA3 tcc number */
#define DSP1_EDMA3_TCC 0

/* DSP1 EDMA3 evtq number */
#define DSP1_EDMA3_EVTQ 0

/* 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 EDMA3_ERROR_INT_A15(14)
#define EDMA3_ERROR_INT_A15_1(15)
#define EDMA3_ERROR_INT_M4(36)
#define EDMA3_ERROR_INT_M4_1(37)

#define EDMA3_CC_REGION_A15(0U)
#define EDMA3_CC_REGION_M4(1U)

#define MCSPI_MASTERSLAVE_POLLED_MODE_TEST('1')
#define MCSPI_MASTERSLAVE_DMA_MODE_TEST('2')
#define EXIT(opt)(('x' == opt) || ('X' == opt))



/**********************************************************************
 ************************** Global Variables **************************
 **********************************************************************/
uint32_t dataToSlave;

uint32_tgChNum  = 0;
uint32_tlength = 0;
uint8_tdataFromSlave;
uint8_trxBuffer[McSPI_DATA_COUNT + 10];
uint8_ttxBuffer[McSPI_DATA_COUNT + 10];
uint8_ttxSlvBuffer[McSPI_DATA_COUNT + 10];
uint8_trxSlvBuffer[McSPI_DATA_COUNT + 10];
uint8_tgRxBuffer[McSPI_DATA_COUNT];
uint8_tgTxBuffer[McSPI_DATA_COUNT];

static void(*cb_Fxn[EDMA3_NUM_TCC]) (uint32_t tcc,uint32_t status);

volatile uint8_t  flagTx= 0;
volatile uint8_t  flagRx= 0;
volatile uint8_t  flagSlvTx = 0;
volatile uint8_t  flagSlvRx = 0;

/* ========================================================================== */
/*Function Declarations*/
/* ========================================================================== *//* clock callback function */
void SPI_callback(SPI_Handle handle, SPI_Transaction *transaction);
static void McSPI1SetUp(void);
static void McSPIMSTransfer(uint16_t length);
static void McSPIVerifyData(void);
static void McSPIInitializeBuffers(void);
void McSPIMasterSlaveAppTest(void);
static void McSPIConfigureDma(uint32_t length);

static void McSpi1TxEdmaParamSet(uint32_t tccNum, uint32_t chNum,volatile uint8_t *buffer,uint16_t buffLength);
static void McSpi1RxEdmaParamSet(uint32_t tccNum, uint32_t chNum,volatile uint8_t *buffer,uint16_t buffLength,uint32_t destBidxFlag);
static void CallBack_McSPI1(uint32_t tccNum, uint32_t status);
static void TxDummyPaRAMConfEnable(void);
static void RequestEDMA3Channels(void);
static void EDMA3Initialize(void);
static void spiedma_cb_isr(UInt32 event_id);
static int EDMA3IntConfigure(void);


/* ========================================================================== */
/*Function Definitions*/
/* ========================================================================== */

void McSPIMasterSlaveAppTest(void)
{/* Do the necessary set up configurations for McSPI.*/
//EDMA3Init(EDMA_TDA2XX_U_BASE, 0);/* Initialize the EDMA3 instance.*/EDMA3Initialize();/* Request EDMA3CC for Tx and Rx channels for SPI0. */RequestEDMA3Channels();McSPI1SetUp();McSPIInitializeBuffers();McSPIConfigureDma(McSPI_DATA_COUNT);McSPIMSTransfer(McSPI_DATA_COUNT);Task_sleep(1000);/* Verify whether the data written by Master and the one read by* Slave are Equal */McSPIVerifyData();
}

static void EDMA3Initialize(void)
{/* Configuring the AINTC to receive EDMA3 Interrupts */EDMA3IntConfigure();
}

/*
** This function configures the AINTC to receive EDMA3 interrupts.
*/
static int EDMA3IntConfigure(void)
{
#ifdef _TMS320C6X/* Initialize DSP interrupt controller and enable interrupts */Hwi_Params hwiParams;Error_Block eb;EDMAsetRegion(DSP1_EDMA3_REGION);EDMA3Init(CSL_DSP_DSP_EDMA_CC_REGS, 0);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(12, spiedma_cb_isr, &hwiParams, &eb);if (Error_check(&eb)) {Log_print0(Diags_INFO, "Hwi create failed \n");return -1;}/* 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(13, spiedma_cb_isr, &hwiParams, &eb);if (Error_check(&eb)) {Log_print0(Diags_INFO, "Hwi create failed \n");return -1;}Hwi_enable();
#endif
}

static void spiedma_cb_isr(UInt32 event_id)
{System_printf("spiedma_cb_isr...\r\n");switch(event_id) {case DSP1_EDMA3_CC_XFER_COMPLETION_INT:/* Transfer completed successfully */
//(*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);break;case DSP1_EDMA3_CC_ERROR_INT:/* Transfer resulted in error. */break;default:break;};EDMA3ClrIntr(CSL_DSP_DSP_EDMA_CC_REGS, DSP1_EDMA3_TCC);
}

/*
** This function allocates EDMA3 channels to McSPI0 for trasmisssion and
** reception purposes.
*/
static void RequestEDMA3Channels(void)
{/* Request DMA Channel and TCC for SPI Transmit*/EDMA3RequestChannel(EDMA_TDA2XX_U_BASE, EDMA3_CHANNEL_TYPE_DMA, \MCSPI1_TX_EVENT, MCSPI1_TX_EVENT, EVT_QUEQUE_NUM);EDMA3EnableEvtIntr(EDMA_TDA2XX_U_BASE, MCSPI1_TX_EVENT);/* Request DMA Channel and TCC for SPI Receive*/EDMA3RequestChannel(EDMA_TDA2XX_U_BASE, EDMA3_CHANNEL_TYPE_DMA, \MCSPI1_RX_EVENT, MCSPI1_RX_EVENT, EVT_QUEQUE_NUM);EDMA3EnableEvtIntr(EDMA_TDA2XX_U_BASE, MCSPI1_RX_EVENT);
}

/*
** This function will call the necessary McSPI APIs which will configure the
** McSPI controller.
*/
static void McSPI1SetUp(void)
{uint32_t status = 1U; // FALSE/* Reset the McSPI instance.*/McSPIReset(MCSPI1_BASE_ADDRESS);/* CLOCKACTIVITY bit - OCP and Functional clocks are maintained*//* SIDLEMODEbit - Ignore the idle request and configure in normal mode*//* AUTOIDLEbit - Disable (OCP clock is running free, no gating)*/MCSPISysConfigSetup(MCSPI1_BASE_ADDRESS, MCSPI_CLOCKS_OCP_ON_FUNC_ON,MCSPI_SIDLEMODE_NO, MCSPI_WAKEUP_DISABLE,MCSPI_AUTOIDLE_OFF);/* Enable chip select pin.*/McSPICSEnable(MCSPI1_BASE_ADDRESS);/* Enable master mode of operation.*/McSPIMasterModeEnable(MCSPI1_BASE_ADDRESS);/* Perform the necessary configuration for master mode. */status = McSPIMasterModeConfig(MCSPI1_BASE_ADDRESS, MCSPI_SINGLE_CH,MCSPI_TX_RX_MODE,MCSPI_DATA_LINE_COMM_MODE_6,gChNum);if (0 == status){//UARTConfigPuts(uartBaseAddr,"\nMcSPI1 - Communication not supported by SPIDAT[1:0]",-1);}/* Configure the McSPI bus clock depending on clock mode. */McSPIClkConfig(MCSPI1_BASE_ADDRESS, MCSPI_IN_CLK, MCSPI_OUT_FREQ, gChNum,MCSPI_CLK_MODE_0);/* Configure the word length.*/McSPIWordLengthSet(MCSPI1_BASE_ADDRESS, MCSPI_WORD_LENGTH(8), gChNum);/* Set polarity of SPIEN to low.*/McSPICSPolarityConfig(MCSPI1_BASE_ADDRESS,(MCSPI_CH0CONF_EPOL_ACTIVELOW <<MCSPI_CH0CONF_EPOL_SHIFT), gChNum);/* Enable the transmitter FIFO of McSPI peripheral.*/McSPITxFIFOConfig(MCSPI1_BASE_ADDRESS, MCSPI_TX_FIFO_ENABLE, gChNum);/* Enable the receiver FIFO of McSPI peripheral.*/McSPIRxFIFOConfig(MCSPI1_BASE_ADDRESS, MCSPI_RX_FIFO_ENABLE, gChNum);
}


static void McSPIInitializeBuffers(void)
{uint32_t index = 0;static int cnt = 0;char msg[McSPI_DATA_COUNT] = {"Initialize the txBuffer McSPI1 with a known pattern of data:"};for (index = 0; index < McSPI_DATA_COUNT; index++){/* Initialize the txBuffer McSPI1 with a known pattern of data */

//txBuffer[index] = (uint8_t) index;/* Initialize the rxBuffer McSPI1 with 0 */rxBuffer[index] = (uint8_t) 0;}sprintf(txBuffer,"%s%d",msg,cnt++);for (index = 0; index < McSPI_DATA_COUNT; index++){/* Initialize the txBuffer McSPI1 with a known pattern of data */txSlvBuffer[index] = (uint8_t) index;/* Initialize the rxBuffer McSPI1 with 0 */rxSlvBuffer[index] = 0;}
}


static void McSPIConfigureDma(uint32_t length)
{/* DMA PaRAM Configuration for McSPI1 *//* Configure the read data parameters of McSPI for Edma transmit.*/McSpi1TxEdmaParamSet(MCSPI1_TX_EVENT, MCSPI1_TX_EVENT, txBuffer,length);/* Configure the read data parameters of McSPI for Edma receive.*/McSpi1RxEdmaParamSet(MCSPI1_RX_EVENT, MCSPI1_RX_EVENT, rxBuffer,length, TRUE);/* Register the call-back function for Tx/Rx edma events of McSPI.*/cb_Fxn[MCSPI1_TX_EVENT] = &CallBack_McSPI1;cb_Fxn[MCSPI1_RX_EVENT] = &CallBack_McSPI1;/* Set the word count field with the data length to be transferred.*/McSPIWordCountSet(MCSPI1_BASE_ADDRESS, length);/* Enable the Tx/Rx DMA events for McSPI. */McSPIDMAEnable(MCSPI1_BASE_ADDRESS,(MCSPI_DMA_RX_EVENT | MCSPI_DMA_TX_EVENT),MCSPI_CH_NUM);
}

/*
** Call back function. Here we disable the Tx/Rx DMA events of McSPI
** peripheral.
*/
static void CallBack_McSPI1(uint32_t tccNum, uint32_t status)
{System_printf("CallBack_McSPI1...\r\n");if (tccNum == MCSPI1_TX_EVENT){flagTx = 1;System_printf("MCSPI1_TX_EVENT\r\n");/* Disable McSPI Transmit event */McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAW_MASK,MCSPI_CH_NUM);}if (tccNum == MCSPI1_RX_EVENT){flagRx = 1;System_printf("MCSPI1_RX_EVENT\r\n");/* Disable McSPI Receive event */McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAR_MASK,MCSPI_CH_NUM);}
}

/*
** This function is used to set the PaRAM entries of EDMA3 for the Receive
** event of channel 0 of McSPI1 instance. The corresponding EDMA3 channel
** is also enabled for reception.
*/
static void McSpi1RxEdmaParamSet(uint32_t tccNum, uint32_t chNum,volatile uint8_t *buffer,uint16_t buffLength,uint32_t destBidxFlag)
{EDMA3CCPaRAMEntry paramSet = {0};/* Fill the PaRAM Set with Receive specific information.*//* srcAddr holds address of SPI Rx FIFO.*/paramSet.srcAddr = (uint32_t) (MCSPI1_RX0_REG);/* destAddr is address of memory location named buffer.*/paramSet.destAddr = (uint32_t) buffer;/* aCnt holds the number of bytes in an array.*/paramSet.aCnt = 1;/* bCnt holds the number of such arrays to be transferred.*/paramSet.bCnt = buffLength;/* cCnt holds the number of frames of aCnt*bBcnt bytes to be transferred.*/paramSet.cCnt = 1;/* The srcBidx should not be incremented since it is a h/w register.*/paramSet.srcBIdx = 0;if (TRUE == destBidxFlag){/* The destBidx should be incremented for every byte.*/paramSet.destBIdx = 1;}else{/* The destBidx should not be incremented.*/paramSet.destBIdx = 0;}/* A sync Transfer Mode. *//* srCIdx and destCIdx set to zero since ASYNC Mode is used.*/paramSet.srcCIdx  = 0;paramSet.destCIdx = 0;/* Linking transfers in EDMA3 are not used.*/paramSet.linkAddr = 0xFFFF;paramSet.bCntReload = 0;paramSet.opt = 0x00000000;/* Set TCC field in OPT with the tccNum.*/paramSet.opt |= ((tccNum << EDMA_TPCC_OPT_TCC_SHIFT) &EDMA_TPCC_OPT_TCC_MASK);/* EDMA3 Interrupt is enabled and Intermediate Interrupt Disabled.*/paramSet.opt |= (1 << EDMA_TPCC_OPT_TCINTEN_SHIFT);/* Now write the PaRam Set to EDMA3.*/EDMA3SetPaRAM(EDMA_TDA2XX_U_BASE, chNum, &paramSet);/* EDMA3 Transfer is Enabled.*/EDMA3EnableTransfer(EDMA_TDA2XX_U_BASE, chNum, EDMA3_TRIG_MODE_EVENT);
}

/*
** This function is used to set the PaRAM entries of EDMA3 for the Transmit
** Channel 0 of SPI1 instance. The corresponding EDMA3 channel is also enabled
** for transmission.
*/
static void McSpi1TxEdmaParamSet(uint32_t tccNum, uint32_t chNum,volatile uint8_t *buffer,uint16_t buffLength)
{EDMA3CCPaRAMEntry paramSet = {0};/* Fill the PaRAM Set with transfer specific information. *//* srcAddr holds address of memory location buffer. */paramSet.srcAddr = (uint32_t) buffer;/* destAddr holds address of McSPI_TX register. */paramSet.destAddr = (uint32_t) (MCSPI1_TX0_REG);/* aCnt holds the number of bytes in an array. */paramSet.aCnt = 1;/* bCnt holds the number of such arrays to be transferred. */paramSet.bCnt = buffLength;/* cCnt holds the number of frames of aCnt*bBcnt bytes to be transferred. */paramSet.cCnt = 1;/*** The srcBidx should be incremented by aCnt number of bytes since the** source used here is memory.*/paramSet.srcBIdx  = 1;paramSet.destBIdx = 0;/* Async Transfer Mode is set in OPT.*//* srCIdx and destCIdx set to zero since ASYNC Mode is used. */paramSet.srcCIdx  = 0;paramSet.destCIdx = 0;/* Linking transfers in EDMA3 are not used. */paramSet.linkAddr= (EDMA3CC_OPT(DUMMY_CH_NUM));paramSet.bCntReload = 0;paramSet.opt = 0x00000000;/* SAM and DAM fields both are set to 0 *//* Set TCC field in OPT with the tccNum. */paramSet.opt |= ((tccNum << EDMA_TPCC_OPT_TCC_SHIFT) &EDMA_TPCC_OPT_TCC_MASK);/* EDMA3 Interrupt is enabled and Intermediate Interrupt Disabled.*/paramSet.opt |= (1 << EDMA_TPCC_OPT_TCINTEN_SHIFT);/* Now write the PaRam Set to EDMA3.*/EDMA3SetPaRAM(EDMA_TDA2XX_U_BASE, chNum, &paramSet);/* Dummy param set is enabled */TxDummyPaRAMConfEnable();/* EDMA3 Transfer is Enabled. */EDMA3EnableTransfer(EDMA_TDA2XX_U_BASE, chNum, EDMA3_TRIG_MODE_EVENT);
}

/*
** This configures the PaRAM set for the Dummy Transfer.
*/
static void TxDummyPaRAMConfEnable(void)
{EDMA3CCPaRAMEntry dummyPaRAMSet;EDMA3GetPaRAM(EDMA_TDA2XX_U_BASE, DUMMY_CH_NUM, &dummyPaRAMSet);dummyPaRAMSet.aCnt= 1;dummyPaRAMSet.bCnt= 0;dummyPaRAMSet.cCnt= 0;dummyPaRAMSet.srcAddr= 0;dummyPaRAMSet.destAddr= 0;dummyPaRAMSet.srcBIdx= 0;dummyPaRAMSet.destBIdx= 0;dummyPaRAMSet.srcCIdx= 0;dummyPaRAMSet.destCIdx= 0;dummyPaRAMSet.linkAddr= 0xFFFFU;dummyPaRAMSet.bCntReload = 0;dummyPaRAMSet.opt= 0;EDMA3SetPaRAM(EDMA_TDA2XX_U_BASE, DUMMY_CH_NUM, &dummyPaRAMSet);
}

static void McSPIMSTransfer(uint16_t length)
{/* Enable the McSPI channel for communication.*/McSPIChannelEnable(MCSPI1_BASE_ADDRESS, gChNum);/* SPIEN line is forced to low state.*/McSPICSAssert(MCSPI1_BASE_ADDRESS, gChNum);Task_sleep(1000);/* Force SPIEN line to the inactive state.*/McSPICSDeAssert(MCSPI1_BASE_ADDRESS, gChNum);/* Disable the McSPI channel.*/McSPIChannelDisable(MCSPI1_BASE_ADDRESS, gChNum);
}

/*
** This function will verify the data written to and read from flash and print
** the appropriate message.
*/
static void McSPIVerifyData(void)
{uint32_t index = 0;uint32_t error = 0;

//for (index = 0; index < McSPI_DATA_COUNT; index++)
//{
//if ((rxSlvBuffer[index] != txBuffer[index]) ||
//(txSlvBuffer[index] != rxBuffer[index]))
//{
////UARTConfigPuts(uartBaseAddr,"\nData Mismatch found at index : \r",-1);
//error = 1;
//break;
//}
//}System_printf("txBuffer:%s\r\n",txBuffer);System_printf("rxBuffer:%s\r\n",rxBuffer);memset(txBuffer,0,McSPI_DATA_COUNT);
//memset(rxBuffer,0,McSPI_DATA_COUNT);if (error == 0){//UARTConfigPuts(uartBaseAddr,"\nThe data written by Master and the one read by Slave are Equal",-1);}
}

我在单独使用EDMA在内存中传输数据时能够触发中断,但是为什么变成MCSPI事件触发就无法成功了呢?

期待您的宝贵意见!谢谢!

Nancy Wang:

请详细说明一下是在哪个例程上做了哪些修改。

,

hongyou lu:

例程:processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\csl\example\mcspi\mcspiMasterSlave\mcspiMasterSlave_spi1_spi2.c

修改部分:1、static int EDMA3IntConfigure(void);  2、SOC_EDMA_TPCC_BASE_VIRT换成CSL_DSP_DSP_EDMA_CC_REGS

修改原因:1、找不到IntRegister等函数。2、程序运行失败

也参考了MCSPI_BasicExample_Dma_idkAM571x_c66xTestProject的方式,但是程序会卡在edma3init,因此没有采用这种方式。

参考帖子:https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_DSP_3432812

https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_DSP_am5728-rtos-issues-with-spi

尝试了很多种方式,也看了很多论坛的帖子,没有找到可以使用的方式,如果这种方式不能够使用的话,您能提供一个例程吗?

,

Nancy Wang:

好的,稍后我会升级到英文论坛。

,

hongyou lu:

你好,发布到英文论坛了吗

,

Nancy Wang:

已经发了,请关注:

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1070837/am5718-mcspi-edma

已分配相关专家跟进。

,

hongyou lu:

您好,Nancy,我使用LLD的方式(MCSPI_BasicExample_Dma_idkAM571x_c66xTestProject)实现了EDMA传输,解决方式是将edmainit的edma3Id改为1,但是又回到了我之前一个帖子的问题(https://e2echina.ti.com/support/processors/f/processors-forum/215638/am5718-dsp-spi),最大只能使用3Mhz了(使用超过3Mhz的CLK时在示波器能看到输出波形,数据量小的时候可以进入回调函数,但是无法传输数据,而数据量大的时候会卡在spi_transfer,也不会进入中断回调函数),部分测试代码如下:

/****************************************************************************************************************/
/****************************************test_spi_LLD************************************************************/
/****************************************************************************************************************/#include <string.h>/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>
#include <stdio.h>
#include <ti/sysbios/knl/Task.h>/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <xdc/runtime/Error.h>/* TI-RTOS Header files */
#include <ti/drv/spi/SPI.h>
#include <ti/drv/spi/soc/SPI_soc.h>
#include <ti/drv/spi/src/SPI_osal.h>
//#include "System_printf.h"
//#include "SPI_test.h"/* GPIO Header files */
#include <ti/drv/gpio/GPIO.h>
#include <ti/drv/gpio/soc/GPIO_v1.h>#include <ti/board/board.h>#ifdef SPI_DMA_ENABLE
#include <ti/osal/CacheP.h>/* EDMA3 Header files */
#include <ti/sdo/edma3/drv/edma3_drv.h>
#include <ti/sdo/edma3/rm/edma3_rm.h>
#include <ti/sdo/edma3/rm/sample/bios6_edma3_rm_sample.h>
#endif
/* Maximum # of channels per SPI instance */
#define MCSPI_MAX_NUM_CHN (1U)
#define McSPI_DATA_COUNT3U
/* Transfer length in bytes */#define MCSPI_OUT_FREQ(48000000U)
#define MCSPI_IN_CLK(48000000U)/* Buffer containing the known data that needs to be written to flash *///#pragma DATA_ALIGN (txBuf, 32)
uint8_t txBuf[McSPI_DATA_COUNT] = {1,2,3};//"123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.";/* Buffer containing the received data */
//#pragma DATA_ALIGN (rxBuf, 32)
uint8_t rxBuf[McSPI_DATA_COUNT] = {0};/* Transaction data */
SPI_Transactiontransaction;/* Flag to check transfer completion in callback mode */
uint32_t txCompleteCallbackFlag = 1U;/* Callback mode variables */
SemaphoreP_Params cbSemParams;
SemaphoreP_Handle cbSem[MCSPI_MAX_NUM_CHN] = {NULL};uint32_t testChNum = 0;/* Callback mode functions */
void SPI_callback(SPI_Handle handle, SPI_Transaction *transaction)
{SPI_osalPostLock(cbSem[0]);System_printf("SPI_callback\r\n");
}
#ifdef MCSPI_MULT_CHANNEL
void MCSPI_callback0(MCSPI_Handle handle, SPI_Transaction *transaction)
{SPI_osalPostLock(cbSem[0]);System_printf("MCSPI_callback0\r\n");
}#endif/**======== CompareData ========*/
bool VerifyData(uint8_t *expData, uint8_t *rxData, uint32_t length)
{uint32_t idx = 0;uint32_t match = 1;bool retVal = false;for(idx = 0; ((idx < length) && (match != 0)); idx++){if(*expData != *rxData) match = 0;expData++;rxData++;}if(match == 1) retVal = true;System_printf("txBuffer:%d\r\n",txBuf[1]);System_printf("rxBuffer:%d\r\n",rxBuf[1]);return retVal;
}/**======== spi_test_transfer ========*/
bool spi_test_transfer(void *spi, bool cbMode, uint32_t timeout, bool dmaMode, bool multChn)
{bool retVal;SemaphoreP_Handle sem;/* Load data *//* Initiate transfer */
//txBuf[0] = 0xAAU;memset(rxBuf, 0, McSPI_DATA_COUNT);transaction.status= SPI_TRANSFER_STARTED;transaction.count = McSPI_DATA_COUNT;transaction.txBuf = &txBuf[0];transaction.rxBuf = &rxBuf[0];#ifdef SPI_DMA_ENABLEif (dmaMode){CacheP_wb((void *)txBuf, (int32_t)McSPI_DATA_COUNT);CacheP_wb((void *)rxBuf, (int32_t)McSPI_DATA_COUNT);}
#endif#ifdef MCSPI_MULT_CHANNELif (multChn == true){retVal = MCSPI_transfer((MCSPI_Handle)spi, &transaction);}else
#endif{retVal = SPI_transfer((SPI_Handle)spi, &transaction);}#ifdef SPI_DMA_ENABLEif (dmaMode == true){CacheP_Inv((void *)rxBuf, (int32_t)McSPI_DATA_COUNT);}
#endifif(false == retVal){System_printf("\n Error occurred in spi transfer \n");goto Err;}else{/***wait for the semaphore is posed in the callback mode to indicate the*transfer completion.*/if(cbMode == true){if (multChn == true){sem = cbSem[testChNum];}else{sem = cbSem[0];}if (SPI_osalPendLock(sem, timeout) != SemaphoreP_OK){goto Err;}}//Task_sleep(1000);retVal = VerifyData((uint8_t *)&txBuf[0], &rxBuf[0], McSPI_DATA_COUNT);}System_printf("\n SPI_Transfer returned transaction status = %d,retVal = %d\n",transaction.status,retVal);Err:return (retVal);
}/**======== SPI init config ========*/
static void SPI_initConfig(uint32_t instance,bool multiChn)
{SPI_HWAttrs spi_cfg;boolpollMode = false;
#ifdef SPI_DMA_ENABLEbooldmaMode = true;
#endif/* Get the default SPI init configurations */SPI_socGetInitCfg(instance, &spi_cfg);/** Set blocking mode (dma mode or non-dma interrupt mode)* or callback mode*/if (pollMode == true){/* polling mode */spi_cfg.enableIntr = false;}else{/* interrupt enabled */spi_cfg.enableIntr = true;
#ifdef SPI_DMA_ENABLEif (dmaMode == true){/* Set the DMA related init config */spi_cfg.edmaHandle = MCSPIApp_edmaInit();spi_cfg.dmaMode= TRUE;}else
#endif{spi_cfg.edmaHandle = NULL;spi_cfg.dmaMode= FALSE;}}
//System_printf("spi_cfg.inputClkFreq = %d\n",spi_cfg.inputClkFreq);spi_cfg.inputClkFreq =MCSPI_IN_CLK;
//spi_cfg.chnCfg[0].dataLineCommMode = MCSPI_DATA_LINE_COMM_MODE_0;#ifdef MCSPI_MULT_CHANNEL
//testChNum = spi_cfg.chNum;/** Set multi or single channel mode*/
//if (multiChn == true)
//{
//spi_cfg.chMode = MCSPI_MULTI_CH;
//}
//else
//{
//spi_cfg.chMode = MCSPI_SINGLE_CH;
//}
#endif/* Set the SPI init configurations */SPI_socSetInitCfg(instance, &spi_cfg);
}//#define BOARD_MCSPI_SERIALIZER_INSTANCE 0U
/**======== spi_test_single_channel ========*/
bool spi_test_single_channel(void *arg)
{SPI_ParamsspiParams;/* SPI params structure */SPI_Handlespi;/* SPI handle */uint32_tinstance;boolretVal = FALSE;/* return value */boolcbMode = false;booldmaMode = true;uint32_ttimeout = SemaphoreP_WAIT_FOREVER;if (cbMode == true){/* Create call back semaphore */SPI_osalSemParamsInit(&cbSemParams);cbSemParams.mode = SemaphoreP_Mode_BINARY;cbSem[0] = SPI_osalCreateBlockingLock(0, &cbSemParams);}instance = 0;SPI_initConfig(instance, false);/* Default SPI configuration parameters */SPI_Params_init(&spiParams);spiParams.frameFormat= SPI_POL1_PHA0;spiParams.transferTimeout = timeout;spiParams.bitRate = MCSPI_OUT_FREQ;if (cbMode){spiParams.transferMode = SPI_MODE_CALLBACK;spiParams.transferCallbackFxn = SPI_callback;}/* Open QSPI driver */spi = SPI_open(instance, &spiParams);if (spi == NULL){System_printf("Error initializing SPI\n");goto Err;}else{System_printf("SPI initialized\n");}retVal = spi_test_transfer((void *)spi, cbMode, timeout, dmaMode, false);Err:if (spi){SPI_close(spi);}if (cbSem[0]){SPI_osalDeleteBlockingLock(cbSem[0]);cbSem[0] = NULL;}return (retVal);
}#ifdef MCSPI_MULT_CHANNEL
/**======== spi_test_multiple_channel ========*/
bool spi_test_multiple_channel(void *arg)
{MCSPI_ParamsmcSpiParams;MCSPI_Handlespi[MCSPI_MAX_NUM_CHN];MCSPI_CallbackFxn cbFxn[MCSPI_MAX_NUM_CHN] = {MCSPI_callback0};uint32_tinstance, chn;boolretVal = FALSE;boolcbMode = true;booldmaMode = true;uint32_ttimeout = SemaphoreP_WAIT_FOREVER;if (cbMode == true){/* Create call back semaphore */SPI_osalSemParamsInit(&cbSemParams);cbSemParams.mode = SemaphoreP_Mode_BINARY;}instance = 0;SPI_initConfig(instance,true);/* Default SPI configuration parameters */MCSPI_Params_init(&mcSpiParams);mcSpiParams.frameFormat= SPI_POL0_PHA0;mcSpiParams.transferTimeout = timeout;mcSpiParams.bitRate = MCSPI_OUT_FREQ;mcSpiParams.dataSize = 8;mcSpiParams.mode = SPI_MASTER;if (cbMode){mcSpiParams.transferMode = SPI_MODE_CALLBACK;}/* Open the default channel first */chn = testChNum;if (cbMode == true){cbSem[chn] = SPI_osalCreateBlockingLock(0, &cbSemParams);mcSpiParams.transferCallbackFxn = cbFxn[chn];}spi[chn] = MCSPI_open(instance, chn, &mcSpiParams);if (spi[chn] == NULL){System_printf("Error initializing SPI");goto Err;}else{System_printf("SPI instance %d channel %d initialized\n",instance, chn);}retVal = spi_test_transfer((void *)spi[testChNum], cbMode, timeout, dmaMode, true);Err:if (spi[chn]){MCSPI_close(spi[chn]);}if (cbSem[chn]){SPI_osalDeleteBlockingLock(cbSem[chn]);cbSem[chn] = NULL;}return (retVal);
}
#endif#ifdef SPI_DMA_ENABLE
EDMA3_RM_Handle gEdmaHandle = NULL;/*** \briefFunction to initialize the edma driver and get the handle to the*edma driver;*/
EDMA3_RM_Handle MCSPIApp_edmaInit(void)
{EDMA3_DRV_Result edmaResult = EDMA3_DRV_E_INVALID_PARAM;uint32_tedma3Id;if (gEdmaHandle != NULL){return (gEdmaHandle);}System_printf("\nMCSPIApp_edmaInit\n");edma3Id = 1;gEdmaHandle = (EDMA3_RM_Handle)edma3init(edma3Id, &edmaResult);if (edmaResult != EDMA3_DRV_SOK){/* Report EDMA Error */System_printf("\nEDMA driver initialization FAIL\n");}else{System_printf("\nEDMA driver initialization PASS.\n");}return(gEdmaHandle);
}
#endifvoid spi_lld_test(void)
{
//spi_test_single_channel(NULL);
//McSPI1SetUp();spi_test_multiple_channel(NULL);
}

所以目前有两个问题:

1、CSL的方式如何才能触发EDMA中断?

2、LLD的方式为什么不能实现48Mhz传输?

,

hongyou lu:

你好,Nancy,很抱歉,就在刚刚回复你过后,我实现了LLD方式48Mhz传输,在分配内存前增加了 #pragma DATA_ALIGN (txBuf, 32),但是每次只能传输32字节,这是在手册上规定的吗,可我在手册上没有看到,还需要注意哪些地方才能传输更大的数据呢?

,

Nancy Wang:

应该没有字节数的限定,这部分内容我没有测试过,我认为可能是与EDMA部分的配置有关系。

https://www.ti.com/lit/ug/sprugs5b/sprugs5b.pdf

https://e2echina.ti.com/support/processors/f/processors-forum/194970/edma3-sysbios

,

hongyou lu:

好的,我再研究下,谢谢!

,

hongyou lu:

谢谢你,Nancy,我在使用了04版本的RTOS SDK过后,这部分问题解决了,没有字节数的限制。

,

Nancy Wang:

好的,感谢分享!

,

hongyou lu:

非常抱歉,最近测试出,之前触发的只是SPI传输中断,并不是DMA中断,如果在cfg文件中调用Spi.Setting.useDma="true";就无法再触发回调函数了,也就是说,DMA传输并没有成功。

赞(0)
未经允许不得转载:TI中文支持网 » AM5718: DSP核使用MCSPI无法触发EDMA中断
分享到: 更多 (0)