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.

C6726b Inf/Nan Problem

 

I'm using c6726 and wrote a program that communicates with 4 microcontrollers by SPI.

 

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

}

 

 

 

  • Maxim Gorbachov,

    Maxim Gorbachov said:
    sometimes my variables are transformed in the INF or NAN immediately after the program starts.

    Which variables? What are their hex values? Do they appear as 0xdeadbeef or 0xabcdabcd or some random value?

    Does this mean that their initial values are interpreted as INF or NAN?

    Regards,
    RandyP

  • I have a few variables that are the sum of the values obtained in transmission by SPI. They are initialized before starting the exchange between the microcontroller (I set them all to 0). And in the debugger looks like 0x00000000. After initializing these variables, I set up the interrupt and SPI. As soon as the exchange begins, these variables are already 0x1FFFFFFF.

    And the interesting thing is that sometimes it works well. One need only change one line of code in a very different place in the program - and once INF. As I wrote above, helps the rearrangement in the program memory. If you picked a "good" place "- is always loaded and works well. I think, though may be mistaken, it's about configuring SPI.

    I do not use arrays. Only the buffers for transmission over the SPI.

  • Maxim,

    If your variables are the sum of values received from the SPI, what are the values received before adding them to make the variables?

    Maxim Gorbachov said:
    After initializing these variables, I set up the interrupt and SPI. As soon as the exchange begins, these variables are already 0x1FFFFFFF.

    "As soon as the exchange begins" is not clear to me. What does this mean?

    Changing the program and getting different results implies that you have something wrong in your linker command file or you have overlapped cache with SRAM.

    You will have to do a lot more debugging, like comparing everything that is different between the code with a change that fails and with a change that works.

    Regards,
    RandyP

  • RandyP said:

    "As soon as the exchange begins" is not clear to me. What does this mean?

    Аfter the first execution of the interrupt function, these variables take the value 0x7FFFFFFF

     

    RandyP said:

    You will have to do a lot more debugging, like comparing everything that is different between the code with a change that fails and with a change that works.

    After debugging I found some of the variables are not initialized. At this point, the program works correctly, but I'm not sure how it would behave in the future. So have more questions.

     

    1) Сan this problem be associated with an incorrect configuration of interrupts and SPI? Or due to an incorrect location of interrupt vector (0x10000000)?

    2) What does it  mean: "you have overlapped cache with SRAM"? Please, explain.

    3) In any instructions, we can't find description behavior of DSP, when we have a few interrupt at the same time. Whether it will place them in a stack?

    4) Whether can incorrect work of program be associated with turning off SPI (spi1_ptr[SPIGCR0]=0x00) and reconfigure it after each received message?

  • Maxim Gorbachov said:
    After debugging I found some of the variables are not initialized. At this point, the program works correctly, ...

    Did you fix the cause of the variables that were not initialized? Or are you saying that the program works correctly even though the variables are not initialized?

    Maxim Gorbachov said:
    I'm not sure how it would behave in the future. So have more questions.

    It is not practical to try to discuss everything that could go wrong in a system. Maybe that is not what you mean to say, but we can help you on the forum with specific problems you have. Or you can study all the User's Guides and Application Notes we have written for the device and peripherals. There is a lot of information, and any of it could be relevant, or there may be no problem if you have the system working now.

    Maxim Gorbachov said:

    2) What does it  mean: "you have overlapped cache with SRAM"? Please, explain.

    L2 is a fixed size resource. You can allocate some of it as cache, which reduces the amount available as SRAM. If you allocate 50% as cache, but try to use the whole L2 as SRAM, then some variables in SRAM will overlap with cache.

    Maxim Gorbachov said:

    3) In any instructions, we can't find description behavior of DSP, when we have a few interrupt at the same time. Whether it will place them in a stack?

    If you go to the TI Wiki Pages and search for C6000 BIOS Workshop, you will find an excellent source of training material for C6000 devices operating under DSP/BIOS (workshop v5.93) or SYS/BIOS (workshop v6.00).

    The section on interrupts explains what the process flow is for interrupts on a DSP. There may be some minor differences between devices, but the concepts are the same and most of the implementation points are the same.

    Different interrupts are retained in the IFR register. Multiple interrupts on the same line may be lost if they happen faster than the ISR can handle them.

    I do not know how to answer the other questions. Sorry.

    Regards,
    RandyP

  • RandyP said:

    Did you fix the cause of the variables that were not initialized? Or are you saying that the program works correctly even though the variables are not initialized?

    Yes, now I initialize these variables, and my program works correctly. I tried to change its location in memory, and such problems will no longer appear. Perhaps it was my mistake.


    RandyP, thanks for your advice and answers to my questions.