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

