Hello everyone,
I have established SPI communication using the pins of SPI NOR flash, as I explained in this post: https://e2e.ti.com/support/processors/f/791/p/902619/3342190#3342190.
I attempted to upgrade the communication, so that it uses DMA. Therefore, I have noticed that all of the functions of SPI driver have a corresponding calls to functions in case DMA is enabled. I have found the definitions of SPI configuration and transfer using DMA in the C:\ti\pdk_c665x_2_0_15\packages\ti\drv\spi\soc\dma\v0 directory inside the file SPI_dma.c, and also used main_mcspi_test.c, found in C:\ti\pdk_c665x_2_0_15\packages\ti\drv\spi\test\src as reference. Additionally I have imported several files from C:\ti\edma3_lld_2_12_05_30E\packages\ti\sdo\edma3\drv\sample and C:\ti\edma3_lld_2_12_05_30E\packages\ti\sdo\edma3\rm\sample, as they contained several function definitions needed for the building of code. Finally, I was able to build the code without the error, but when I try executing it, the EDMA Iinitialization returns PASS, but the transfer is failed due to TIMEOUT error. While debugging, I noticed that functions for dma interrupts are not being called at all, therefore I thought that maybe I have a mistake in SPI configuration.
Am I initializing SPI and DMA correctly?
Parameters of SPI configuration structure:
Here is what I change from the parameters of SPI configuration structure:
And here is the function for EDMA init:
Here are all of the files imported in the project:
I will appreciate any help or comment. If needed, I can attach any of the files that I use.
Here is the main file:
/** * \file main_spi_flash_read_example.c * * \brief Example application main file. This application will read * the data from flash through spi interface. * */ #ifndef BARE_METAL /* XDCtools Header files */ #include <xdc/std.h> #include <xdc/cfg/global.h> #include <xdc/runtime/System.h> #include <stdio.h> #include <xdc/runtime/Error.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #endif /* SPI Header files */ #include <ti/drv/spi/SPI.h> #if defined(SOC_K2H) || defined(SOC_K2K) || defined(SOC_K2E) || defined(SOC_K2L) || defined(SOC_K2G) || defined(SOC_C6678) || defined(SOC_C6657) || defined(SOC_OMAPL137) || defined(SOC_OMAPL138) #include <ti/drv/spi/src/v0/SPI_v0.h> #endif #include <ti/drv/spi/soc/SPI_soc.h> #include <ti/drv/spi/test/src/SPI_log.h> #include <ti/drv/spi/test/src/SPI_test.h> /* GPIO Header files */ #include <ti/drv/gpio/GPIO.h> #include <ti/drv/gpio/soc/GPIO_v1.h> /* Board Header files */ #include <ti/board/board.h> #include <ti/board/src/flash/include/board_flash.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 /********************************************************************** ************************** Macros ************************************ **********************************************************************/ /********************************************************************** ************************** Internal functions ************************ **********************************************************************/ /********************************************************************** ************************** Global Variables ************************** **********************************************************************/ #ifdef SPI_DMA_ENABLE static EDMA3_RM_Handle MCSPIApp_edmaInit(void); #endif //Char myTaskStack[1024]; //Task_Struct myTaskStruct; bool loop = true; bool dmaMode = true; // PROMIJENITI U SLUCAJU NE KORISCENJA DMA //SPI_Handle spiHandle; //SPI_Params spiParams; //SPI_Transaction spiTransaction; /* * ======== Board_initSPI ======== */ void Board_initSPI(void) { Board_initCfg boardCfg; SPI_v0_HWAttrs spi_cfg; Board_SoCInfo socInfo; bool boardStatus; /* Get the default SPI init configurations */ SPI_socGetInitCfg(0, &spi_cfg); /* Update the SPI functional clock based on CPU clock*/ Board_getSoCInfo(&socInfo); if(socInfo.sysClock != BOARD_SYS_CLK_DEFAULT) { spi_cfg.inputClkFreq = socInfo.sysClock/SPI_MODULE_CLOCK_DIVIDER; } #ifdef SPI_DMA_ENABLE if (dmaMode == true) { /* Set the DMA related init config */ spi_cfg.edmaHandle = MCSPIApp_edmaInit(); spi_cfg.dmaMode = TRUE; spi_cfg.enableIntr = FALSE; } else #endif { spi_cfg.edmaHandle = NULL; spi_cfg.dmaMode = FALSE; } /* Set the default SPI init configurations */ SPI_socSetInitCfg(0, &spi_cfg); boardCfg = BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO; boardStatus = Board_init(boardCfg); if (boardStatus != BOARD_SOK) { printf("\nBoard not OK!\n"); } else{ printf("\nBoard OK!\n"); } } /* * ======== test function ======== */ #ifdef BARE_METAL void main() #else void spi_test(UArg arg0, UArg arg1) #endif { SPI_Handle spiHandle; SPI_Params spiParams; SPI_Transaction spiTransaction1; uint32_t xferEnable; uint32_t terminateXfer = 0; SPI_v0_HWAttrs const *hwAttrs = NULL; SPI_v0_Object *object = NULL; bool retVal; #ifdef BARE_METAL /* Call board init functions */ Board_initSPI(); #endif SPI_init(); SPI_Params_init(&spiParams); spiParams.frameFormat = SPI_POL1_PHA1;// for DAC //spiParams.frameFormat = SPI_POL0_PHA0; // for ADC spiParams.transferMode = SPI_MODE_BLOCKING; //spiParams.transferTimeout = SPI_WAIT_FOREVER; spiParams.transferTimeout = 1000; //spiParams.transferCallbackFxn = NULL; spiParams.mode = SPI_MASTER; spiParams.bitRate = 1000000000/18; spiParams.dataSize = 8; spiHandle = SPI_open(0, &spiParams); if (!spiHandle) { printf("\n SPI_open failed. \n"); } hwAttrs = (const SPI_v0_HWAttrs *)spiHandle->hwAttrs; object = (SPI_v0_Object*)spiHandle->object; // Definition of signal to be sent /* Enable transfer */ //terminateXfer = 0; xferEnable = 1; SPI_control(spiHandle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable); uint8_t transmitBuffer1[1]; uint8_t receiveBuffer[1]; transmitBuffer1[0] = (uint8_t)0x09; transmitBuffer1[1] = (uint8_t)0xff; transmitBuffer1[2] = (uint8_t)0xff; transmitBuffer1[3] = (uint8_t)0x09; transmitBuffer1[4] = (uint8_t)0x8b; transmitBuffer1[5] = (uint8_t)0xb7; spiTransaction1.txBuf = transmitBuffer1; spiTransaction1.rxBuf = NULL; spiTransaction1.count = 1; terminateXfer = 1; spiTransaction1.arg = (void *)&terminateXfer; #ifdef SPI_DMA_ENABLE if (dmaMode) { // CacheP_wb((void *)transmitBuffer1, (int32_t)1); // CacheP_wb((void *)receiveBuffer, (int32_t)1); } #endif #ifdef SPI_DMA_ENABLE if (dmaMode == true) { //CacheP_Inv((void *)receiveBuffer, (int32_t)1); } #endif while (loop) { retVal = SPI_transfer(spiHandle, &spiTransaction1); //retVal = SPI_transfer(spiHandle, &spiTransaction2); //retVal = SPI_transfer(spiHandle, &spiTransaction3); //retVal = SPI_transfer(spiHandle, &spiTransaction4); //transmitBuffer[0] = (uint8_t)0x0009; //transmitBuffer[1] = (uint8_t)0xFFFF; //transmitBuffer[2] = (uint8_t)0xFF; //spiTransaction.txBuf = transmitBuffer; //spiTransaction.rxBuf = NULL; //retVal = SPI_transfer(spiHandle, &spiTransaction); if (retVal == false){ printf("\nSPI transfer failed!\n");} //printf("%x",receiveBuffer[0]); if (retVal == true){ printf("\nSPI transfer completed!\n");} //printf("%x",receiveBuffer[0]); //printf("%d",receiveBuffer[0]); } /* Disable transfer */ xferEnable = 0; SPI_control(spiHandle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable); SPI_close(spiHandle); } /* * ======== main ======== */ #ifndef BARE_METAL int main(void){ System_printf("Start Setup\n"); /* Call board init functions */ Board_initSPI(); /* Configure task. */ //Task_Params taskParams; //Task_Params_init(&taskParams); //taskParams.stack = myTaskStack; //taskParams.stackSize = sizeof(myTaskStack); //Task_construct(&myTaskStruct, spi_test, &taskParams, NULL); System_printf("End Setup\n"); /* Start BIOS */ BIOS_start(); return (0); } #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; */ static EDMA3_RM_Handle MCSPIApp_edmaInit(void) { EDMA3_DRV_Result edmaResult = EDMA3_DRV_E_INVALID_PARAM; uint32_t edma3Id; if (gEdmaHandle != NULL) { return (gEdmaHandle); } edma3Id = 0; 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
Kind regards,
Dejana