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.

C6678 reading from ADC using SPI - problem with interrupt

Hi!

I'm relaying a question from a colleague. He wants to use SPI to read out an ADC, but there seems to be a configuration problem with the interrupt or SPI interface itself. On a related note, is there an C6678 EVM with accessible SPI? Do we have Code Examples using SPI interrupts and DMA?

Thanks a lot for your help
Marcus

Due to company proxy settings, its a bit difficult to update the CCS and packages and the ones used are a bit outdated. Please point out, if the problem would be solved by a newer version, but it looks like there might just be an error in the code somewhere.

Code Composer Studio Version: 5.2.1.00018
Compiler Version 8.1.0
bios_mcsdk_02_01_02_05

The Hardware:

I am using the Evaluation Board TMDSEVM6678L Rev.3B. I intend to use the SPI to connect to an ADC and so I have to read data via the SPI. The SPI of the DSP provides two chip select pins but all are in use. CS0 is connected to the NOR-Flash and CS1 is connected to the FPGA. The CS1 is connected to the 80-pin connector as well; the CS0 is not accessible via the 80-pin connector. So I intend to use the CS1 for my ADC connection. I had cut the CS1 to the FPGA and connected it via a resistor to 1.8V. The FPGA should be disabled now.

 

The Problem:

I have to read continuously from ADC but the SPI interrupt does not work. Please find my configuration below. What I have done wrong? What is necessary to use DMA? Has anybody an example code for SPI configuration using interrupt or DMA?

 

uint32_t scalar;
Int iEventID;

#define SPI_MAX_FREQ            66000000
#define SYSTEM_INTERRUPT_SPI_0                (54)
#define SYSTEM_INTERRUPT_SPI_1                (55)
#define HOST_INT_SPI_ISR          (41)
#define INT_VEC_SPI_ISR             (13)

SPI_Status_Type SPIDriverInit(void)
{
                        Hwi_disable();

                        /* Enable the SPI hardware */
                        SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_IN_RESET;
                        spi_delay2 (2000);
                        SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_OUT_OF_RESET; //Global Control Register 0

                        /* Set master mode, powered up and not activated */
                        SPI_SPIGCR1 =              (CSL_SPI_SPIGCR1_MASTER_MASTER << CSL_SPI_SPIGCR1_MASTER_SHIFT)   | //Global Control Register 1
                                                                                                                        (CSL_SPI_SPIGCR1_CLKMOD_INTERNAL << CSL_SPI_SPIGCR1_CLKMOD_SHIFT);


                        /* CS0, CS1, CLK, Slave in and Slave out are functional pins */
                        SPI_SPIPC0 =                  ((CSL_SPI_SPIPC0_SCS0FUN1_SPI << CSL_SPI_SPIPC0_SCS0FUN1_SHIFT) | //SPI Pin Control Register 0
                                                                                                                        (CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT)                  |
                                                                                                                        (CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT)   |
                                                                                                                        (CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT)) & 0xFFFF;


                        /* setup format */
                        scalar = ((SPI_MODULE_CLK / SPI_MAX_FREQ) - 1 ) & 0xFF;

                        SPI_SPIFMT0 =              (16 << CSL_SPI_SPIFMT_CHARLEN_SHIFT)                            |
                                                                                                                        (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT)                                                                                                                    |
                                                                                                                        (CSL_SPI_SPIFMT_PHASE_NO_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT)      |
                                                                                                                        (CSL_SPI_SPIFMT_POLARITY_LOW << CSL_SPI_SPIFMT_POLARITY_SHIFT) |
                                                                                                                        (CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);


                        /* hold cs active at end of transfer until explicitly de-asserted */
                        SPI_SPIDAT1 = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT);// |
                        //                                                                                            (0x02 << CSL_SPI_SPIDAT1_CSNR_SHIFT);


                        /*SPI_SPIDELAY =        (6 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |
                                                                                                                        (3 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);*/

                        SPI_SPIDELAY = 0;


                        /* interrupts */
                        SPI_SPIINT0 = ((CSL_SPI_SPIINT0_RXINTENA_ENABLE << CSL_SPI_SPIINT0_RXINTENA_SHIFT) | //SPI Interrupt Register
                                                                                                                        (CSL_SPI_SPIINT0_TXINTENA_ENABLE << CSL_SPI_SPIINT0_TXINTENA_SHIFT) |
                                                                                                                        (CSL_SPI_SPIINT0_OVRNINTENA_ENABLE << CSL_SPI_SPIINT0_OVRNINTENA_SHIFT) |
                                                                                                                        (CSL_SPI_SPIINT0_BITERRENA_ENABLE << CSL_SPI_SPIINT0_BITERRENA_SHIFT));

                        //SPI_SPIINT0 = CSL_SPI_SPIINT0_RESETVAL;

                        SPI_SPILVL = CSL_SPI_SPILVL_RESETVAL; //SPI Interrupt Level Register

                        /* enable SPI */
                        SPI_SPIGCR1 |= ( CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT );



                        /* Plug the function for event */
                        CpIntc_dispatchPlug(SYSTEM_INTERRUPT_SPI_0, SPI_HWI_Isr, HOST_INT_SPI_ISR, TRUE);

                        /* The configuration is for I2CREVT. We map system interrupt to Host Interrupt */
                        CpIntc_mapSysIntToHostInt(0, SYSTEM_INTERRUPT_SPI_0, HOST_INT_SPI_ISR);

                        // Enable host interrupt hostInt
                        CpIntc_enableHostInt(0, HOST_INT_SPI_ISR);

                        /* Get the event id associated with the host interrupt. */
                        iEventID = CpIntc_getEventId(HOST_INT_SPI_ISR);

                        Hwi_Params_init(&hwiParamsSPI);
                        hwiParamsSPI.arg = HOST_INT_SPI_ISR;
                        hwiParamsSPI.eventId = iEventID;
                        hwiParamsSPI.enableInt = TRUE;
                        hwiParamsSPI.priority = 2;

                        // don't allow this interrupt to nest
                        hwiParamsSPI.maskSetting = Hwi_MaskingOption_ALL;
                        SPI_Hwi = Hwi_create(INT_VEC_SPI_ISR, &CpIntc_dispatch, &hwiParamsSPI, NULL);
                        Hwi_enableInterrupt(INT_VEC_SPI_ISR); //Interrupt Enable Register (IER)
                        Hwi_enable(); //Global Interrupt Enable (GIE)

}



void SPI_HWI_Isr(UArg arg)
{
                        uint32_t uiTestSPIFLG;
                        uiTestSPIFLG = SPI_SPIFLG;
                        if(uiTestSPIFLG & CSL_SPI_SPIFLG_RXINTFLG_MASK)
                        {
                                                .......
                        }
                        if(uiTestSPIFLG & CSL_SPI_SPIFLG_TXINTFLG_MASK)
                        {
                                                ........            
                        }
}

 


 

  • Hi Marcus,

    I've notified the MCSDK team. Their feedback will be posted directly here.

    Best Regards,
    Yordan

  • The CS1 is connected to the 80-pin connector as well; the CS0 is not accessible via the 80-pin connector. So I intend to use the CS1 for my ADC connection. I had cut the CS1 to the FPGA and connected it via a resistor to 1.8V. The FPGA should be disabled now.



    The CS1 of FPGA is used to access the FPGA configuration registers from DSP.


    The Problem:
    I have to read continuously from ADC but the SPI interrupt does not work. Please find my configuration below. What I have done wrong? What is necessary to use DMA? Has anybody an example code for SPI configuration using interrupt or DMA?


    Is it not working only on DMA mode? Please refer the platform source for reading data using CS1 of ADC and Iwe do not have SPI DMA example in SDK package.

    PATH: ~\ti\pdk_C6678_1_x_x_x\packages\ti\platform\evmc6678l\platform_lib\src
    Files: evmc66x_spi.c and evmc66x_fpga.c

    Thank you.
  • Hi Raja!
    Thanks for the quick reply. Do you require the SPI connection between DSP and FPGA?

    He didn't test DMA yet, but interrupt triggered SPI should work nevertheless, right?

    Best regards
    Marcus
  • Do you require the SPI connection between DSP and FPGA?

    To answer this question, please answer below questions.

    What is boot mode used to test the above SPI code? How the image being loaded to DSP?
  • I have reviewed the interrupt configuration and please change update the code as below and let me know if you can get an interrupt.

    #define HOST_INT_SPI_ISR          (8)
    
    
    /* Plug the function for event */
    CpIntc_dispatchPlug(SYSTEM_INTERRUPT_SPI_1, &SPI_HWI_Isr, SYSTEM_INTERRUPT_SPI_1, TRUE);
    
    /* The configuration is for I2CREVT. We map system interrupt to Host Interrupt */
    CpIntc_mapSysIntToHostInt(0, SYSTEM_INTERRUPT_SPI_1, HOST_INT_SPI_ISR);
    
    /* Enable host interrupt hostInt */
    CpIntc_enableHostInt(0, HOST_INT_SPI_ISR);
    
    /* Enable the System Interrupt */
    CpIntc_enableSysInt(0, SYSTEM_INTERRUPT_SPI_1);
    
    /* Get the event id associated with the host interrupt. */
    iEventID = CpIntc_getEventId(HOST_INT_SPI_ISR);

    Please refer below thread as well,

    Thank you.

  • Hi Raja,


    the interrupts seem still not to work at the customer  (I have asked to review the "Interrupt Handling in C6678" post) once more.

    The SPI-communication to the ADC in general is working w/o interrupt usage. But now they need to get interrupts or DMA involved, in order to automate the communication and to offload the CPU.

    Do we have a SPI example using interrupts or DMA which we could refer to?

    I am sure, the SPI has been already used with interrupts/DMA on the C6678.

    Thanks,
    BR,

    Matthias