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.

TMS320F28379D: Strange behavior by SPI communication in between c2000 and CC3220SF

Part Number: TMS320F28379D
Other Parts Discussed in Thread: CC3220SF

Hi,

I am working to send the raw data from C2000 to CC3220SF. When we give a sinusoid input (0-2V) to ADC of C2000 based on PWM triggered sampling frequency, we are able to send the raw data to cc3220sf successfully while we are performing 64Point FFT on the ADC data (64 samples/cycle) simultaneously . Here the strange thing come when we try to  generate harmonics (consider an arc in a power circuit as signal containing harmonics) signal at the input of adc and send the harmonized raw data to SPI.  SPI starts sending all data as 0xFFFF (from c2000 to cc3220sf) and CC3220SF clock continue even after receiving the intended size (ex. Rx Count at cc3220sf is 256 but it will continuous to receive 0xFFFF even after that. 

What can be the issue, is it hardware or something else ? 

Thank you.

Best Regards,

Kuldeep

  • Kuldeep,

    Is the C2000 MCU the SPI master or slave in this case? How is data copied from the ADC to the SPI in the C2000 MCU? Is it via DMA or CPU? 

  • Hi Martinez,

    1. C2000 is in Slave Mode, frequency is 500KHz, Data Size - 16bit. No DMA.

    2. I am taking data into a buffer from adc interrupt and same is updated to another buffer which is used to send the data through SPI (so its CPU).

    Thanks for quick reply.

    Thanks & Regards,

    Kuldeep

  • Thanks for the clarification.

    When we give a sinusoid input (0-2V) to ADC of C2000 based on PWM triggered sampling frequency, we are able to send the raw data to cc3220sf successfully

    Since you are able to send data via SPI successfully in one case, I would not suspect an issue with the SPI configuration or setup.

    I am taking data into a buffer from adc interrupt and same is updated to another buffer which is used to send the data through SPI (so its CPU).

    Have you looked at this buffer to see if indeed has 0xFFFF values in it? If it does have 0xFFFF in it, I would look closely at the ADC and how it is configured. Perhaps the ADC is getting saturated.

  • Hi Martinez,

    Thanks for reply.

    As I see the buffer, its seems fine and ADC is not getting saturated (12 bit adc which can give max digital value as 4096) (max sensor output is 2V) . my FFT Results are also fine. 

    Also the data into the TX Reg also fine but when it comes to the Shift Register I see the data as 0xFFFF. and cc3220sf Launchpad gets the same data.

    Note: Before sending any data between c2000 and cc3220, I have a handshaking using a GPIO interrupt on CC3220SF. After handshaking I am transferring the data.

    The handshaking is working fine with sinusoid data. Handshaking is done using Raising Edge interrupt on CC3220SF. The GPIO on C2000 again bring down to Zero after transfer of SPI Data (A counter (256 data) on SPI RX at C2000 for number of data transfer which reset a flag on C2000 which then in main code changes the GPIO from high to low)  . This functionality is working fine with sinusoid data.

    When data containing harmonics at input, GPIO is going LOW (desired ) after 256 data  (0xFFFF) but the SPI communication still remain continue.  

     

    Thanks & Regards,

    Kuldeep

  • Hi Kuldeep,

    The handshaking is working fine with sinusoid data. Handshaking is done using Raising Edge interrupt on CC3220SF. The GPIO on C2000 again bring down to Zero after transfer of SPI Data (A counter (256 data) on SPI RX at C2000 for number of data transfer which reset a flag on C2000 which then in main code changes the GPIO from high to low)  . This functionality is working fine with sinusoid data.

    I'm having trouble understanding this. The C2000 sets a GPIO low after it sends 256 values via SPI?

    When data containing harmonics at input, GPIO is going LOW (desired ) after 256 data  (0xFFFF) but the SPI communication still remain continue.  

    This is also confusing. If the C2000 device is the slave, then the CC3220 is in full control of the SPI transmissions. In slave mode, the C2000 device cannot initiate any SPI transactions. 

    Also the data into the TX Reg also fine but when it comes to the Shift Register I see the data as 0xFFFF. and cc3220sf Launchpad gets the same data.

    The C2000 slave SPI will simultaneously send AND receive data on SPIDAT (I assume this is what you mean by shift register). If the C2000 SPI SIMO pin is floating or set high by the master, then I think it makes sense that the SPIDAT is always 0xFFFF.

  • Hi Martinez,

    Kindly have a look in below logic for better understanding - 

    This is an external GPIO 16 at C2000 which gives an interrupt to CC3220SF when even want to communicate data as shown in c2000 code below .

    I'm having trouble understanding this. The C2000 sets a GPIO low after it sends 256 values via SPI?

    GPIO is just to notify Master cc3220sf that slave want to communicate. Master only will initiate the transaction - 

    This is also confusing. If the C2000 device is the slave, then the CC3220 is in full control of the SPI transmissions. In slave mode, the C2000 device cannot initiate any SPI transactions. 

    Right but the data received at CC3220 is 0xFFFF not the desired. 

    The C2000 slave SPI will simultaneously send AND receive data on SPIDAT (I assume this is what you mean by shift register). If the C2000 SPI SIMO pin is floating or set high by the master, then I think it makes sense that the SPIDAT is always 0xFFFF.

    1. Logic with code for C2000 -

    if(adcBuff have 64 new data)
        {
              if(condition)
              {
                   for(i=0;i<64;i++)
                   {
                       slaveTxBuffer[i+64*cyclesFilled+1] = adcData[i];
                   }
                   cyclesFilled++;  //Data for 4 cycles means (64*4) 256 +1 (some status) 
                   if(cyclesFilled==4)
                   {
                       cyclesFilled = 0;
                       
                       //External interrupt to Master (This is not CS) for handshaking
                       GPIO_writePin(16, 0);
    
                       for(i = 0; i < SPI_MSG_LENGTH; i++)
                       {
                           SPI_writeDataBlockingFIFO(SPIA_BASE, slaveTxBuffer[i]);
                       }
    
                       while(condition == true){} //This will become false in SPI interrupt once 256 Data Receive is Done
    
                        //Make GPIO to High Again for new handshaking 
                       GPIO_writePin(16, 1);
                   }
    
               }
               
               //Perform Harmonic Analysis using FFT
        }
    
    
    //SPI Interrupt 
     __interrupt void spiaRxFIFOISR(void)
    {
         //
         // Read data
         //
         slaveRxBuffer[receiveCount++] = SPI_readDataNonBlocking(SPIA_BASE);
         if(receiveCount == 257)
         {
             receiveCount=0;
             condition = false;
         }
    
         //
         // Clear interrupt flag and issue ACK
         //
         SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF);
         Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
    }
    

    2. Code at cc3220sf -

     

    //In GPIO Interrrupt for handshaking - 
    void slaveReadyFxn(uint_least8_t index)
    {
            sem_post(&spiSem);
    }
    
    
    
    //In Task SPI Receive 
            
            sem_wait(&spiSem);
    
            /* Initialize master SPI transaction structure */
            memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
            transaction.count = SPI_MSG_LENGTH;
            transaction.txBuf = NULL;
            transaction.rxBuf = (void *) masterRxBuffer;

    Please let me know if this makes sense.

    Thanks & Regards,

    Kuldeep

  • Kuldeep,

    Thanks for the additional information. This helps me understand the problem better. 

    One question, you are saying that even after the master has sent 256 characters to the slave, the GPIO continues to be low. Is this right? Is this what you mean by the "SPI communication still remains"?

    Please note that the spiaRxFIFOISR will only get called when the RX FIFO level is met. Therefore, the number of times you call SPI_readDataNonBlocking needs to reflect the RXFFIL setting. In other words, if RXFFIL == 4, then the SPI RX FIFO has at least 4 characters and you should call SPI_readDataNonBlocking four times. What is the RXFFIL setting you are using? Since you are using an odd number (257) as the check to clear "condition", you should probably use RXFFIL = 1.

    Another question, I'm assuming SPI_MSG_LENGTH is defined as 257 in your code?

  • Hi Martinez,

    Please find the details as below - 

    Yes. Even after sending 257 (I am sending 256 adc data and 1 status data), GPIO remains low and also SPI clock and data transfer continue for approx 2 to 3 times of the length of 257 data (approx 2*257)

    One question, you are saying that even after the master has sent 256 characters to the slave, the GPIO continues to be low. Is this right? Is this what you mean by the "SPI communication still remains"?

    Correct, I am using RXFFIL=1 in c2000 and same is used in CC3220SF by default. you can see same as below - 

    Please note that the spiaRxFIFOISR will only get called when the RX FIFO level is met. Therefore, the number of times you call SPI_readDataNonBlocking needs to reflect the RXFFIL setting. In other words, if RXFFIL == 4, then the SPI RX FIFO has at least 4 characters and you should call SPI_readDataNonBlocking four times. What is the RXFFIL setting you are using? Since you are using an odd number (257) as the check to clear "condition", you should probably use RXFFIL = 1.

      SPI_setFIFOInterruptLevel(SPIA_BASE, SPI_FIFO_TXEMPTY, SPI_FIFO_RX1);
    

    SPI Initialization on c2000 - 

    void initSPIASlave(void)
    {
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIA_BASE);
    
        //
        // SPI configuration. Use a 500kHz SPICLK and 16-bit word size.
        //
        SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA1,
                      SPI_MODE_SLAVE, 500000, 16);
        SPI_disableLoopback(SPIA_BASE);
        SPI_setEmulationMode(SPIA_BASE, SPI_EMULATION_FREE_RUN);
    
        //
        // FIFO and interrupt configuration
        //
        SPI_enableFIFO(SPIA_BASE);
        SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF);
        SPI_setFIFOInterruptLevel(SPIA_BASE, SPI_FIFO_TXEMPTY, SPI_FIFO_RX1);
        SPI_enableInterrupt(SPIA_BASE, SPI_INT_RXFF);
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIA_BASE);
    }

    where I am using SPI in blocking mode to transfer the data from c2000.

    SPI_writeDataBlockingFIFO(SPIA_BASE, slaveTxBuffer[i]);
     

    Yes, That's correct .

    Another question, I'm assuming SPI_MSG_LENGTH is defined as 257 in your code?

    In CC3220SF - 

        /* Open SPI as master (default) */
        SPI_Params_init(&spiParams);
        spiParams.frameFormat = SPI_POL0_PHA0;
        spiParams.transferMode= SPI_MODE_BLOCKING;
        spiParams.bitRate = 500000;
        spiParams.dataSize = 16;
        masterSpi = SPI_open(CONFIG_SPI_MASTER, &spiParams);
        if (masterSpi == NULL) {
           // Display_printf(display, 0, 0, "Error initializing master SPI\n");
            while (1);
        }

    POL and PHA have different values at C2000 and CC3220SF as both devices have different meaning for same types. POL0_PHA0  at cc3220sf and POL0PHA1 at c2000 have same meaning with respect to clock which also can be checked in TRM.

    Thank you.

    Best Regards,

    kuldeep

  • At this point I cannot find anything wrong with your SPI configuration. The SPI operation is agnostic to the data being transmitted or received, therefore, in theory the harmonic data should not affect the operation of the SPI.

    I would recommend focusing the debug on your code flow. When the device gets in this bad state (always keeping GPIO low), I would recommend looking at the status registers in the SPI and the global variables in your code to get more debug information. 

    You can also set the GPIO high in the ISR and configure your oscilloscope to detect any low to high transition. Perhaps the GPIO high pulse is very short?

  • Hi Martinez,

    No, its remain High for significant duration .

    You can also set the GPIO high in the ISR and configure your oscilloscope to detect any low to high transition. Perhaps the GPIO high pulse is very short?

    Okay, I will continue my debugging.

    Thank you.

    Best Regards,

    Kuldeep