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.

TMS320C6745: SPI and MCASP

Part Number: TMS320C6745

Using pdk 1_0_10.

The SPI driver has some huge limitation.

If used without DMA and in SPI_MODE_BLOCKING modality; the driver disable all the interrupts during the transaction.

/* Check if a transfer is in progress */
key = SPI_osalHardwareIntDisable();
if (object->transaction) {
SPI_osalHardwareIntRestore(key);
/* Transfer is in progress */
transaction->status=SPI_TRANSFER_CANCELED;
ret = (bool)false;
}
else {
/* Save the pointer to the transaction */
object->transaction = transaction;

/* Acquire the lock for this particular SPI handle */
SPI_osalPendLock(object->mutex, SemaphoreP_WAIT_FOREVER);

SPI_primeTransfer_v0(handle, transaction);

SPI_osalHardwareIntRestore(key);


If the transaction is long (for example reading 50K on an external SPI memory), other driver based on interrupt fails (for example an uart receiving a packet bigger than the fifo).

It get worse if i use other configurations (DMA or SPI_MODE_CALLBACK), in these cases the MCASP (implemented as in the sample of the pdk) totally stops the activity.

I think there is something related to interrupt configuration, but I can't see any releation beetween SPI in mode callback (or DMA) and mcASP... it simply it doesn't work

All the configuration of interrupt, events, edma are defaulted by the driver.

In the configuration there is:

ECM.eventGroupHwiNum[0] = 7;
ECM.eventGroupHwiNum[1] = 8;
ECM.eventGroupHwiNum[2] = 9;
ECM.eventGroupHwiNum[3] = 10;

  • Other info:

    if the driver SPI_v0 is modified commenting the interrupt enabling/disabling (i can do it because in SPI_OPER_MODE_POLLING no interrupt related function is used) also SPI works, Uart works, MCASP STOPS!!!!

    How it is possible?  

  • Another info:

    With all driver unchanged and SPI at default parameter, tried to split a single huge SPI_transfer in more  small transfer (a cycle of SPI_transfer with transaction.arg = (void *)&terminateXfer = 0).

    SPI works, McASP stops.

    When i say "stop" i intend no callback from EDMA3 linked to Mcasp (as the sample application: audioSample_io.c). The McASP runs in a separated thread at higher priority.

    • Is there a reason that you suspect MCASP stopping is related to the SPI HW interrupt disable ? Was McASP working when you didn`t comment out the code?
    • What is the nature of MCASP Errors reported when the MCASP stops.
    • Can you please provide the BIOS configuration, MCASP, UART, SPI SOC files and configuration details.
    • Are the SPI and MCASP events going to the same DSP Interrupt or are they connect to different interrupts.
    • I would recommend not using SPI in blocking mode. Can you change this to use CALL_BACK mode instead.

     

  • 1) What i see is that with SPI in SPI_MODE_BLOCKING  the McASP is working, with dma enabled or using callback the mcasp stops on the first transaction of the SPI

    2) I don't see any error on McASP, what get that is that "mcaspAppCallback" isn't called anynore (see audioSample_io.c to know what i'm speackin of). I don't know if there is some option to increase the "verbosity" of the driver.

    3)  Configuration and cfg has been provided, i can provide all the project but i prefer in a private way

    4) Interrupts and events are masked to me, what is see is that all the drivers are managed by the event combiner, but is all hidden by the driver in the pdk

    5) I prefer use callback and DMA on SPI, if there is a way to get them working.

    5633.app.cfg

    void InitAllUart()
    {
        UART_HwAttrs uart_cfg;
    
        memset((void*)&MyUart,0,sizeof(T_MyUart));
    
        UART_init();
    
         /* Get the default UART init configurations */
         UART_socGetInitCfg(CMD_UART, &uart_cfg);
    
         /* Set the DMA enabled UART init configurations */
         UART_socSetInitCfg(0, &uart_cfg);
    
         UART_Params_init(&uartParams);
         uartParams.parityType = UART_PAR_EVEN;
    
        uartParams.readMode = UART_MODE_CALLBACK;
        uartParams.writeMode = UART_MODE_CALLBACK;
        uartParams.readCallback = UART_callbackRead;
        uartParams.writeCallback = UART_callbackWrite;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_ZERO;
    
    
        uart = UART_open(CMD_UART, &uartParams);
    }
    
    //---------------------------------------------------------------------------------------------------------------------------
    
    void NorSpiInit(void)
    {
        SPI_Params      spiParams; /* SPI params structure */
        SPI_v0_HWAttrs spi_cfg;
        uint32_t        xferEnable= 1;
    
        /* Get the default UART init configurations */
        SPI_socGetInitCfg(SPI_FLASH_INSTANC, &spi_cfg);
    
        spi_cfg.enableIntr = false;
    
        SPI_socSetInitCfg(SPI_FLASH_INSTANC, &spi_cfg);
    
        SPI_Params_init(&spiParams);
    
        spiParams.frameFormat=SPI_POL0_PHA1;
        spiParams.bitRate=32*1024*1024;
    
        /* Init SPI driver */
        SPI_init();
    
        NorSPIHandle = (SPI_Handle)SPI_open(SPI_FLASH_INSTANC, &spiParams);
    
        xferEnable = 1;
        SPI_control(NorSPIHandle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable);
    
        GateSPI = GateTask_create(NULL, NULL);
    }
    
    //-----------------------------------------------------------------------------------------------------------------------------
    
    //--------------------------------------------------------------------------
    ///@brief Rx definitions for McASP
    //--------------------------------------------------------------------------/*
    Mcasp_HwSetupData mcaspRcvSetup =
        {
            /* .rmask    = */ 0xFFFFFFFF,   /* All the data bits are to be used     */
            /* .rfmt     = */ 0x00008070,   /* 0/1 bit delay from framsync
                                             * MSB first
                                             * No extra bit padding
                                             * Padding bit (ignore)
                                             * slot Size is 16
                                             * Reads from DMA port
                                             * NO rotation
                                             */
    
            /* .afsrctl  = */ 0x00000202,    /* 4 TDM mode,
                                              * Frame sync is one bit
                                              * internally generated frame sync
                                              * Rising edge is start of frame
                                              */
    
            /* .rtdm     = */ 0x0000000F,    /* slot 1-2-3-4 is active (DSP)
                                              *              */
            /* .rintctl  = */ 0x00000003,    /* sync error and overrun error         */
            /* .rstat    = */ 0x000001FF,    /* reset any existing status bits       */
            /* .revtctl  = */ 0x00000000,    /* DMA request is enabled or disabled   */
                {
                /* .aclkrctl  = */ 0x00000025,  // 0x15 - HCLK/6 = 2000kbit -> 31250 sample/rate a 16 bit * 4 tracce
                /* .ahclkrctl = */ 0x00008001,  // AuxCLK/2 = 12.000.000
                /* .rclkchk   = */ 0x00000000
                }
    } ;
    
    //--------------------------------------------------------------------------
    ///@brief Rx definitions for McASP
    //--------------------------------------------------------------------------/*
    Mcasp_HwSetupData mcaspXmtSetup =
        {
            /* .xmask    = */ 0xFFFFFFFF,   /* All the data bits are to be used     */
            /* .xfmt     = */ 0x00008070,   /*
                                             * 0/1 bit delay from framsync
                                             * MSB first
                                             * No extra bit padding
                                             * Padding bit (ignore)
                                             * slot Size is 16
                                             * Reads from DMA port
                                             * 0-bit rotation
                                             */
            /* .afsxctl  = */ 0x00000002,   /* burst mode,
                                             * Frame sync is one bit
                                             * Internally generated frame sync
                                             * Rising edge is start of frame
                                             */
            /* .xtdm     = */ 0x00000001,   /* slot 1 is active (DSP) */
            /* .xintctl  = */ 0x00000003,   /* sync error,overrun error,clK error   */
            /* .xstat    = */ 0x000001FF,   /* reset any existing status bits       */
            /* .xevtctl  = */ 0x00000000,   /* DMA request is enabled or disabled   */
                {
                /* .aclkxctl  = */ 0x00000077,  // HCLK/24 = 500kbit -> 31250 sample/rate a 16 bit
                /* .ahclkxctl = */ 0x00008001,  // AuxCLK/2 = 12.000.000
                /* .xclkchk   = */ 0x00000000
            },
    };
    
    /* McAsp channel parameters                                  */
    Mcasp_ChanParams  mcasp_chanparam[2]=
    {
        {
            RX_NUM_SERIALIZER,                                          /* number of serialisers      */
            {Mcasp_SerializerNum_0,Mcasp_SerializerNum_10 },            /* serialiser index           */
            &mcaspRcvSetup,
            TRUE,                                                       /* isDMaDriver                */
            Mcasp_OpMode_TDM,                                           /* Mode (TDM/DIT)             */
            Mcasp_WordLength_16,
            NULL,
            0,
            NULL,
            (Mcasp_GblCallback)&GblErrRcv,
            RX_NUM_SLOT,                                                // number of channels
            Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1,
            TRUE,
            RX_FIFO_EVENT_DMA_RATIO,
            TRUE,
            Mcasp_WordBitsSelect_MSB
        },
        {
            TX_NUM_SERIALIZER,                   /* number of serialisers       */
            {Mcasp_SerializerNum_1,Mcasp_SerializerNum_2,Mcasp_SerializerNum_3,Mcasp_SerializerNum_4,Mcasp_SerializerNum_5,Mcasp_SerializerNum_6,Mcasp_SerializerNum_7,Mcasp_SerializerNum_8},
            &mcaspXmtSetup,
            TRUE,
            Mcasp_OpMode_TDM,
            Mcasp_WordLength_16,                 /* word width                  */
            NULL,
            0,
            NULL,
            (Mcasp_GblCallback)&GblErrXmt,
            1,
            //Mcasp_BufferFormat_1SER_1SLOT,
            Mcasp_BufferFormat_MULTISER_1SLOT_SER_NON_INTERLEAVED,
            TRUE,
            TX_FIFO_EVENT_DMA_RATIO,
            TRUE,                                // IsDataPacket
            Mcasp_WordBitsSelect_MSB
        }
    };
    
    void McaspDriverInit(void)
    {
        Int i;
    
        for (i = 0; i < (int32_t)MCASP_CNT; i++)
            {
                /* have to initialize  ally */
                Mcasp_module.inUse[i] = (Bool)0;/* FALSE; */
                memset((void *)&Mcasp_Instances[i], 0x0, sizeof(Mcasp_Object));
    
                Mcasp_module.isrObject[i].isIsrRegistered[0] = (Bool)0;/* FALSE; */
                Mcasp_module.isrObject[i].isIsrRegistered[1] = (Bool)0;/* FALSE; */
                Mcasp_module.isrObject[i].chanEnabled[0] = (Bool)0;/* FALSE; */
                Mcasp_module.isrObject[i].chanEnabled[1] = (Bool)0;/* FALSE; */
                Mcasp_module.isrObject[i].instHandle = 0;/* NULL; */
                Mcasp_module.isrObject[i].isrSwiTaskHandle = 0;/* NULL; */
    
                if (i == 0)
                {
                    Mcasp_deviceInstInfo[i].ditSupport = (Bool)0;/* FALSE; */
                    Mcasp_deviceInstInfo[i].baseAddress =
                        (CSL_McaspRegs *)CSL_MCASP_0_CFG_REGS;
                    Mcasp_deviceInstInfo[i].fifoAddress =
                        (CSL_AfifoRegs *)CSL_MCASP_0_FIFO_CFG_REGS;
                    Mcasp_deviceInstInfo[i].dataAddress =
                        (CSL_AdataRegs *)CSL_MCASP_0_SLV_REGS;
                    Mcasp_deviceInstInfo[i].numSerializers = 16u;
                    Mcasp_deviceInstInfo[i].rxDmaEventNumber =
                        (uint32_t)CSL_EDMA3_CHA_MCASP0_RX;
                    Mcasp_deviceInstInfo[i].txDmaEventNumber =
                        (uint32_t)CSL_EDMA3_CHA_MCASP0_TX;
        #ifndef BIOS_PWRM_ENABLE
                    Mcasp_deviceInstInfo[i].pwrmLpscId = (Uint32)7;
        #else
                    Mcasp_deviceInstInfo[i].pwrmLpscId =
                        (uint32_t)CSL_LPSC_NUMBER_MCASP_0;
        #endif
                    Mcasp_deviceInstInfo[i].pscInstance =
                       1;
    
                }
    
                else if (i == 1)
                {
                    Mcasp_deviceInstInfo[i].ditSupport = (Bool)0;/* FALSE; */
                    Mcasp_deviceInstInfo[i].baseAddress =
                        (CSL_McaspRegs *)CSL_MCASP_1_CFG_REGS;
                    Mcasp_deviceInstInfo[i].fifoAddress =
                        (CSL_AfifoRegs *)CSL_MCASP_1_FIFO_CFG_REGS;
                    Mcasp_deviceInstInfo[i].dataAddress =
                        (CSL_AdataRegs *)CSL_MCASP_1_SLV_REGS;
    
                    Mcasp_deviceInstInfo[i].numSerializers = 12u;
                    Mcasp_deviceInstInfo[i].rxDmaEventNumber =
                        (uint32_t)CSL_EDMA3_CHA_MCASP1_RX;
                    Mcasp_deviceInstInfo[i].txDmaEventNumber =
                        (uint32_t)CSL_EDMA3_CHA_MCASP1_TX;
        #ifndef BIOS_PWRM_ENABLE
                    Mcasp_deviceInstInfo[i].pwrmLpscId = (Uint32)8;
        #else
                    Mcasp_deviceInstInfo[i].pwrmLpscId =
                        (uint32_t)CSL_LPSC_NUMBER_MCASP_1;
        #endif
                    Mcasp_deviceInstInfo[i].pscInstance = 1;
    
                }
    
                else if (i == 2)
                {
                    Mcasp_deviceInstInfo[i].ditSupport = (Bool)0;
                    Mcasp_deviceInstInfo[i].baseAddress =
                        (CSL_McaspRegs *)CSL_MCASP_2_CFG_REGS;
                    Mcasp_deviceInstInfo[i].fifoAddress =
                        (CSL_AfifoRegs *)CSL_MCASP_2_FIFO_CFG_REGS;
                    Mcasp_deviceInstInfo[i].dataAddress =
                        (CSL_AdataRegs *)CSL_MCASP_2_SLV_REGS;
                    Mcasp_deviceInstInfo[i].numSerializers = 4u;
                    Mcasp_deviceInstInfo[i].rxDmaEventNumber =
                        (uint32_t)CSL_EDMA3_CHA_MCASP2_RX;
                    Mcasp_deviceInstInfo[i].txDmaEventNumber =
                        (uint32_t)CSL_EDMA3_CHA_MCASP2_TX;
        #ifndef BIOS_PWRM_ENABLE
                    Mcasp_deviceInstInfo[i].pwrmLpscId = (Uint32)9;
        #else
                    Mcasp_deviceInstInfo[i].pwrmLpscId =
                        (uint32_t)CSL_LPSC_NUMBER_MCASP_2;
        #endif
                    Mcasp_deviceInstInfo[i].pscInstance = 1;
                }
                else
                {
                    /* do nothing                                                     */
                }
    #if defined (_TMS320C6X)
                Mcasp_deviceInstInfo[i].cpuTxEventNumber = CSL_INTC_EVENTID_AXRINT;
                Mcasp_deviceInstInfo[i].cpuRxEventNumber = CSL_INTC_EVENTID_AXRINT;
                Mcasp_deviceInstInfo[i].txIntNum = OSAL_REGINT_INTVEC_EVENT_COMBINER;
                Mcasp_deviceInstInfo[i].rxIntNum = OSAL_REGINT_INTVEC_EVENT_COMBINER;
    
    #else
                Mcasp_deviceInstInfo[i].cpuTxEventNumber = AINTC_EVENTID_AXRINT;
                Mcasp_deviceInstInfo[i].cpuRxEventNumber = AINTC_EVENTID_AXRINT;
                Mcasp_deviceInstInfo[i].txIntNum = AINTC_EVENTID_AXRINT;
                Mcasp_deviceInstInfo[i].rxIntNum = AINTC_EVENTID_AXRINT;
    #endif
                /* No mux present */
                Mcasp_deviceInstInfo[i].muxNum=MCASP_INVALID_MUX_NUM;
                Mcasp_deviceInstInfo[i].txMuxInEvent=MCASP_INVALID_MUX_EVENTNUM;
                Mcasp_deviceInstInfo[i].txMuxOutEvent=MCASP_INVALID_MUX_EVENTNUM;
                Mcasp_deviceInstInfo[i].rxMuxInEvent=MCASP_INVALID_MUX_EVENTNUM;
                Mcasp_deviceInstInfo[i].rxMuxOutEvent=MCASP_INVALID_MUX_EVENTNUM;
            }
    
            /* intialise the loop job buffers and the mute buffers for all instances  */
        #ifdef Mcasp_LOOPJOB_ENABLED
            memset((void *)Mcasp_loopDstBuf, 0x0,
                   sizeof(Mcasp_TempBuffer) * MCASP_CNT);
            memset((void *)Mcasp_loopSrcBuf, 0x0,
                   sizeof(Mcasp_TempBuffer) * MCASP_CNT);
        #endif /* Mcasp_LOOPJOB_ENABLED */
            memset((void *)Mcasp_muteBuf, 0x0,
                   sizeof(Mcasp_TempBuffer) * MCASP_CNT);
    }
    
    //------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------
    static void enableEDMAHwEvent(uint32_t edmaNum, uint32_t eventNo)
    {
        sampleEdma3GblCfgParams[edmaNum].dmaChannelHwEvtMap[eventNo/32] |= (1 << (eventNo%32));
    }
    
    //------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------
    EDMA3_DRV_Handle McaspApp_edmaInit(Mcasp_HwInfo *cfg)
    {
    
        EDMA3_DRV_Result edmaResult = 0;
    
        enableEDMAHwEvent(EDMACC_NUM,MCASP_RX_DMA_CH);
        enableEDMAHwEvent(EDMACC_NUM,MCASP_TX_DMA_CH);
    
        hEdma = edma3init(EDMACC_NUM, &edmaResult);
    
        if (edmaResult != EDMA3_DRV_SOK)
        {
        }
        else
        {
        }
    
        return hEdma;
    }
    
    
    

  • Hello,

    Did you add this code when enabling SPI DMA? I did not see it in Init.c. 

        spi_cfg.edmaHandle = gEdmaHandle
        spi_cfg.dmaMode    = TRUE;
        spi_cfg.enableIntr = false;

    It is difficult to see where the issue lies at the moment. Could you get in touch with your TI contact to send us your CCS project so we can take a closer look?

    Regards,
    Sahin

  • Hello,

    working with DMA is the final step.I try with :

    #ifdef SPI_DMA_ENABLE
    /* Set the DMA related init config */
    spi_cfg.edmaHandle = SPIApp_edmaInit();
    spi_cfg.dmaMode = TRUE;
    spi_cfg.enableIntr = false;
    #endif

    with //Spi.Settings.useDma  = "true"; in the app.cfg.

    It doesn't work, but also witout dma in callbak mode doesn't work. What i mean as "doesn't work" is that MCASP1 stops at the first transaction on SPI.

    I can provide the whole project but in a private form (i can't paste the project in a forum accessible to everyone)

    Regards,

    Andrea Iachini

  • Hello,

    Yes, could you please email the whole project to your local TI contact? I will get it from them. 

    Regards,
    Sahin

  • Hello,

    the whole project has been sent to our local contact.

    Regards,

    Andrea