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.

F28069F SPI Master/slave communication.

Other Parts Discussed in Thread: CONTROLSUITE

Hello Team,

I need to establish SPI master/slave communication between two f28069f microcontrollers for motor control application.

The microcontroller boards have only following pins for SPI communication in both the boards:
SPI-B MOSI -> pin 97, GPIO24.
SPI-B SOMI -> pin 95, GPIO25.
SPI-B sclk -> pin 96, GPIO14.
SPISTEB pin is not configured for any of the predefined SPI module pins in the microcontroller, it is used for the other purpose in both the boards.
GPIO58 pin available, for configuring it has slave enable transmission pin(SPISTEB pin) in both the boards.
I want to know, whether I could use the GPIO58 pin has the SPISTEB pin in both the master and slave boards for slave enable transmission(SPISTEB). Since it doesn't belong to any of the predefined SPI module pins.
If it is possible, could please provide me the steps, or document to use the GPIO58 pin as the SPISTEB for both the Master/Slave configuration.
Requesting to please do the needful.


Thanks and best regards,
Chetan.

  • Hi Chetan,

    Let me make it very simple: you can use slave select on any GPIO (SPISTE not required). Just that you need to keep playing with this GPIO to enable and disable when required and not respectively.

    Regards,

    Gautam

  • Chetan,

    There are a few things to consider here.

    1. The SPI master is able to manually control any GPIO to act as a Chip Select Signal. It must be controlled by the Software using standard GPIO Set/Clear. There are Various forum threads on this topic. Please use the Search to find them.

    2. The SPI Slave is only able to use the GPIOs that have the SPISTEB signal muxed into it. There are a few options available to you if you cannot reallocate your GPIOs such that you have SPISTEB brought to a pin.

    a. Do not bring out SPISTEB to any pin. If the Signal is not muxed to any pins, the default state is enabled. If the SPI Slave is always enabled, the SPI Slave will interpret any transition on SPICLK as a valid clock edge and act appropriately. We do not recommend this as the SPI Slave is susceptible to noise and could cause the Master/Slave link to become corrupted. You may be able to handle this resynchronization using software.

    b. You may be able to implement Some sort of custom software synchronization using GPIO58. On the Slave side, you could hold the SPI in reset, preventing it from receiving any data. If the Master sends a trigger to the Slave, the Slave could exit reset and then handle any data input/output required. once the transmission is complete, the Slave would again enter reset to prevent any corruption.

    I hope this gives you some ideas. If I misinterpreted your question, please let me know.

    -Mark

  • Hello Gautham and Mark,

    Thanks for your inputs.

    I was able to establish SPI communication between both the boards, I have connected the SPITEB pin to ground, and keeping it low in the GPIO initialization.

    But now the problem, data I receive in slave from the master is getting shifted.

    An example of the data being transmitting from Master to Slave.
    Master || Slave

    0x1111 || 0x4444
    0x2222 || 0x8888
    0x0010 || 0x0040
    0xF00F || 0xC03F.

    In the above example, data is getting shifted by one bit.
    At times, bits gets shifted by two or three bits place. Same happens when the data is transmitted from slave to master too.

    I am writing the data in SPITXBUF register in the master, I am reading the received data from SPIRXBUF of the slave.


    Settings in my Master and slave programs are as follows :

    SysCtrlRegs.LOSPCP.all = 0x0006; / same clk for both master and slave.

    SPI intialization for master as follows :

    SpibRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
    SpibRegs.SPICCR.all=0x000F; //16-bit character, Loopback mode
    SpibRegs.SPICTL.all=0x0017; //Interrupt enabled, Master/Slave XMIT enabled
    SpibRegs.SPISTS.all=0x0000;
    SpibRegs.SPIBRR=0x007F; // Baud rate
    SpibRegs.SPIFFTX.all=0xC022; // Enable FIFO's, set TX FIFO level to 4
    SpibRegs.SPIFFRX.all=0x0022; // Set RX FIFO level to 4
    SpibRegs.SPIFFCT.all=0x00;
    SpibRegs.SPIPRI.all=0x0010;
    SpibRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
    SpibRegs.SPIFFTX.bit.TXFIFO=1;
    SpibRegs.SPIFFRX.bit.RXFIFORESET=1;

    SPI intialization for Slave as follows :
    SpibRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
    SpibRegs.SPICCR.all=0x000F; //16-bit character, Loopback mode
    SpibRegs.SPICTL.all=0x0013; //Interrupt enabled, Master/Slave XMIT enabled
    SpibRegs.SPISTS.all=0x0000;
    SpibRegs.SPIBRR=0x007F; // Baud rate
    SpibRegs.SPIFFTX.all=0xC022; // Enable FIFO's, set TX FIFO level to 4
    SpibRegs.SPIFFRX.all=0x0022; // Set RX FIFO level to 4
    SpibRegs.SPIFFCT.all=0x00;
    SpibRegs.SPIPRI.all=0x0010;
    SpibRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
    SpibRegs.SPIFFTX.bit.TXFIFO=1;
    SpibRegs.SPIFFRX.bit.RXFIFORESET=1;

    Please let me know if anything has to be checked or changed.

    Please find the attached screenshot.

    In the above screen:

    Yellow waveform : MOSI.

    Green waveform : SYSCLK  on the master side.

    Pink waveform : SPISTE pin output, which is connected to ground.

    Blue waveform : SYSCLK on the  slave side. 




    Thanks in advance.

    Best regards,
    Chetan.

  • Chetan,

    Does the data start out being shifted, or does the data become out of sync after some time? 

    If the data starts out shifted, It sounds like there is an extra clock edge early before your master begins it's transmission. 

    To be clear, the SPISTE on the Slave side is tied to ground? meaning that the pink signal is "SPISTE 'input'" instead of output? as I mentioned in my previous post. Tying the SPISTE to GND opens up your system to this sort of issue. Since the slave is always active, it will react to ANY transition on SPICLK, even noise. Please ensure that there are no unintentional transitions on SPICLK.

    -Mark

  • Hello Mark,

    Thanks for the reply.

    Does the data start out being shifted, or does the data become out of sync after some time?
    - Data start out being shifted.

    To be clear, the SPISTE on the Slave side is tied to ground? meaning that the pink signal is "SPISTE 'input'" instead of output? as I mentioned in my previous post. Tying the SPISTE to GND opens up your system to this sort of issue. Since the slave is always active, it will react to ANY transition on SPICLK, even noise. Please ensure that there are no unintentional transitions on SPICLK.

    - SPISTE were tied to ground pin in the both master and slave side and I had interconnected the ground pins of the master and slave.
    - GPIO58 (SPISTEB), I hava intialized as output on the master side and input on the slave side.
    - I removed the connected SPISTEB from ground and connected the SPISTEB pin from master to slave, but still no luck :(.

    GPIO Intialization
    Master side :
    GpioCtrlRegs.GPAPUD.bit.GPIO24 = 1; // Enable pull-up on GPIO24 (SPISIMOB)
    GpioCtrlRegs.GPAPUD.bit.GPIO13 = 1; // Enable pull-up on GPIO13 (SPISOMIB)
    GpioCtrlRegs.GPAPUD.bit.GPIO14 = 1; // Enable pull-up on GPIO14 (SPICLKB)
    GpioCtrlRegs.GPBPUD.bit.GPIO58 = 1; // Enable pull-up on GPIO58 (SPISTEB)

    GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 0; // 0=GPIO, 1=MCLKRA, 2=SCITXDB, 3=EPWM7A
    GpioDataRegs.GPBCLEAR.bit.GPIO58 = 1; // uncomment if --> Set Low initially
    //GpioDataRegs.GPBSET.bit.GPIO58 = 1; // uncomment if --> Set High initially
    GpioCtrlRegs.GPBDIR.bit.GPIO58 = 1; // 1=OUTput, 0=INput

    /* Set qualification for selected pins to asynch only */
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 3; // Asynch input GPIO24 (SPISIMOB)
    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3; // Asynch input GPIO13 (SPISOMIB)
    GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 3; // Asynch input GPIO14 (SPICLKB)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO58 (SPISTEB)


    /* Configure SPI-B pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be SPI functional pins.
    // Comment out other unwanted lines.


    GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 3; // Configure GPIO24 as SPISIMOB
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 3; // Configure GPIO13 as SPISOMIB
    GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 3; // Configure GPIO14 as SPICLKB
    GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO58 as SPISTEB


    I have the same intailization on the slave side too, but I have set the GPIO58 has a input on the slave side.
    GpioCtrlRegs.GPBDIR.bit.GPIO58 = 0; // 1=OUTput, 0=INput

    Best regards,
    Chetan
  • Chetan,

    It sounds like your Slave is detecting a transition on the clock line during initialization. Depending on the order of power up between master and slave. Your comments are incorrect for the Pull-up control. Setting GPxPUD to 1 will disable the pull-ups. It's up to you what mode you would like, but I just want to make sure that you may not be doing what you think you are.

    It also looks like you are reconfiguring GPIO58 to be EPWM7A after you already configure it to be GPIO mode.

    If you would like to use GPIO58 as a custom chip select, or Slave enable, the following strategy should help to guard the slave against any unintentional transitions on the SPICLK line.

    1. Master drive GPIO58 "active"
    2. Slave detect GPIO58 as active by polling, or by XINT
    3. Slave release SPI slave from reset.
    4. Master start transmission.
    5. Master end transmission.
    6. Master drive GPIO58 "inactive"
    7. Slave detects GPIO58 as inactive/
    8. Slave puts SPI into reset.

    -Mark
  • Hello Mark,

    Thanks for your inputs.

    Since I couldn't find the details how to convert the GPIO58 to the custom slave enable, so I was following this procedure.

    If I haven't understood instructions wrong, I would follow following procedure.

    1. Master drive GPIO58 "active"
    - Set GPIO58 as output and make it low.

    2. Slave detect GPIO58 as active by polling, or by XINT
    - Use external interrupt to make the slave pin active low.

    3. Slave release SPI slave from reset.
    - Slave SPI module is enabled.

    4. Master start transmission.
    - Data is sent from SPITXBUF.

    5. Master end transmission.
    - After the data is recieved by the slave(SPIRXBUF).

    6. Master drive GPIO58 "inactive"
    - Master should set SPISTE pin to high.

    7. Slave detects GPIO58 as inactive
    - Use XINT to detect the high and slave should be inactive.

    8. Slave puts SPI into reset.

    Please correct me if I am wrong at any of the step.


    Best regards,
    Chetan

  • Chetan,

    This looks like it is the correct procedure. Please try it out and report back your results.

    I believe that the underlying issue probably that the default state of GPIO14( your SPICLK) is input with pullup enabled. If your SPI slave comes up before the master, it will see the SPICLK as High. When you reconfigure the master GPIOs to use SPI, and then enable the SPI module, SPICLK is driven to 0. since the SPI Slave is already enabled, it will act on this transition and clock in data.
    I think you are seeing how important the SPISTE signal is for the SPI module. You are relying on a software workaround to handle what is done in hardware. If you have the chance to revise your board, I strongly suggest bringing out the SPISTEB on the slave side to a pin as it will free up some software complexity and delays.

    Thanks,
    Mark
  • Hello Mark,

    I made the changes to the program as following.
    1. GPIO58 pin was set has an output on the master side and it's initial value is kept high.
    2. GPIO58 pin on the slave side is configured has input, and it's default value is high.
    3. When the transfer interrupt ISR starts the GPIO58 pin on the master side is set low, which should cause the GPIO58 pin low on the slave side, since they are interconnected.
    4. After the data is written to the SPITXBUF, GPIO58 pin is set high again on the master side.

    With the above settings, I thought GPIO58 pin would be low until the data is transferred to the slave.
    But GPIO58 would go low only for a short duration when the data is written to the SPITXBUF and it won't go low until data is received on the slave side.
    Please find the screen for the same.
    Yellow > SYSCLK.
    Green > SPISTE.
    Pink > MOSI.


    I wanted to know is there any method which I can use to keep the GPIO58 pin low until data is received on the slave side.

    I am not sure about how to XINT in this situation since I wasn't able to find any help online either.

    I have also attached my master/slave code composer files.

    spi.zip

    Could you please help me with this.

    Thanks in advance.

    Best regards,
    Chetan.

  • Hello Mark,

    I made the changes to the program as following.
    1. GPIO58 pin was set has an output on the master side and it's initial value is kept high.
    2. GPIO58 pin on the slave side is configured has input, and its default value is kept high.
    3. When the transfer interrupt ISR starts the GPIO58 pin on the master side is set low, which should cause the GPIO58 pin low on the slave side, since they are interconnected.
    4. After the data is written to the SPITXBUF, GPIO58 pin is set high again on the master side.

    With the above settings, I thought GPIO58 pin would be low until the data is transferred to the slave.
    But GPIO58 would go low only for a short duration when the data is written to the SPITXBUF and it won't go low until data is received on the slave side.

    Please find the screen for the same.
    Yellow > SYSCLK.
    Green > SPISTE.
    Pink > MOSI

    I wanted to know is there any method which I can use to keep the GPIO58 pin low until data is received on the slave side.

    I am not sure about how to XINT in this situation since I wasn't able to find any help online either.

    I have also attached my master/slave code composer files.

    2112.spi.zip

    Could you please help me with this.

    Thanks in advance.


    Best regards,
    Chetan.

  • Chetan,

    I quickly looked at the master code. It is behaving exactly how you programmed it to behave. The TX ISR will load the next words into the FIFO. This happens much faster than it takes to actually send the data out of the SPI. You will need to have a little bit more manual control over GPIO58, especially since you need to release the SPI Slave from reset.

    Please search for custom SPI drivers online. They should provide you with an example of how you should do this from the master side. The basic idea is that you may not be able to always use the SPI interrupts on the master side. There is a program flow that will need to be followed.
    1. Application code
    2. Transmit/receive phase
    2a. Set GPIO58 active
    2b. Fill SPITXBUF with data
    2c. Wait for data to be completely transmitted (RX FIFO status)
    2d. Clear GPIO58 to inactive
    3. Return to 1.

    There is an example in controlSuite for the XINT, or External interrupt: "C:\ti\controlSUITE\device_support\f2806x\v151\F2806x_examples_ccsv5\external_interrupt"

    I hope this helps get you moving forward.

    -Mark
  • Hello Mark,

    Thanks for your inputs.

    I was thinking of implementing following changes SPI transfer isr in both the master and slave. Since I am not able to figure out a better way to know the status of the receiver register on the slave side, until I have communication working in one way properly.

    On the master side, GPIO58 pin status is kept low until the data is received from the slave. On the slave side data transmission starts only after it receives the data from the master.

    Code snippet for the same.
    Master side ::
    __interrupt void spiTxFifoIsr(void)
    {
    // SpibRegs.SPICCR.bit.SPISWRESET=1;
    GpioDataRegs.GPBCLEAR.bit.GPIO58 = 1;
    Uint16 i;
    for(i=0;i<2;i++)
    {
    SpibRegs.SPITXBUF=sdata[i]; // Send data
    }

    while(SpibRegs.SPIFFRX.bit.RXFFST !=2) {} // wait for the data to be received on the master side, from slave.

    SpibRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flag
    PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ACK


    GpioDataRegs.GPBSET.bit.GPIO58 = 1;
    }

    Slave side ::

    __interrupt void spiTxFifoIsr(void)
    {

    while(SpibRegs.SPIFFRX.bit.RXFFST !=2) {} // wait for the actual data to be received on the master.

    Uint16 i; for(i=0;i<2;i++)
    {
    SpibRegs.SPITXBUF=sdata[i]; // Send data
    }


    SpibRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flag
    PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ACK

    }


    Do you think this would help in keeping the SPISTE pin low, until the data is transferred from the master?
    I would be happie, if the data is transmitted from master to slave side correctly.

    Thanks in advance

    Best regards,
    Chetan.
  • Hello Mark,

    I was able to get the waveforms for the GPIO58 has it was discussed earlier. But I am still getting error in my data received in the slave.

    Please find the attached screen for the same.

    Green : GPIO58(SPISTE)

    Yellow : SYSCLK.

    Pink : MOSI.

    In the screen below, data sent is (0xABCD) from master on the falling edge of the sysclk.

    Data sent matches the waveform of MOSI.

    Please do let me know if anything has to be checked or changed.

    Thanks and best regards,

    Chetan

  • Chetan,

    Can you try to provide a delay in between each transmission and see if that helps?

    -Mark

  • Hello Mark,

    Thanks for your inputs.

    I would try that.

    best regards,
    Chetan
  • Hello Mark,

    Thanks for your inputs and suggestions previously.
    SPI communication between boards works, with one-bit shift, since it is constant always, I was able to do manipulation at the receiver side to match the requirement.

    I have few doubts and questions.
    1. I came across one of the TI forum, where it was told bit-shift is due to synchronization problem between the SPI module pins.
    2. In my case, GPIO58 pin is used to act has SPISTE pin and it is not synchronized to the SPI module clock. Is that the reason for this bit shift ?
    3. If that's the case, is there a way to synchronize GPIO58 pin with the SPI module clock ?

    Best regards,
    Chetan.
  • Chetan.
    let me answer your questions

    1. Yes. The issue you are having is all to do with synchronization. Your Slave is likely receiving an extra clock edge very early before the transmitter is actually transmitting. I suspect that your slave is configured and waiting for transmission before the transmitter is configured. The default state of GPIO14 (your SPICLK pin) is an input with pullups enabled. This means that when the GPIO is reconfigured to be the SPICLK, the pin will be driven low. If the Slave is configured and ready to receive data, which I suspect is the case, when the transmitter is configured, the Pin is driven low. The slave interprets this as a valid clock edge, so the state of the MOSI pin is interpreted as valid (how it would know otherwise?) and your slave is now off by 1 bit forever. until you resynchronize.
    2/ 3. Correct, GPIO58 is not able to actually be synchronized with the SPICLK the way SPISTE is. The strategy I have repeatedly recommended is a way in which you are able to synchronize the SPI master and slave by holding the Slave in reset until the master is prepared to transmit.

    Regards,
    Mark