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.

RTOS/PROCESSOR-SDK-AM335X: QSPI-McSPI device driver issue

Part Number: PROCESSOR-SDK-AM335X
Other Parts Discussed in Thread: AM3358

Tool/software: TI-RTOS

Hello Everyone,

I have a problem receiving SPI data very fast in short intervals on SYS/BIOS with PDK device driver "QSPI-MCSPI". I want to send 32*16bit values every 50 microseconds at 20 MHz. For performance optimization I tried to buffer the data via dma but as soon I make use of a memcpy to store the data in another buffer I do lose some data. I tried as well not to use dma but I didn't work out either. Do you know if there is a performance limit which is smaller than my requirement? If so, do you have other ideas using the beaglebone black with AM3358 chip? I would be nice to know the limit of the dma buffering as well.

EDIT: When i set the invervall to every 90 microseconds I get correct data from dma buffers. Every interval below 90 microseconds leads to dataloss at specific indices of the buffer (index: 0xF, 0x20, 0x40) which are all multiples of 16. My buffer type is "uint16_t". I tested the positive and the negative scenario several times with same results.

EDIT: As an overview I am sending data from a stm32 board using a chipselect line. It would be interesting to know if the dma or the spi module is the bottlleneck. The data corruption happens before only between dma packets. I tried different dma buffers from 64 to 2048 16bit values (128 to 4096 byte dma buffer size).

EDIT: I am 100 percent sure that the data loss happens between two dma packets. When I increase the buffer to 4096 bytes I get 4096 correct bytes but the next dma buffer doesn't receive the first databytes. Is there any way to increase the dma performance?

Regards

  • The RTOS team have been notified. They will respond here.
  • David,
    Will need to look into this and get back to you.

    Lali
  • Hello Lali,

    do you have any updates so far? Does it perhaps make sense to use a lower level of the SPI api for performance increase? My application is about to read spi data and send it out via ethernet. At the moment it is configured to received 64 16 bit values every 100 microseconds and send it out buffered every millisecond. Can you suggest anything for that application?

    EDIT: even with that configuration I get RX overflow and TX underflow Error on SPI .

    With kind regards

    David

  • David,

    Do you have the SPI_DMA_ENABLE compilation flag set on your project?
    Which processor SDK example did you start your project on?

    Lali

  • Hello Lali,

    SPI DMA is activated and the system works in general with dma but not at the transmission speed I need to use and explained in my last post. Probably it is not possible to use the SPI library with DMA for my scenario, but I don't know how to use SPI and DMA without that library yet. To answer your question, I used the "mcspi_slavemode" project as reference. Does it make sense to start at a lower layer to improve spi dma performance? If so, do you have any hints for me on how to do that?

    UPDATE: Perhaps there is a functionality for improving the overall system by directly putting received data into the ethernet transmit buffer. In general my application should only forward received spi data via ethernet tcp/udp to the pc. Do you have any hints for that or can you suggest any papers which give some explanations?

    With kind regards

    David

  • David,

    Apologies for the slow reply. Was checking with some colleagues internally.
    What is the TX/RX FIFO threshold size you are using?
    Does sending 2 back-back 4096 byte packets cause the same problem?

    Lali
  • Hi Lali,

    1. I tried several different configurations and I tried to fullfill all the requirements described in the am335x user manual. I aligned the buffers to 256 bit and I set the FIFO TX and RX size to 16 at the moment but I also tried to set it to 32 or even 256. If it makes sense I can increase or decresae the buffer size. I just has to be in range of 256 to 8192 bytes.
    2.What do you mean with sending back-back 4096 byte packets?

    Update 1: Does it make sense to enable turbo mode for performance increase?

    Update 2: I analyzed the PDK spi driver and when using dma I could see that much configuration is done everytime I call the SPI_Transfer function. Is there a way to avoid that configuration to increase performance?

    Extract:

    static void MCSPI_DMA_primeTransfer_v1(MCSPI_Handle     mcHandle,
                                           SPI_Transaction *transaction)
    {
        SPI_Handle            handle;
        SPI_v1_Object        *object;
        SPI_v1_chObject      *chObj;
        uint32_t              chNum;
        SPI_v1_HWAttrs const *hwAttrs;
        EDMA3_DRV_PaRAMRegs   rxParamSet = {0};
        EDMA3_DRV_PaRAMRegs   txParamSet = {0};
        EDMA3_DRV_PaRAMRegs   dummyParamSet = {0};
    
        /* Input parameter validation */
        OSAL_Assert(!((mcHandle != NULL) && (transaction != NULL)));
    
        /* Get the pointer to the object and hwAttrs */
        handle  = mcHandle->handle;
        chNum   = mcHandle->chnNum;
        object  = (SPI_v1_Object*)handle->object;
        chObj   = &(object->chObject[chNum]);
        hwAttrs = (SPI_v1_HWAttrs*)handle->hwAttrs;
    
        /* setup transfer mode and FIFO trigger levels */
        MCSPI_xferSetup_v1(mcHandle, transaction);
    
        /* receive parameter set */
        EDMA3_DRV_getPaRAM((EDMA3_DRV_Handle)hwAttrs->edmaHandle,
                            hwAttrs->rxDmaEventNumber,
                            &rxParamSet);
    
        /* transmit parameter set */
        EDMA3_DRV_getPaRAM((EDMA3_DRV_Handle)hwAttrs->edmaHandle,
                            hwAttrs->txDmaEventNumber,
                            &txParamSet);
    
        /* Update param sets based on the transaction parameters */
        MCSPI_DMA_localEdmaUpdateParams_v1(mcHandle,
                                           transaction,
                                           &rxParamSet,
                                           &txParamSet);
    
        /* Dummy paramSet Configuration */
        EDMA3_DRV_getPaRAM(hwAttrs->edmaHandle,
                           EDMA3_DRV_LINK_CHANNEL,
                           &dummyParamSet);
    
        dummyParamSet.aCnt     = (uint16_t)MCSPI_EDMA3CC_PARAM_ACNT;
        dummyParamSet.linkAddr = MCSPI_EDMA3CC_PARAM_LINK_ADDRESS;
        dummyParamSet.opt     &= ~((uint32_t)0x01U << MCSPI_EDMA3CC_OPT_STATIC_SHIFT);
    
        /* Now, write the PaRAM Set. */
        EDMA3_DRV_setPaRAM(hwAttrs->edmaHandle,
                           EDMA3_DRV_LINK_CHANNEL,
                           &dummyParamSet);
    
        /* Write Rx param set */
        EDMA3_DRV_setPaRAM((EDMA3_DRV_Handle)(hwAttrs->edmaHandle),
                            hwAttrs->rxDmaEventNumber,
                            &rxParamSet);
    
        /* Write Tx param set */
        EDMA3_DRV_setPaRAM((EDMA3_DRV_Handle)(hwAttrs->edmaHandle),
                           hwAttrs->txDmaEventNumber,
                           &txParamSet);
    
        /* Link the Dummy paramset */
        EDMA3_DRV_linkChannel(hwAttrs->edmaHandle,
                              hwAttrs->txDmaEventNumber,
                              EDMA3_DRV_LINK_CHANNEL);
    
        /* Program the RX side */
        EDMA3_DRV_enableTransfer(hwAttrs->edmaHandle,
                                 hwAttrs->rxDmaEventNumber,
                                 EDMA3_DRV_TRIG_MODE_EVENT);
    
        /* Program the TX side */
        EDMA3_DRV_enableTransfer(hwAttrs->edmaHandle,
                                 hwAttrs->txDmaEventNumber,
                                 EDMA3_DRV_TRIG_MODE_EVENT);
    
        /* Enable McSPI DMA for transaction
         * MCSPI_CH(chNum)CONF -> DMAR bit for receive DMA
         */
        McSPIDMAEnable((uint32_t)(hwAttrs->baseAddr),
                       ((uint32_t)MCSPI_DMA_RX_EVENT |
                        (uint32_t)MCSPI_DMA_TX_EVENT),
                       chNum);
    
        /* Enable the channel */
        McSPIChannelEnable((uint32_t)(hwAttrs->baseAddr), chNum);
    
        if ((SPI_MASTER == chObj->spiParams.mode) &&
            (hwAttrs->chMode == MCSPI_SINGLE_CH))
        {
            /* Assert chip select signal */
            McSPICSAssert((uint32_t)(hwAttrs->baseAddr), chNum);
        }
    
    }



    regards,

    David

  • David,

    The maximum SPI FIFO size is 32 bytes, in duplex mode, it is recommended to set both the TX and RX FIFO size. It seems that you are using half duplex mode (?) sending data only.

    You could try to set the mode to be TX only half duplex. Set the TX FIFO size to 32 and RX FIFO to 0. See if that helps.

    Please ignore my the back-back comment.

    Lali
  • Hi Lali,

    it is completely the other way round I only receive data via spi. I redirect the received data then via ethernet to a computer. I already tried to set TX FIFO size to 0 and RX FIFO size to 32/16.

    regards,

    David
  • Hi Lali,

    I tried to use the spi dma with csl driver now but I still get the RX_OVERFLOW set. After it is set I can't receive data anymore.

    /* Include all the necessary header files */
    #include "stdint.h"
    #include "mcspi.h"
    #include "hw_mcspi.h"
    #include "edma_event.h"
    #include "soc_AM335x.h"
    #include "evmAM335x.h"
    #include "interrupt.h"
    #include "hw_types.h"
    
    #include "error.h"
    #include "edma.h"
    
    /*****************************************************************************/
    /*                      INTERNAL MACRO DEFINITIONS                           */
    /*****************************************************************************/
    //#define MCSPI_TX_EVENT                  (EDMA3_CHA_MCSPI0_CH0_TX)
    //#define MCSPI_RX_EVENT                  (EDMA3_CHA_MCSPI0_CH0_RX)
    #define MCSPI_TX_EVENT                  (EDMA3_CHA_MCSPI1_CH0_TX)
    #define MCSPI_RX_EVENT                  (EDMA3_CHA_MCSPI1_CH0_RX)
    //#define MCSPI_TX0_REG                   (0x48130138u)
    #define MCSPI_TX0_REG                   (0x481A0138u)
    //#define MCSPI_RX0_REG                   (0x4803013Cu)
    #define MCSPI_RX0_REG                   (0x481A013Cu)
    #define MCSPI_IN_CLK                    (48000000u)
    #define MCSPI_OUT_FREQ                  (24000000u)
    #define MCSPI_CH_NUM                    (0u)
    #define EVT_QUEQUE_NUM                  (0u)
    #define DUMMY_CH_NUM                    (5u)
    #define MCSPISLV_MCSPI_REGS             SOC_SPI_1_REGS
    #define MCSPI_CH_ZERO                           (0u)
    
    #define FIFORX                          DATALENGTH/2
    #define DATALENGTH                      32
    #define FDAAENABLE                      (1u)
    
    
    
    #define MCSPI_SIDLEMODE_NO            ((uint32_t) MCSPI_SYSCONFIG_SIDLEMODE_NO \
                                           << MCSPI_SYSCONFIG_SIDLEMODE_SHIFT)
    
        EDMA3CCPaRAMEntry paramSet;
    /*****************************************************************************/
    /*                      LOCAL FUNCTION PROTOTYPES                            */
    /*****************************************************************************/
    static void McSpiTxEdmaParamSet(unsigned int tccNum, unsigned int chNum,
                                    volatile unsigned char *buffer,
                                    unsigned short buffLength);
    static void McSpiRxEdmaParamSet(unsigned int tccNum, unsigned int chNum,
                                    volatile unsigned char *buffer,
                                    unsigned short buffLength,
                                    unsigned int destBidxFlag);
    static void CallBack(unsigned int tccNum, unsigned int status);
    static void McSPITransfer(unsigned short length);
    static void TxDummyPaRAMConfEnable(void);
    static void Edma3ErrorHandlerIsr(void);
    static void Edma3ComplHandlerIsr(void);
    static void RequestEDMA3Channels(void);
    static void EDMA3AINTCConfigure(void);
    static void EDMA3Initialize(void);
    static void McSPISetUp(void);
    
    static void testSPIEdma();
    
    /*****************************************************************************/
    /*                         GLOBAL VARIABLES                                  */
    /*****************************************************************************/
    static void (*cb_Fxn[EDMA3_NUM_TCC])(unsigned int tcc, unsigned int status);
    
    uint16_t rxBuffer[8192] __attribute__ ((aligned (256)));
    
    uint16_t* rxBufferPtr = rxBuffer;
    volatile unsigned char vrfyData[256];
    volatile unsigned char flagTx = 0;
    volatile unsigned char flagRx = 0;
    static uint8_t myCount = 0;
    
    /*****************************************************************************/
    /*                       LOCAL FUNCTION DEFINITIONS                          */
    /*****************************************************************************/
    
    /*
     ** Main Function.
     */
    int main(void)
    {
        testSPIEdma();
        while (1)
        {
    
        }
    }
    
    static void testSPIEdma()
    {
        /* Enable the clocks for McSPI1 module.*/
        McSPI1ModuleClkConfig();
        /* Perform Pin-Muxing for SPI1 Instance.*/
        McSPI1PinMuxSetup();
        /* Initialize the EDMA3 instance.*/
        EDMA3Initialize();
        /* Request EDMA3CC for Tx and Rx channels for SPI1. */
        RequestEDMA3Channels();
        /* Set up the McSPI instance.*/
        McSPISetUp();
        cb_Fxn[MCSPI_RX_EVENT] = &CallBack;
        /* Configure the write enable parameters for Edma receive.*/
        McSpiRxEdmaParamSet(MCSPI_RX_EVENT, MCSPI_RX_EVENT, rxBuffer, DATALENGTH, TRUE);
        EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT, &paramSet);
            /* EDMA3 Transfer is Enabled.*/
        EDMA3ClrMissEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
        EDMA3EnableDmaEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
        McSPITransfer(DATALENGTH);
    }
    
    /*
     ** This function configures the power supply for EDMA3 Channel Controller 0
     ** and Transfer Controller 0, registers the EDMA interrupts in AINTC.
     */
    static void EDMA3Initialize(void)
    {
        /* Enable module clock for EDMA */
        EDMAModuleClkConfig();
    
        /* Initialization of EDMA3 */
        EDMA3Init(SOC_EDMA30CC_0_REGS, EVT_QUEQUE_NUM);
    
        /* Configuring the AINTC to receive EDMA3 Interrupts */
        EDMA3AINTCConfigure();
    }
    
    /*
     ** This function will Assert the Chip select line before transmission, will
     ** enable the Edma events for Tx/Rx of McSPI peripheral, will De-assert the
     ** Chip select once communication is complete.
     */
    static void McSPITransfer(unsigned short length)
    {
        /* Set the word count field with the data length to be transferred.*/
        McSPIWordCountSet(SOC_SPI_1_REGS, length);
    
        /* Enable the Tx/Rx DMA events for McSPI. */
        McSPIDMAEnable(SOC_SPI_1_REGS, (MCSPI_DMA_RX_EVENT),
        MCSPI_CH_NUM);
    
        /* Enable the McSPI channel for communication.*/
        McSPIChannelEnable(SOC_SPI_1_REGS, MCSPI_CH_NUM);
    
        /* Wait for control to return from ISR.*/
    //    while (flagRx == 0)
    //        ;
    //
    //    flagTx = 0;
    //    flagRx = 0;
    //
    //    /* Disable the McSPI channel for communication.*/
    //    McSPIChannelDisable(SOC_SPI_1_REGS, MCSPI_CH_NUM);
    }
    
    /*
     ** EDMA3 completion Interrupt Service Routine(ISR).
     */
    static void Edma3ComplHandlerIsr(void)
    {
        unsigned int pendingIrqs;
        unsigned int isIPR = 0;
        unsigned int indexl;
        unsigned int Cnt = 0;
    
        indexl = 1;
        EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
        (*cb_Fxn[MCSPI_RX_EVENT])(MCSPI_RX_EVENT, EDMA3_XFER_COMPLETE);
    }
    
    /* EDMA3 Error Handler */
    static void Edma3ErrorHandlerIsr(void)
    {
        EDMA3ClrMissEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
    
        /* Disable McSPI Receive event */
        McSPIDMADisable(SOC_SPI_1_REGS, MCSPI_DMA_RX_EVENT, MCSPI_CH_NUM);
    
        /* Disable Edma Transfer */
        EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT,
        EDMA3_TRIG_MODE_EVENT);
    
        flagRx = 1;
    
    }
    
    /*
     ** Call back function. Here we disable the Tx/Rx DMA events of McSPI
     ** peripheral.
     */
    static void CallBack(unsigned int tccNum, unsigned int status)
    {
    
        if (tccNum == MCSPI_RX_EVENT)
        {
            flagRx = 1;
            //McSPIDMADisable(SOC_SPI_1_REGS, MCSPI_DMA_RX_EVENT, MCSPI_CH_NUM);
            //McSPIChannelDisable(SOC_SPI_1_REGS, MCSPI_CH_NUM);
            rxBufferPtr+=DATALENGTH;
            //McSpiRxEdmaParamSet(MCSPI_RX_EVENT, MCSPI_RX_EVENT, rxBufferPtr, DATALENGTH, TRUE);
            paramSet.destAddr = (unsigned int) rxBufferPtr;
            EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT, &paramSet);
            EDMA3ClrMissEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
            EDMA3EnableDmaEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
            McSPIWordCountSet(SOC_SPI_1_REGS, DATALENGTH);
    
            //McSPIDMAEnable(SOC_SPI_1_REGS, MCSPI_DMA_RX_EVENT, MCSPI_CH_NUM);
            //McSPIChannelEnable(SOC_SPI_1_REGS, MCSPI_CH_NUM);
            /* Disable McSPI Receive event */
            //McSPIDMADisable(SOC_SPI_1_REGS, MCSPI_DMA_RX_EVENT, MCSPI_CH_NUM);
        }
    }
    
    /*
     ** This function is used to set the PaRAM entries of EDMA3 for the Receive
     ** event of channel 0 of McSPI0 instance. The corresponding EDMA3 channel
     ** is also enabled for reception.
     */
    static void McSpiRxEdmaParamSet(unsigned int tccNum, unsigned int chNum,
                                    volatile unsigned char *buffer,
                                    unsigned short buffLength,
                                    unsigned int destBidxFlag)
    {
    
    
        unsigned char *p = (unsigned char *) &paramSet;
        unsigned int index = 0;
    
        /* Clean-up the contents of structure variable. */
        for (index = 0; index < sizeof(paramSet); index++)
        {
            p[index] = 0;
        }
    
        /* Fill the PaRAM Set with Receive specific information.*/
    
        /* srcAddr holds address of SPI Rx FIFO.*/
        paramSet.srcAddr = (unsigned int) (MCSPI_RX0_REG);
    
        /* destAddr is address of memory location named buffer.*/
        paramSet.destAddr = (unsigned int) buffer;
    
        /* aCnt holds the number of bytes in an array.*/
        paramSet.aCnt = 2;
    
        /* bCnt holds the number of such arrays to be transferred.*/
        paramSet.bCnt = FIFORX >> 1;
    
        /* cCnt holds the number of frames of aCnt*bBcnt bytes to be transferred.*/
        paramSet.cCnt = DATALENGTH / paramSet.bCnt;
    
        /* 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 = paramSet.aCnt;
        }
        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;
        /*TODO: rxtrig or 0*/
        paramSet.destCIdx = FIFORX;
    
        /* Linking transfers in EDMA3 are not used.*/
        paramSet.linkAddr = 0xFFFF;
    
        paramSet.bCntReload = paramSet.bCnt;
    
        paramSet.opt &= 0xFFFFFFFCU;
        paramSet.opt &= 0xFFFFF8FFU;
        paramSet.opt |= 0x4U;
        paramSet.opt &= (~EDMA3CC_OPT_TCC);
        /* Set TCC field in OPT with the tccNum.*/
        paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    
    
        /* EDMA3 Interrupt is enabled and Intermediate Interrupt Disabled.*/
        paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
    
    }
    
    /*
     ** 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(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, \
    //                        MCSPI_TX_EVENT, MCSPI_TX_EVENT, EVT_QUEQUE_NUM);
        /* Request DMA Channel and TCC for SPI Receive*/
        EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
        MCSPI_RX_EVENT,
                            MCSPI_RX_EVENT, EVT_QUEQUE_NUM);
    }
    
    /*
     ** This function will call the necessary McSPI APIs which will configure the
     ** McSPI controller.
     */
    static void McSPISetUp(void)
    {
        /* Reset the McSPI instance.*/
        McSPIReset(SOC_SPI_1_REGS);
    
        MCSPISysConfigSetup(SOC_SPI_1_REGS, MCSPI_CLOCKS_OCP_ON_FUNC_ON,
        MCSPI_SIDLEMODE_NO,
                            MCSPI_WAKEUP_DISABLE,
                            MCSPI_AUTOIDLE_OFF);
        /* Enable chip select pin.*/
        McSPICSEnable(SOC_SPI_1_REGS);
    
        /* Enable master mode of operation.*/
        /*Slave mode enable*/
        //McSPIMasterModeEnable(SOC_SPI_1_REGS);
        McSPISlaveModeEnable(SOC_SPI_1_REGS);
        McSPIFIFODatManagementConfig(SOC_SPI_1_REGS, FDAAENABLE);
        /* Perform the necessary configuration for master mode.*/
        MCSPIPinDirSet(SOC_SPI_1_REGS, MCSPI_RX_ONLY_MODE,
                       MCSPI_DATA_LINE_COMM_MODE_7, 0);
    
        McSPITurboModeEnable(SOC_SPI_1_REGS, MCSPI_CH_NUM);
        /* Configure the McSPI output frequency. */
        McSPIClkConfig(SOC_SPI_1_REGS, MCSPI_IN_CLK, MCSPI_OUT_FREQ,
        MCSPI_CH_NUM,
                       MCSPI_CLK_MODE_0);
    
        /* Configure the word length.*/
        McSPIWordLengthSet(SOC_SPI_1_REGS, MCSPI_WORD_LENGTH(16), MCSPI_CH_NUM);
    
        /* Set polarity of SPIEN to low.*/
        McSPICSPolarityConfig(SOC_SPI_1_REGS, MCSPI_CS_POL_LOW, MCSPI_CH_NUM);
    
        /* Enable the Tx FIFO of McSPI.*/
        McSPITxFIFOConfig(SOC_SPI_1_REGS, MCSPI_TX_FIFO_DISABLE, MCSPI_CH_NUM);
    
        /* Enable the Rx FIFO of McSPI.*/
        McSPIRxFIFOConfig(SOC_SPI_1_REGS, MCSPI_RX_FIFO_ENABLE, MCSPI_CH_NUM);
    
        McSPIFIFOTrigLvlSet(SOC_SPI_1_REGS, FIFORX, 0, MCSPI_RX_ONLY_MODE);
    }
    
    /*
     ** This function configures the AINTC to receive EDMA3 interrupts.
     */
    static void EDMA3AINTCConfigure(void)
    {
        /* Enable IRQ in CPSR.*/
        IntMasterIRQEnable();
        /* Initializing the ARM Interrupt Controller. */
        IntAINTCInit();
    
        /* Registering EDMA3 Channel Controller 0 transfer completion interrupt.  */
        IntRegister(SYS_INT_EDMACOMPINT, Edma3ComplHandlerIsr);
    
        /* Setting the priority for EDMA3CC0 completion interrupt in AINTC. */
        IntPrioritySet(SYS_INT_EDMACOMPINT, 0, AINTC_HOSTINT_ROUTE_IRQ);
    
        /* Enabling the EDMA3CC0 completion interrupt in AINTC. */
        IntSystemEnable(SYS_INT_EDMACOMPINT);
    
        /* Registering EDMA3 Channel Controller 0 Error Interrupt. */
        IntRegister(SYS_INT_EDMAERRINT, Edma3ErrorHandlerIsr);
    
        /* Setting the priority for EDMA3CC0 Error interrupt in AINTC. */
        IntPrioritySet(SYS_INT_EDMAERRINT, 0, AINTC_HOSTINT_ROUTE_IRQ);
    
        /* Enabling the EDMA3CC0 Error interrupt in AINTC. */
        IntSystemEnable(SYS_INT_EDMAERRINT);
    }
    
    /*
     ** This configures the PaRAM set for the Dummy Transfer.
     */
    static void TxDummyPaRAMConfEnable(void)
    {
        EDMA3CCPaRAMEntry dummyPaRAMSet;
    
        EDMA3GetPaRAM(SOC_EDMA30CC_0_REGS, 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(SOC_EDMA30CC_0_REGS, DUMMY_CH_NUM, &dummyPaRAMSet);
    }
    
    

    Do you have any updates?

  • I implemented SPI DMA on baremetal starterware basis and I got it working now. I tested to receive millions of data as a slave with 24MHz master clock and it seems to work. I still get the RX_OVERFLOW register flag set, but I do ignore that now because I didn't lose any data. It would be nice if you extend the MCSPI driver to allow higher throughput by adding a SPIDMA transfer function which doesn't completely close the driver. In my callback function I only do this to restart transfer.

    static void CallBack(unsigned int tccNum, unsigned int status)
    {

    if (tccNum == MCSPI_RX_EVENT)
    {
    flagRx = 1;
    rxBufferPtr+=DATALENGTH;
    paramSet.destAddr = (unsigned int) rxBufferPtr;
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT, &paramSet);
    EDMA3ClrMissEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
    EDMA3EnableDmaEvt(SOC_EDMA30CC_0_REGS, MCSPI_RX_EVENT);
    McSPIWordCountSet(SOC_SPI_1_REGS, DATALENGTH);
    }
    }