SPI0 used in 3pin master mode (CLK, MOSI and MISO) and configured to receive data from the three microprocessors, switching their CS (some GPIO pins).
SPI1 used in 4pin slave mode (CLK,MOSI,MISO and CS).
Both of SPI modules configured to communicate via DMAX interface. Also set up two interrupts: one on a timer event (intr04), the second - at the end of the transfer on SPI1 (intr08).
Interrupt (intr08, spi1 transfer complete) clears the interrupt flag and synchronizes the operation of the timer. Interrupt (intr04, timer event) switches to the desired CS microcontroller sends and receives data from it and quickly processes the data. In the oscilloscope clearly shows that the processing time to work out before the emergence of the next interrupt.
And now the problem: sometimes my variables are transformed in the INF or NAN immediately after the program starts. This happens when I change the code and compile it. The solution to this problem, I found by changing the start address of boot program into the internal memory of the processor. And sometimes it helps.
Below I will give part of the code by setting SPI, DMAX, interrupts, and memory configuration.
I think that in these settings, I made a mistake.
Here is code:
void initDmaxConfig(void)
{
CSL_sysInit();
CSL_intcSetVectorPtr (ISTP_VECTOR_VALUE); //Relocating Interrupt Vector Table
// ISTP_VECTOR_VALUE= 0x10000000
configureSPI0();
configureSPI1();
setup_interrupts();
initDMAX();
initTimers();
}
void configureSPI0(void){
/* Configure SPI0 for master */
spi0_ptr = (unsigned int *) 0x47000000;
/* 1. Take the SPI0 out of reset */
spi0_ptr[SPIGCR0]=0x01;
/* 2. Configure SPI0 for master */
spi0_ptr[SPIGCR1]=0x03;
/* 3. Configure SPI0 for 3-pin mode */
spi0_ptr[SPIPC0]=0x0E00; //3pin mode
//
spi0_ptr[SPIPC1]|=0x0101; //CS and ENA - output
//
/* 4. Chose SPI0 SPIFMT0 */
spi0_ptr[SPIDAT1]=0x00000000;
/* 5. Configure SPI0 for SHIFTDIR=0,POLARITY=1,PHASE=0,CHARLEN=16 , prescale = 0x0C*/
spi0_ptr[SPIFMT0]=0x00020C10;
//spi0_ptr[SPIFMT0]=0x00026210;
/* 6. Configure SPI0 for C2TDELAY=2,T2CDELAY=2,T2EDELAY=4,C2EDELAY=8 */
spi0_ptr[SPIDELAY]=0x02020408;
/* 7. Configure SPI0 for error n*/
//spi1_ptr[SPIINT0]=0x00000054;
spi0_ptr[SPIINT0]=0x00000000;
spi0_ptr[SPILVL]=0x00;
/* 8. Enable SPI1 communication */
spi0_ptr[SPIGCR1]|=0x01000000;
/* 9. Configure SPI0 for dmax service*/
spi0_ptr[SPIINT0]|=0x00010000;
//
}
void configureSPI1(void){
/* Configure SPI1 for slave */
spi1_ptr = (unsigned int *) 0x48000000;
/* 1. Take the SPI1 out of reset */
spi1_ptr[SPIGCR0]=0x01;
/* 2. Configure SPI1 for slave */
spi1_ptr[SPIGCR1]=0x00;
/* 3. Configure SPI1 for 4-pin mode */
spi1_ptr[SPIPC0]=0x0E01; //4pin mode with chip select
//spi1_ptr[SPIPC0]=0x0E00; //3pin mode
//
spi1_ptr[SPIPC1]|=0x0100; //ENA - output
//
/* 4. Chose SPI1 SPIFMT0 */
spi1_ptr[SPIDAT1]=0x00000000;
/* 5. Configure SPI1 for SHIFTDIR=0,POLARITY=1,PHASE=0,CHARLEN=16 */
spi1_ptr[SPIFMT0]=0x00020010;
/* 6. SPIDELAY for SPI1 not relevant in slave mode */
spi1_ptr[SPIDELAY]=0x00;
/* 7. Disable interrupts*/
spi1_ptr[SPIINT0]=0x00000000;
spi1_ptr[SPILVL]=0x00;
/* 8. Enable SPI1 communication */
spi1_ptr[SPIGCR1]|=0x01000000;
/* 9. Configure SPI1 for dmax service*/
spi1_ptr[SPIINT0]|=0x00010000;
///
}
void initDMAX(void){
pDmaxRegs = (CSL_DmaxRegs*)0x60000000;
/***********************/
// SPI0 Event
/***********************/
// Step 1: Configure whether to use HiMAX or LoMAX for data transfer
// Writing a zero to a bit in the register has no effect
// Writing a 1 to the bit in DELPR will zero the bit
pDmaxRegs->DEHPR = 0x2000; // set Event 13 (SPI 0 RX) as high priority event (HiMAX)
// Step 2: Program the polarity of the dMAX event
pDmaxRegs->DEPR |= 0x2000; // set Event 13 to trigger on rising edge
// Step 3: Define the Event Entry within the corresponding PaRAM (hi/lo)
// BIT 31:30 RSVD reserved
// BIT 29 SPI = 0 SPI 0
// BIT 28 TCINT = 0 generate interrupt on complete
// BIT 27:24 TCC = 0 transfer complete code
// BIT 23:8 PTE = 0xA0 points to transfer entry 0 (could be 0-7) in PaRAM
// BIT 7:6 ESIZE = 10 16bit
// BIT 5 RLOAD = 0 rload disable
// BIT 4:0 ETYPE = 00010 spi slave data transfer
pDmaxRegs->HiPriorityEventTable.EVENT13 = 0x0000A082;
// Step 4: Configure the Transfer Entry
pDmaxRegs->HiMaxParam[0].WORD0 = (Uint32)gyro_txBuff; // src (active)
pDmaxRegs->HiMaxParam[0].WORD1 = (Uint32)uGyroSPI.buff; // dst (active)
pDmaxRegs->HiMaxParam[0].WORD2 = SizeMessGyro; // PP=0; COUNT active
// Step 5: Enable the corresponding transfer in the DEER
pDmaxRegs->DEER |= 0x2000; // enable Event 13
/***********************/
// SPI1 Event
/***********************/
pDmaxRegs->DEHPR = 0x4000; // set Event 14 (SPI 1 RX) as high priority event (HiMAX)
pDmaxRegs->DEPR |= 0x4000; // set Event 14 to trigger on rising edge
// Define the Event Entry within the corresponding PaRAM (hi/lo)
// BIT 31:30 RSVD reserved
// BIT 29 SPI = 1 SPI 1
// BIT 28 TCINT = 1 generate interrupt on complete
// BIT 27:24 TCC = 1 transfer complete code
// BIT 23:8 PTE = 0xCC points to transfer entry 0 (could be 0-7) in PaRAM
// BIT 7:6 ESIZE = 10 16bit
// BIT 5 RLOAD = 0 rload disable
// BIT 4:0 ETYPE = 00010 spi slave data transfer
pDmaxRegs->HiPriorityEventTable.EVENT14 = 0x3100CC82;
//Configure the Transfer Entry
pDmaxRegs->HiMaxParam[1].WORD0 = (Uint32)main_txBuff; // src (active)
pDmaxRegs->HiMaxParam[1].WORD1 = (Uint32)uHighc_rx.buff; // dst (active)
pDmaxRegs->HiMaxParam[1].WORD2 = SizeMessFromMain; // PP=0; COUNT active
//Enable the corresponding transfer in the DEER
pDmaxRegs->DEER |= 0x4000; // enable Event 14*/
}
void initTimers(void){
int prescale;
int freq = 32100; //(hz)
//SYSCLK=97.5MHz (15*13/2)
prescale = 97500000/(freq);
*(unsigned int *) 0x42000018 = prescale; //prescale
*(unsigned int *) 0x42000050 = 0x00000001; //compare
*(unsigned int *) 0x42000054 = 0x00000001; //update (compare= compare + update)
*(unsigned int *) 0x42000080 = 0x00000001; //interrupt enable
}
void setup_interrupts(void)
{
CSL_IntcObj intcObj;
CSL_IntcGlobalEnableState state;
CSL_IntcEventHandlerRecord isrRec;
CSL_IntcContext intcContext;
CSL_Status status;
/* Initialize the intc CSL modules with zeros */
memset (&intcContext, 0, sizeof (CSL_IntcContext));
memset (&intcDispatcherContext, 0, sizeof (CSL_IntcDispatcherContext));
/* Interrupt Initialization */
status = CSL_intcInit (&intcContext);
if (status != CSL_SOK) {
return;
}
status = CSL_intcDispatcherInit (&intcDispatcherContext);
if (status != CSL_SOK) {
return;
}
/* Install handler for INT04 Interrupt */
hIntc = CSL_intcOpen (&intcObj,
CSL_INTC_EVENTID_RTI_INT_REQ0, NULL, &status);
if ((hIntc == NULL) || (status != CSL_SOK)) {
status = CSL_ESYS_BADHANDLE;
return;
}
isrRec.handler = (CSL_IntcEventHandler)intr04;
/* As no arguments assigning zero(0) value */
isrRec.arg = (void *) 0x0;
/*Plugging ISR in Event Handler */
CSL_intcPlugEventHandler (hIntc, &isrRec);
/* Enabling DMAXEVTOUT1 Event */
status = CSL_intcEventEnable (CSL_INTC_EVENTID_RTI_INT_REQ0, &eventStat);
if (status != CSL_SOK) {
return;
}
/* Install handler for DMAX INT08 interrupt */
hIntc = CSL_intcOpen (&intcObj,
CSL_INTC_EVENTID_DMAXEVTOUT1, NULL, &status);
if ((hIntc == NULL) || (status != CSL_SOK)) {
status = CSL_ESYS_BADHANDLE;
return;
}
isrRec.handler = (CSL_IntcEventHandler)intr08;
/* As no arguments assigning zero(0) value */
isrRec.arg = (void *) 0x0;
/* Plugging ISR in Event Handler */
CSL_intcPlugEventHandler (hIntc, &isrRec);
/* DMAXEVTOUT0 Event Enable */
status = CSL_intcEventEnable (CSL_INTC_EVENTID_DMAXEVTOUT1, &eventStat);
if (status != CSL_SOK) {
return;
}
/* Enabling Non-Maskable Interrupt */
status = CSL_intcEventEnable (CSL_INTC_EVENTID_NMI, &eventStat);
if (status != CSL_SOK) {
return;
}
/* Enabling Global Enable bit in Control Status Register (CSR) */
status = CSL_intcGlobalEnable (&state);
if (status != CSL_SOK) {
return;
}
/* Closing INTC Handle */
status = CSL_intcClose (hIntc);
if (status != CSL_SOK) {
return;
}
/* End of setup_interrupts() */
}
void SendDataGyro(void){
pDmaxRegs->HiMaxParam[0].WORD0 = (Uint32)gyro_txBuff; // src (active)
pDmaxRegs->HiMaxParam[0].WORD1 = (Uint32)uGyroSPI.buff; // dst (active)
pDmaxRegs->HiMaxParam[0].WORD2 = SizeMessGyro; // PP=0; COUNT active
spi0_ptr[SPIDAT1]=(spi0_ptr[SPIDAT1]&0xFFFF0000)|0xFFFF;
}
void reloadExchangeMain(void){
spi1_ptr[SPIGCR0]=0x00;
configureSPI1();
//
pDmaxRegs->HiMaxParam[1].WORD0 = (Uint32)main_txBuff; // src (active
pDmaxRegs->HiMaxParam[1].WORD1 = (Uint32)uHighc_rx.buff; // dst (active
pDmaxRegs->HiMaxParam[1].WORD2 = SizeMessFromMain; // PP=0; COUNT active)
//
}
void intr04()
{
//
*(unsigned int *) 0x42000088 = 0x00000001; //clear interrupt TIMER0 flag
//
switch(work_state){
case Work_X_CS:{
CS_X_1;
work_state = Work_X_CLK;
break;
}
case Work_X_CLK:{
SendDataGyro(); //send CLK for GyroX
reloadExchangeMain();
work_state = Work_Y_CS;
break;
}
case Work_Y_CS:{
CS_X_0;
CS_Y_1;
work_state = Work_Y_CLK;
break;
}
case Work_Y_CLK:{
SendDataGyro(); //send CLK for GyroY
work_state = Work_Z_CS;
break;
}
case Work_Z_CS:{
CS_Y_0;
CS_Z_1;
work_state = Work_Z_CLK;
break;
}
case Work_Z_CLK:{
SendDataGyro(); //send CLK for GyroZ
work_state = Work_Idle0;
break;
}
case Work_Idle0:{
CS_Z_0;
work_state = Work_Idle1;
break;
}
case Work_Idle1:{
work_state = Work_X_CS;
IIRFiltr();
break;
}
}
//end
}
//dmax spi1 transfer complete (exchange with main)
void intr08()
{
pDmaxRegs->DTCR0 |= 0x0002; //clear interrupt
startTimer0();
}
void startTimer0(void){
*(unsigned int *) 0x42000014 = 0x00000000; //reset upcounter0
*(unsigned int *) 0x42000000 = 0x00000001; //timer start
}
Here is memory configuration:
-e int00
-c
-x
-stack 0x8000
-lrts6700.lib
/****************************************************************************/
/* Specify the Memory Configuration */
/****************************************************************************/
MEMORY
{
RAM : origin = 0x10004000 length = 0x3C000
SDRAM : origin = 0x80000000 length = 0x2000000
}
/****************************************************************************/
/* Specify the Output Sections */
/****************************************************************************/
SECTIONS
{
.vector: load = RAM align = 0x400
.text: load = RAM
.stack load = RAM fill = 0xdeadbeef
.cinit load = RAM
.cio load = RAM
.const load = RAM
.data load = RAM
.switch load = RAM
.far load = RAM
.bss load = RAM
.sysmem load = RAM
.test_cache load = RAM
.pinit load = RAM /* Added by sumanth */
.err_buffers load = RAM fill=0xabcdabcd
.src_a_buffers load = RAM align = 0x200
.src_b_buffers load = RAM align = 0x200
.src_c_buffers load = RAM align = 0x200
.src_d_buffers load = RAM align = 0x200
.src_e_buffers load = RAM align = 0x200
.src_f_buffers load = RAM align = 0x200
.dst_buffers load = RAM align = 0x200
.dsp_data load = RAM align = 0x200
.src_buffers load = RAM align = 0x200
.SDRAM_Memory load = SDRAM
}