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.

TMS320F28376S: SPI issue

Part Number: TMS320F28376S
Other Parts Discussed in Thread: C2000WARE

Dear Sir,

we are under development of controler based on 28376s , and have some issue with SPI slave transmit 

the spi interface is as follow 

1. one unit is configured as SPI Master , send every chuck of 8 SPI word (each 16 bit)  (using SPI  TX FIFO)   - without any interrupt 

    the slave data is read also from RX FIFO (when the fifo is not empty) , for test purpose the unit sends   8 words of 0xaa55  (this is validated on the slave side)

2.the seconds unit  configure as SPI Slave , and every 1ms checks the SPI RX FIFO, if there not empty read all the data avilable in the fifo  and insert data to be transmited for the next SPI communicaiton

 with the master , also 8 SPI words (16 bit ) , for test purpose the unit sends 8 words of 0xbb66 (this is validated on the master) side

this tested with various SPI CLK  (2.5Mhz , 1Mhz ,400Khz)  , and issue remain  which is somtimes that data from the Slave look corrupted  (as if it is shifted by few bits)  it occur every 5 - 10 minutes

is there issue writting to  SPI TX buffer on the slave side (assunming it is not full ) ?  i am guessing there could some conflict when the slave writes to SPI TX FIFO while there is communication with SPI master

but i assume there should be any issue beacuse it write to FIFO  and not directly to SPIDAT

please your advise  on this matter

   

  • Eyal,

    How are you directly writing to SPITX FIFO registers? Is your SPI master and slave talking in same clocking scheme?

    Regards,

    Manoj

  • HI Manjo   ,

    1. I dont write directly  to FIFO but using SPITXBUF anf SPIRXBUF  to interface FIFO for RX and TX

    2. the clock schem is Rising edgde without delay (e.g. Send on rising edge capture of falling edge)

    plese see below for proper communication between SPI Slave Master     

    every 1ms  Master Sends   8x 16 bit words (All  0xaa55)

                      slave sends      8x 16bit  words  (all 0xbb66)

    when the issue occuers (every 5-10minuts ) , it corrupts only the SPI slave data  (e.g. MISO) but in such that it courrputs 

    as exaplains below 

    1.word #5  shifteed by 2 bits ,   is now 0x2ED9  (which is 0xBB66>>2)    - after X ms

    2.word #5 shifteed by 3 bits ,    is now 0x176c  (which is 0xBB66>>3)      - after X+1 ms

    3.word #5 shifted by 4 bits  ... is now  0x0BB6    (which is 0xBB66>>4)  - after X+2 ms

    ....  

    i.word  #6 shifteed by 2 bits , .....

    .....

    i.word  #7 shifteed by 2 bits , .....

    as if the issue travels between the words transmitted by the SPI Slave .

    i am guessing that every few minutes SPI master and slave mistakely synchornized to each other in such way where while i am writting to SPITXBUF , the Master sends data and this strange phenomena happens

    below is short video that show the issue(hopefully it can be shown ) , in the video 

    the Master send 8xSPI words of 0x0000  (every 1ms)

    the Slave sends 8xSPI words of 0xbb66 (every 1ms)  

    you can see the "issue" travels  between MISO (e.g. Slave transmit) , word #3  and then 4 and then 5  until dissapers 

  • Eyal,

    It is still not clear to me what might cause this. Will you be able to send us your code to check whether you have configured everything right?

    Additional questions:-

    1) Do you have two physical F28376S devices connected through SPI?

    2) Do you have SPIA configured as master and SPIB configured as slave within one F28376S device?

    3) What triggers SPI communication from master every 1ms?

    4) Is it right you don't use SPI interrupts for both master and slave?

    5) Do you use CPU / DMA to write to SPI slave transmit register? Are you sure Slave. SPITXBUF register is written with 8 words of 0xBB66?

    6) I hope you have Slave TX FIFO filled up with 0xBB66 before SPI master starts transmitting 0xAA55. How are you ensuring this?

    7) Are you seeing corrupted message only on oscilloscope (possible oscilloscope artifact) (or) do you see receive corrupted data in master receive register?

    Regards,

    Manoj

  • Hi Manoj , 

    Thank you for the quick reply.

    1. The Test that i am doing inlcude 2xControllers   

         a. 1 unit is SPI Master 

         b. 1 unit is SPI Slave

         c. cable connectitng both of the unit SPi singnals (CS,CLK,MOSI,MISO) 

    2.both unit use SPIA 

    3. both of the units has 50us interrupt trigger , where every 20th interrupt the SPI communitation is trigger (e.g 50*20 = 1ms)

       the 50us is coming from FPGA  (in very determinsitc fashion)  , and on 1ms CYCLE 

           a. SPI Master - Read from SPI RX FIFO (if FIFO not empty ) , Write to SPI TX FIFO (if FIFO not FULL )  8xwords of  0xaa55

           b.SPI Slave   - Read if SPI RX FIFO is not empty is so  

                                    i.read all SPI RX Words

                                   ii. write to SP TX words   8xwords of   0xbb66  (only if FIFO has space for addtional 8 words )

    4.no dout using SPI based on interrupt would more proper way , but the main purpose of the controller is for motion control 

       as thus most of the time servo alogrithem is running under interrupt (alnog with Current loop , velocity loop ,postion) so it is pretty occuiped 

       and that is way is implmented in such way

    5.i am not using DMA for SPI  ( i am using it for other purpose )

    6.yes SPi Slave is wrritten with 8 words of 0xbb66 , most of the time the communication is working (there is valdiation on both side) , but the issue occur 

       once in  5/10 minutes  , you can alos see in the SCOPE snashot above  (and also the video ) the the data on to MISO   is 0xbb66  

    7. actulay it doesnt matter , SPI SLAVE /  SPI Master    will eventaully aligned   , as master sends up to 8 words (FIFO depth is 16 ) in 1ms

       so they will catch up (maybe in start there will some trasnient ), and they both work on  1ms based 

       i also handle FIFO Overflow (but i dont see indiaction that it is occur)

    8. Some courrpted word i can see in the buffer read  , pay notice it is not rendom courrption but related sonhow to shift reigtser

       e.g  instead of output  0xbb66   , it is output  0xbb66>>2

         session  x+1ms  instead of output  0xbb66   , it is output  0xbb66>>3

          session  x+2ms  instead of output  0xbb66   , it is output  0xbb66>>4

         etc...

    BR,

    EYAL

  • Eyal,

    Thanks for clarification. I tried modifying spi_ex3_external_loopback_fifo_interrupts example code to reproduce the problem. But, I was not successful in reproducing the problem. I'm able to achieve full-duplex communication without any issues. Attached is the modified C2000Ware code for your review.

    I don't think I can help without looking into your SPI related code.

    spi_ex3_external_loopback_fifo_interrupts.c
    //#############################################################################
    //
    // FILE:   spi_ex3_external_loopback_fifo_interrupt.c
    //
    // TITLE:  SPI Digital Loopback with FIFO Interrupts
    //
    //! \addtogroup driver_example_list
    //! <h1>SPI Digital External Loopback with FIFO Interrupts</h1>
    //!
    //! This program uses the external loopback between two SPI modules. Both
    //! the SPI FIFOs and their interrupts are used. SPIA is configured as a slave
    //! and receives data from SPI B which is configured as a master.
    //!
    //! A stream of data is sent and then compared to the received stream.
    //! The sent data looks like this: \n
    //!  0000 0001 \n
    //!  0001 0002 \n
    //!  0002 0003 \n
    //!  .... \n
    //!  FFFE FFFF \n
    //!  FFFF 0000 \n
    //!  etc.. \n
    //! This pattern is repeated forever.
    //!
    //! \b External \b Connections \n
    //!  -GPIO24 and GPIO16 - SPISIMO
    //!  -GPIO25 and GPIO17 - SPISOMI
    //!  -GPIO26 and GPIO18 - SPICLK
    //!  -GPIO27 and GPIO19 - SPISTE
    //!
    //! \b Watch \b Variables \n
    //!  - \b sData - Data to send
    //!  - \b rData - Received data
    //!  - \b rDataPoint - Used to keep track of the last position in the receive
    //!    stream for error checking
    //!
    //
    //#############################################################################
    // $TI Release: F2838x Support Library v2.01.00.00 $
    // $Release Date: Mon Dec 23 17:43:44 IST 2019 $
    // $Copyright:
    // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Globals
    //
    volatile uint16_t sData[2];                  // Send data buffer
    volatile uint16_t rData[2];                  // Receive data buffer
    volatile uint16_t rDataPoint = 0;            // To keep track of where we are in the
                                        // data stream to check received data
    
    //
    // Function Prototypes
    //
    void initSPIBMaster(void);
    void initSPIASlave(void);
    void configGPIOs(void);
    __interrupt void spibTxFIFOISR(void);
    __interrupt void spiaRxFIFOISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t i;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Interrupts that are used in this example are re-mapped to ISR functions
        // found within this file.
        //
        Interrupt_register(INT_SPIB_TX, &spibTxFIFOISR);
        Interrupt_register(INT_SPIA_RX, &spiaRxFIFOISR);
    
        //
        // Configure GPIOs for external loopback.
        //
        configGPIOs();
    
        //
        // Set up SPI B as master, initializing it for FIFO mode
        //
        initSPIBMaster();
    
        //
        // Set up SPI A as slave, initializing it for FIFO mode
        //
        initSPIASlave();
    
        //
        // Initialize the data buffers
        //
        for(i = 0; i < 2; i++)
        {
            sData[i] = 0+i;
            rData[i]= 0;
        }
    
        //
        // Enable interrupts required for this example
        //
        Interrupt_enable(INT_SPIA_RX);
        Interrupt_enable(INT_SPIB_TX);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Loop forever. Suspend or place breakpoints to observe the buffers.
        //
        while(1)
        {
            ;
        }
    }
    
    //
    // Function to configure SPI B as master with FIFO enabled.
    //
    void initSPIBMaster(void)
    {
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIB_BASE);
    
        //
        // SPI configuration. Use a 500kHz SPICLK and 16-bit word size.
        //
        SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                      SPI_MODE_MASTER, 500000, 16);
        SPI_disableLoopback(SPIB_BASE);
        SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_FREE_RUN);
    
        //
        // FIFO and interrupt configuration
        //
        SPI_enableFIFO(SPIB_BASE);
        SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_TXFF);
        SPI_setFIFOInterruptLevel(SPIB_BASE, SPI_FIFO_TX2, SPI_FIFO_RX2);
        SPI_enableInterrupt(SPIB_BASE, SPI_INT_TXFF);
    
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIB_BASE);
    }
    
    //
    // Function to configure SPI A as slave with FIFO enabled.
    //
    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_POL0PHA0,
                      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_TX2, SPI_FIFO_RX2);
        SPI_enableInterrupt(SPIA_BASE, SPI_INT_RXFF);
    
        //
        // Configuration complete. Enable the module.
        //
        SPI_enableModule(SPIA_BASE);
    }
    
    //
    // Configure GPIOs for external loopback.
    //
    void configGPIOs(void)
    {
        //
        // This test is designed for an external loopback between SPIA
        // and SPIB.
        // External Connections:
        // -GPIO24 and GPIO16 - SPISIMO
        // -GPIO25 and GPIO17 - SPISOMI
        // -GPIO26 and GPIO18 - SPICLK
        // -GPIO27 and GPIO19 - SPISTE
        //
    
        //
        // GPIO16 is the SPISIMOA clock pin.
        //
        GPIO_setMasterCore(16, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_16_SPISIMOA);
        GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(16, GPIO_QUAL_ASYNC);
    
        //
        // GPIO17 is the SPISOMIA.
        //
        GPIO_setMasterCore(17, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_17_SPISOMIA);
        GPIO_setPadConfig(17, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(17, GPIO_QUAL_ASYNC);
    
        //
        // GPIO18 is the SPICLKA.
        //
        GPIO_setMasterCore(18, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_18_SPICLKA);
        GPIO_setPadConfig(18, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(18, GPIO_QUAL_ASYNC);
    
        //
        // GPIO19 is the SPISTEA.
        //
        GPIO_setMasterCore(19, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_19_SPISTEA);
        GPIO_setPadConfig(19, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(19, GPIO_QUAL_ASYNC);
    
        //
        // GPIO24 is the SPISIMOB clock pin.
        //
        GPIO_setMasterCore(24, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_24_SPISIMOB);
        GPIO_setPadConfig(24, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(24, GPIO_QUAL_ASYNC);
    
        //
        // GPIO25 is the SPISOMIB.
        //
        GPIO_setMasterCore(25, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_25_SPISOMIB);
        GPIO_setPadConfig(25, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(25, GPIO_QUAL_ASYNC);
    
        //
        // GPIO26 is the SPICLKB.
        //
        GPIO_setMasterCore(26, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_26_SPICLKB);
        GPIO_setPadConfig(26, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(26, GPIO_QUAL_ASYNC);
    
        //
        // GPIO27 is the SPISTEB.
        //
        GPIO_setMasterCore(27, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_27_SPISTEB);
        GPIO_setPadConfig(27, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(27, GPIO_QUAL_ASYNC);
    }
    
    //
    // SPI A Transmit FIFO ISR
    //
    __interrupt void spibTxFIFOISR(void)
    {
        uint16_t i;
        static uint16_t temp=0;
    
        //
        // Send data
        //
        for(i = 0; i < 2; i++)
        {
           SPI_writeDataNonBlocking(SPIB_BASE, temp++);
        }
    
        //
        // Increment data for next cycle
        //
        for(i = 0; i < 2; i++)
        {
           sData[i] = sData[i] + 1;
        }
    
        //
        // Clear interrupt flag and issue ACK
        //
        SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_TXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
    }
    
    //
    // SPI B Receive FIFO ISR
    //
     __interrupt void spiaRxFIFOISR(void)
    {
        uint16_t i;
        static uint16_t temp=0;
    
        static uint16_t temp1 = 0xFFFF;
    
    
        //
        // Read data
        //
        for(i = 0; i < 2; i++)
        {
            rData[i] = SPI_readDataNonBlocking(SPIA_BASE);
        }
    
        //
        // Check received data
        //
        for(i = 0; i < 2; i++)
        {
            if(rData[i] != temp++)
            {
                // Something went wrong. rData doesn't contain expected data.
                ESTOP0;
            }
        }
    
    
        for(i = 0; i < 2; i++)
        {
               SPI_writeDataNonBlocking(SPIA_BASE, temp1--);
        }
    
        rDataPoint++;
    
        //
        // Clear interrupt flag and issue ACK
        //
        SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
    }
    

    Regards,

    Manoj

  • HI Manoj,

    i have looked at the code you setn , 

    1. I see you are using interrupt (while i am ussing Poll Mode ) , altough this not necessary the issue

    2. i am using two diffrent units , while in the code isse you are using same IC but diffreent SPI (e.g A,B)

    I think my issue is on the Slave Side   where i am wriiting to SPITXBUF , while receviing on SPI pin , as if

    instead of trasmiting what i wanted , the SPI Slave transmit what it recevice 

    for example normal  session

    SPI SALVE  SENDS  : 0x5500  0x5501 0x5502 0x5503 0x5504 0x5505 0x5506 0x5507

                     RECEVIE  :  0xAA00 0xAA01 0xAA02 0xAA03 0xAA04 0xAA05 0xAA06 0xAA07

    when error occur 

    SPI SALVE  SENDS  : 0x5500  0x5501 0x5502 0xAA03 0x5504 0x5505 0x5506 0x5507

                     RECEVIE  :  0xAA00 0xAA01 0xAA02 0xAA03 0xAA04 0xAA05 0xAA06 0xAA07

    the Slave mistakly sends 0xaa03  instead of  0x5503  (as if the recevie data enter the TX FIFO)  

    Could it  be ?

  • Eyal,

    I'm not in a position to guess what might have gone wrong. Would you mind sending code snippets?

    Regards,

    Manoj

  • HI Manoj ,

    I didnt meant to put in postion to guess , just tought you might encouter shuch issue  , or may be i am doing  somthing conceptually worng.

     i will smpilfy th structure of the code 

    // Initialize GPIO of SPI

    void ConfigureSPIGPIO()
    {
        EDIS;
    
        /*SPI_DIR  (Master=LOW,Slave=High) - Control 422 Line buffer*/
        GPIOSetupPinMux(SPIA_DIR_GPIO_INDEX, 0, 0);
        GPIOSetupPinOptions(SPIA_DIR_GPIO_INDEX, GPIO_OUTPUT, GPIO_SYNC);
    
        /*SIMOA*/
        GPIOSetupPinMux(SPIA_SIMO_GPIO_INDEX, 0, 1);
        GPIOSetupPinOptions(SPIA_SIMO_GPIO_INDEX, GPIO_OUTPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        /*SOMIA*/
        GPIOSetupPinMux(SPIA_SOMI_GPIO_INDEX, 0, 1);
        GPIOSetupPinOptions(SPIA_SOMI_GPIO_INDEX, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        /*CLKA*/
        GPIOSetupPinMux(SPIA_CLK_GPIO_INDEX, 0, 1);
        GPIOSetupPinOptions(SPIA_CLK_GPIO_INDEX, GPIO_OUTPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        /*STENA*/
        GPIOSetupPinMux(SPIA_CLK_GPIO_ENA, 0, 1);
        GPIOSetupPinOptions(SPIA_CLK_GPIO_ENA, GPIO_OUTPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        EALLOW;
    }


    //Initialize Of SPI Moudle (below are calling for Master / SALVE)
    void ConfigureSPI(sSPIConfig_t *pSPIConfig)
    {
        int lsp_clk_div, spi_bit_rate;
    
        /*Configure 422 Transceivers Direction (Master/Slave)*/
        if (pSPIConfig->spi_config_word.state.spi_mode == spi_master)
        {
            /*Set SPI_DIR to MASTER */
            SPIA_DIR_SET_MASTER();
        }
        else
        {
            /*Set SPI_DIR to SLAVE */
            SPIA_DIR_SET_SLAVE();
        }
    
        /*Configure and reset SPI FIFO*/
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
    
        /*Reset SPI*/
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        /*Clock Polarity & Data Latch */
        switch (pSPIConfig->spi_config_word.state.clk_scheme)
        {
        case spi_clk_pol_rising_edge:
            SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
            SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
            break;
        case spi_clk_pol_rising_edge_with_delay:
            SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
            SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
            break;
    
        case spi_clk_pol_faling_edge:
            SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
            SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
            break;
    
        case spi_clk_pol_faling_edge_with_delay:
            SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
            SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
            break;
    
        default:
            pSPIConfig->spi_config_word.state.spi_mode = spi_disable;
            break;
    
        }
    
        /*SPI Word length*/
        if (pSPIConfig->spi_config_word.state.spi_word_size <= spi_word_len_16bit)
            SpiaRegs.SPICCR.bit.SPICHAR = pSPIConfig->spi_config_word.state.spi_word_size;
    
        /*Loop-back*/
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        switch (pSPIConfig->spi_config_word.state.spi_mode)
        {
        case spi_slave:
            SpiaRegs.SPICTL.bit.MASTER_SLAVE = 0;
            SpiaRegs.SPICTL.bit.TALK = 1;
            pSPIConfig->spi_config_word.state.spi_baud_rate = spi_clk_5Mhz;
            break;
    
        case spi_master:
            SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
            SpiaRegs.SPICTL.bit.TALK = 1;
            break;
    
        case spi_slave_withot_transmit:
            SpiaRegs.SPICTL.bit.MASTER_SLAVE = 0;
            SpiaRegs.SPICTL.bit.TALK = 0;
            pSPIConfig->spi_config_word.state.spi_baud_rate = spi_clk_5Mhz;//spi_clk_5Mhz;
            break;
    
        case spi_disable:
            break;
        }
    
        /*SET SPI Baud rate*/
        switch (pSPIConfig->spi_config_word.state.spi_baud_rate)
        {
    
        /*LSPCLK=20Mhz ,SPIBRR=100 => 20e6/100=200Kbps*/
        case spi_clk_200khz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 100;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=50 => 20e6/50=400Kbps*/
        case spi_clk_400khz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 50;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=25 => 20e6/25=800Kbps*/
        case spi_clk_800khz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 25;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=20 => 20e6/20=1Mbps*/
        case spi_clk_1Mhz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 20;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=13 => 20e6/13=1.538Mbps*/
        case spi_clk_1_5Mhz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 13;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=10 => 20e6/10=2Mbps*/
        case spi_clk_2Mhz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 10;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=10 => 20e6/10=2Mbps*/
        case spi_clk_2_5Mhz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 8;
            break;
    
            /*LSPCLK=50Mhz ,SPIBRR=16 => 50e6/16=3.125Mbps*/
        case spi_clk_3Mhz:
            lsp_clk_div = 2;    //SYSCLK/4
            spi_bit_rate = 16;
            break;
    
            /*LSPCLK=50Mhz ,SPIBRR=16 => 50e6/14=3.57Mbps*/
        case spi_clk_3_5Mhz:
            lsp_clk_div = 2;    //SYSCLK/4
            spi_bit_rate = 14;
            break;
    
            /*LSPCLK=20Mhz ,SPIBRR=5 => 20e6/5=4Mbps*/
        case spi_clk_4Mhz:
            lsp_clk_div = 5;    //SYSCLK/10
            spi_bit_rate = 5;
            break;
    
            /*LSPCLK=40Mhz ,SPIBRR=1 => 50e6/10=5Mbps*/
        case spi_clk_5Mhz:
            lsp_clk_div = 2;    //SYSCLK/4
            spi_bit_rate = 10;
            break;
    
        default:
            lsp_clk_div = 2;    //SYSCLK/4
            spi_bit_rate = 100;
            break;
    
        }
    
        EALLOW;
        ClkCfgRegs.LOSPCP.bit.LSPCLKDIV = lsp_clk_div;
        EDIS;
    
        /*Set LSPCLK CLK*/
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = spi_bit_rate - 1;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        SpiaRegs.SPICCR.bit.HS_MODE = 0;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    
    }


    //main Initialzation
    void Initialization
    {
    ....
    ...
    ConfigureSPIGPIO();
    /*Test purpose only*/ sSPIConfig.spi_config_word.state.spi_mode=SPI_MODE; //spi_master or spi_slave , one for each target sSPIConfig.spi_config_word.state.spi_baud_rate =spi_clk_1Mhz;//spi_clk_1_5Mhz;//spi_clk_400khzspi_clk_400khz; sSPIConfig.spi_config_word.state.clk_scheme=spi_clk_pol_rising_edge; sSPIConfig.spi_max_num_of_words=8; sSPIConfig.spi_config_word.state.num_of_spi_tx_word =8; sSPIConfig.spi_config_word.state.spi_word_size =spi_word_len_16bit; sSPIConfig.debug_cnt=0; sSPIConfig.debug_err_flag=0; if (sSPIConfig.spi_config_word.state.spi_mode==1) { sSPIConfig.spi_tx[0]=MASTER_WORD; sSPIConfig.spi_tx[1]=MASTER_WORD; sSPIConfig.spi_tx[2]=MASTER_WORD; sSPIConfig.spi_tx[3]=MASTER_WORD; sSPIConfig.spi_tx[4]=MASTER_WORD; sSPIConfig.spi_tx[5]=MASTER_WORD; sSPIConfig.spi_tx[6]=MASTER_WORD; sSPIConfig.spi_tx[7]=MASTER_WORD; } else { sSPIConfig.spi_tx[0]=SLAVE_WORD; sSPIConfig.spi_tx[1]=SLAVE_WORD; sSPIConfig.spi_tx[2]=SLAVE_WORD; sSPIConfig.spi_tx[3]=SLAVE_WORD; sSPIConfig.spi_tx[4]=SLAVE_WORD; sSPIConfig.spi_tx[5]=SLAVE_WORD; sSPIConfig.spi_tx[6]=SLAVE_WORD; sSPIConfig.spi_tx[7]=SLAVE_WORD; } ConfigureSPI(&sSPIConfig); }





    /*SPI READ/WRITE for Master and Slave called every 1ms for interrupt*/
    unsigned short SPIWriteRead(sSPIConfig_t *pSPIConfig)
    {
    
        int i, max_rx_spi_word;
    
        if (pSPIConfig->spi_config_word.state.spi_mode != spi_disable)
        {
            /*Check if there is SPI Data Received (Previous season) */
            if (SpiaRegs.SPIFFRX.bit.RXFFST > 0)
            {
                if (SpiaRegs.SPIFFRX.bit.RXFFST > pSPIConfig->spi_max_num_of_words)
                {
                    max_rx_spi_word = pSPIConfig->spi_max_num_of_words;
                }
                else
                {
                    max_rx_spi_word = SpiaRegs.SPIFFRX.bit.RXFFST;
                }
    
                /*Read Previous SPI Data*/
                for (i = 0; i < max_rx_spi_word; i++)
                    pSPIConfig->spi_rx[i] = SpiaRegs.SPIRXBUF;
    
                /* Update Number of Data Received*/
                pSPIConfig->spi_rx_num_of_words = max_rx_spi_word;
    
                if (pSPIConfig->spi_config_word.state.spi_mode == spi_slave)
                {
                    /*Check that TX FIFO is Not FULL*/
                    if ((16 - pSPIConfig->spi_config_word.state.num_of_spi_tx_word) > SpiaRegs.SPIFFTX.bit.TXFFST)
                    {
                        /*Transmit*/
                        for (i = 0; i < pSPIConfig->spi_config_word.state.num_of_spi_tx_word; i++)
                        {
                            SpiaRegs.SPITXBUF = pSPIConfig->spi_tx[i];
                        }
                    }
    
                }
    
            }else   pSPIConfig->spi_rx_num_of_words=0;
    
            if (pSPIConfig->spi_config_word.state.spi_mode == spi_master)
            {
                /*Check that TX FIFO is Not FULL*/
                if ((16 - pSPIConfig->spi_config_word.state.num_of_spi_tx_word) > SpiaRegs.SPIFFTX.bit.TXFFST)
                {
                    /*Transmit*/
                    for (i = 0; i < pSPIConfig->spi_config_word.state.num_of_spi_tx_word; i++)
                    {
                        SpiaRegs.SPITXBUF = pSPIConfig->spi_tx[i];
                    }
                }
            }
    
        }
        return 0;
    }
    

    
    
    ....

    //External Interrupt (FROM FPGA ) , every 50us __interrupt void exInterrupt_isr(void) { /*Generic Function Pointer*/ /*1st Stage - Call DSPCodeLoading() - Load DSP Servo Control into RAM */ /*2nd Stage - Call Servo Tick (loaded by MPU into RAM) */ hal.tick(); //do some work hal.counter++; //every 1ms (e.g. 20*50us=1,ms) if (hal.counter>=20) { SPIWriteRead(&sSPIConfig); } EALLOW; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; EDIS; }

    
    

  • Eyan,

    Max TX FIFO length used in your code is 8.

    I'm not sure about the highlighted logic below. Shouldn't you fill the TX FIFO only when previous contents are transmitted. In the below code, you seem to fill the TX FIFO 8 times irrespective of what has been transmitted previously. If your TX FIFO is partially transmitted, you should only fill the remaining TX FIFO and not the full FIFO again. I think your logic should look something like this.

    Regards,

       Manoj

  • Hi Manoj,

    you are correct in some way , but there is assumption that is valideated   , the function that you are refering is called every 1ms

    the  SPI Master  (in the case you are showing ) will start transmission until FIFO is empty  which will take him  around  50us ...100us s (frequency 2.5Mhz..1Mhz)  SPI CLK.

    so on the next 1ms cycle the SPI master TX FIFO is empty

  • Sorry, I couldn't follow what you are trying to say.

    -Manoj

  • I haven't heard back from you in a while. Is this issue resolved?

  • Hi manjo ,

    sorry for the late update , the issue was due to implmention ,as two untis retrive information each 1ms  on the slave side this is issue , as there will some difirt (not just offset ) what could this cause that in some case SPI Slave will not be able to catch all the required word , so the fix for it is to add sort of shawo buffer to retrive only when the requried number of SPI word has been recevied.

    BR , Eyal