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) { ........ } }