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.
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_COUNT 50U // Data Count Transaction #define MCSPI_INSTANCE 0//0-spi1 1-spi2 2-spi3 #define MCSPI_POLLED_MODE 0 #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_COUNT 256U // 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_t gChNum = 0; uint32_t length = 0; uint8_t dataFromSlave; uint8_t rxBuffer[McSPI_DATA_COUNT + 10]; uint8_t txBuffer[McSPI_DATA_COUNT + 10]; uint8_t txSlvBuffer[McSPI_DATA_COUNT + 10]; uint8_t rxSlvBuffer[McSPI_DATA_COUNT + 10]; uint8_t gRxBuffer[McSPI_DATA_COUNT]; uint8_t gTxBuffer[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 */ /* SIDLEMODE bit - Ignore the idle request and configure in normal mode */ /* AUTOIDLE bit - 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, ¶mSet); /* 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, ¶mSet); /* 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事件触发就无法成功了呢?
期待您的宝贵意见!谢谢!
例程: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,因此没有采用这种方式。
尝试了很多种方式,也看了很多论坛的帖子,没有找到可以使用的方式,如果这种方式不能够使用的话,您能提供一个例程吗?
您好,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_COUNT 3U /* 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_Transaction transaction; /* 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_ENABLE if (dmaMode) { CacheP_wb((void *)txBuf, (int32_t)McSPI_DATA_COUNT); CacheP_wb((void *)rxBuf, (int32_t)McSPI_DATA_COUNT); } #endif #ifdef MCSPI_MULT_CHANNEL if (multChn == true) { retVal = MCSPI_transfer((MCSPI_Handle)spi, &transaction); } else #endif { retVal = SPI_transfer((SPI_Handle)spi, &transaction); } #ifdef SPI_DMA_ENABLE if (dmaMode == true) { CacheP_Inv((void *)rxBuf, (int32_t)McSPI_DATA_COUNT); } #endif if(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; bool pollMode = false; #ifdef SPI_DMA_ENABLE bool dmaMode = 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_ENABLE if (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_Params spiParams; /* SPI params structure */ SPI_Handle spi; /* SPI handle */ uint32_t instance; bool retVal = FALSE; /* return value */ bool cbMode = false; bool dmaMode = true; uint32_t timeout = 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_Params mcSpiParams; MCSPI_Handle spi[MCSPI_MAX_NUM_CHN]; MCSPI_CallbackFxn cbFxn[MCSPI_MAX_NUM_CHN] = {MCSPI_callback0}; uint32_t instance, chn; bool retVal = FALSE; bool cbMode = true; bool dmaMode = true; uint32_t timeout = 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; /** * \brief Function 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_t edma3Id; 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); } #endif void spi_lld_test(void) { // spi_test_single_channel(NULL); // McSPI1SetUp(); spi_test_multiple_channel(NULL); }
所以目前有两个问题:
1、CSL的方式如何才能触发EDMA中断?
2、LLD的方式为什么不能实现48Mhz传输?
你好,Nancy,很抱歉,就在刚刚回复你过后,我实现了LLD方式48Mhz传输,在分配内存前增加了 #pragma DATA_ALIGN (txBuf, 32),但是每次只能传输32字节,这是在手册上规定的吗,可我在手册上没有看到,还需要注意哪些地方才能传输更大的数据呢?
应该没有字节数的限定,这部分内容我没有测试过,我认为可能是与EDMA部分的配置有关系。
https://www.ti.com/lit/ug/sprugs5b/sprugs5b.pdf
https://e2echina.ti.com/support/processors/f/processors-forum/194970/edma3-sysbios
非常抱歉,最近测试出,之前触发的只是SPI传输中断,并不是DMA中断,如果在cfg文件中调用Spi.Setting.useDma="true";就无法再触发回调函数了,也就是说,DMA传输并没有成功。