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.

MSP430FR5992: Facing transmit and receive issue in spi protocol

Part Number: MSP430FR5992

Hi TI team, 

I am using spi protocol  which involves imx8 as master and msp430fr5992 as slave.

MSP430FR5992 will receive some packet, do some processing and send back the processed data to imx.

We are able to receive 32 bytes(packets) from imx8 and process the data also. But we are not able to transmit 32 bytes at a time.

Below is the spi configuration: 

void Spi_slave_init()
{
// Configure GPIO: SEL0+SEL1
P1SEL1 |= (BIT6); //USCI_B0 MOSI
P2SEL1 |= (BIT2); //USCI_B0 CLK
P1SEL1 |= (BIT7); //USCI_B0 MISO pin
P1SEL1 |= (BIT3); //Chip Select Pin

P1SEL0 &= ~(BIT6); //USCI_B0 MOSI
P2SEL0 &= ~(BIT2); //USCI_B0 CLK
P1SEL0 &= ~(BIT7); //USCI_B0 MISO pin
P1SEL0 &= ~(BIT3); //Chip Select Pin

PJSEL0 |= BIT4 | BIT5;

// Configure USCI_B0 for SPI operation
UCB0CTLW0 = UCSWRST; // **Put state machine in reset**
// 4-pin, 8-bit SPI slave
UCB0CTLW0 |= UCSYNC | UCCKPL | UCMSB | UCMODE_2 ; // Clock polarity high, MSB
UCB0CTLW0 &= ~UCCKPH; // Clock Phase = LOW
UCB0CTLW0 |= UCSSEL_0; //UCLK for slave mode
UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
UCB0IE |= UCRXIE; // Enable USCI_B1 RX interrupt
}

This is how we are receiving the packet:

for( index_spi=0; index_spi<MAX_SPI_FRAME ; index_spi++) //MAXIMUM_SPI_FRAME
{
while(!(UCB0IFG & UCRXIFG)){};
SPIRxData[index_spi]= UCB0RXBUF; //Storing the data received from receive buffer into an array
UCB0IFG &= ~UCRXIFG;
}

This is how we are transmitting the processed data:

for(index_tx=0; index_tx< TxLength; index_tx++) //Decide how many bytes to transmit based upon Txlength
{
 while(!(UCB0IFG & UCTXIFG)){}; 
UCB0TXBUF = SPI_TXData[index_tx]; // Transmit data to imx
}

In this transmit function we are able to transmit only one byte. We are not able to send the entire packet. We are able to send the entire packet at the time when we are receiving the next packet.

If any solution you have to transmit the entire packet at a time let me know.

Regards

Abhisek

  • Hi Abhisek,

    When MSP430 as the SPI slave, the colock should controled by master, I means that IMX8, does master send out 32 clock to read some data?

    Do you try to capture some waveform via oscilloscope or logic analyzer?

    Thanks!

    Best Regards

    Johnson

  • Hi Johnson,

    Yes you are correct. Clock is controlled by the master. My client is working on imx side. I have not captured any waveform. I will check and let you know.

    But if you are thinking that if i have written anything wrongly then let me know.

    Regards

    Abhisek

  • Hi Abhisek,

    for(index_tx=0; index_tx< TxLength; index_tx++) //Decide how many bytes to transmit based upon Txlength
    {
     while(!(UCB0IFG & UCTXIFG)){}; 
    UCB0TXBUF = SPI_TXData[index_tx]; // Transmit data to imx
    }

    The TXLength is 32 correct?

    I find you don't enable interrupt yo send data to master, maybe you can try this method.

    Thanks!

    Best Regards

    Johnson

  • Hi,

    Yes TXLength is 32 bytes. 

    You are saying to enable transmit interrupt in Spi_slave_init() function like mentioned below?

    UCB0IE |= UCTXIE;

    Regards

    Abhisek

  • Hi Abhisek,

    Yes, like this example:

    https://dev.ti.com/tirex/explore/node?node=A__ADeJDaaRpnLDh0uux5v45w__msp430ware__IOGqZri__LATEST

    This example is echo received data.

    Thanks!

    Best Regards

    Johnson

  • Hi johnson,

    Do I need to involve ISR ?

    Regards

    Abhisek

  • Hi Abhisek,

     

    Yes, this will be better.

    Thanks!

    Best Regards

    Johnson

  • Hi Johnson,

    While echoing back the received data using isr we are getting like this. Following below is the putty output:- TX is sent by imx and RX is receive by imx.

    TX | 5A 31 33 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 31 0A 
    RX | 00 00 5A 31 33 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 

    TX | 5A 31 33 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 31 0A 
    RX | 31 0A 5A 31 33 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39 |

    Please let me know why this 2 byte shifting is happening while echoing back the received data.

    regards

    Abhisek

  • SPI is a full-duplex protocol, where Tx and Rx operate simultaneously. What this means is that when the slave sends its first byte, it has not yet received its first byte. This is not a coding problem, rather it is a logical/information problem, and is common (in various forms) to all SPI slaves.

    Thus for an "echo" application the slave starts out off-by-1, and depending on how the code is triggering the Tx, by the time it actually loads TXBUF the second byte from the master may already be in progress, putting it off-by-2.

    I'm guessing that "echo" is not your final application, so maybe this is a good time to consider your goal protocol. Some slaves simply say to the master "ignore the first byte you get back". Others pre-load TXBUF with (e.g.) a status byte with a well-known definition, so the first byte has at least some value. 

  • Hi, 

    Can we use for loop for receiving and transmitting packets inside isr?

    Regards

    Abhisek

  • No, for an ISR you need to follow the Hubert Hawkins rule:

    Hubert Hawkins: I'd like to get in, get on with it, get it over with, and get out. Get it?

    Ravenhurst: Got it.

    Hubert Hawkins: Good.

    From "The Court Jester"

    i.e., spend as little time as possible in the ISR. It is best to have the ISR just fill or read from a buffer.

  • Setting aside the byte-shift, I don't see any missing bytes in your trace, so it appears your slave is able to keep up with the byte-pacing from the master. Being off by (at least) 1 is intrinsic, since the slave doesn't know what to send for the first byte.

    Re-reading your original post, it appears that this sort of streaming protocol is not what you had in mind. I think you were picturing (a) master sends 32 bytes to slave (b) slave works on the data while the master pauses [time delay or GPIO signaling] (c) master fetches the result 32 bytes. For this the master would perform 2x separate 32-byte transactions: the first Tx-only for (a), and the second Rx-only for (c). The key here is that by the time the second (Rx-only) transaction starts, the slave already knows the answer and can pre-load TXBUF. [Unsolicited: DMA fits this model well.]

    SPI always does Tx and Rx simultaneously. By Tx-only I mean the master sends 32 bytes but ignores what it gets back, and Rx-only means that the master sends 32 arbitrary ("dummy") bytes and captures what it gets back as the answer.

  • On the L6470 stepper controller I am currently using, you transmit a "command" byte, and receive all zeros. Then the master transmits as many 0 bytes as required to receive the data requested from the slave. So I do something like this:

    uint32_t GetParam3(uint8_t param)
    {
    
        uint8_t rxdata = 0;
        uint32_t data = 0;
    
        // Send command
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN4);
    
        SPI_transmitData(EUSCI_B0_BASE, GET_PARAM | param);
    
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_TRANSMIT_INTERRUPT)));
    
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_RECEIVE_INTERRUPT)));
    
        // should be 0
        rxdata = SPI_receiveData(EUSCI_B0_BASE);
    
    
        MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN4);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN4);
    
        // Get MSB
        SPI_transmitData(EUSCI_B0_BASE, NOP);
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_TRANSMIT_INTERRUPT)));
    
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_RECEIVE_INTERRUPT)));
    
        rxdata = SPI_receiveData(EUSCI_B0_BASE);
        data = (rxdata << 16);
    
        MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN4);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN4);
    
        // Get middle bit
        SPI_transmitData(EUSCI_B0_BASE, NOP);
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_TRANSMIT_INTERRUPT)));
    
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_RECEIVE_INTERRUPT)));
    
        rxdata = SPI_receiveData(EUSCI_B0_BASE);
        data = data | (rxdata << 8);
    
        MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN4);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN4);
    
        // Get Second Byte
        SPI_transmitData(EUSCI_B0_BASE, NOP);
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_TRANSMIT_INTERRUPT)));
    
        while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_SPI_RECEIVE_INTERRUPT)));
    
        rxdata = SPI_receiveData(EUSCI_B0_BASE) ;
        data |= rxdata;
    
        MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN4);
    
        return data;
    }

    Where NOP is all bits zero. YMMV for your device

  • Hi,

    How much approximate  time delay we should give between 1st set of TX and RX and 2nd set of TX and RX?

    Regards

    Abhisek

  • How long does your slave take to process the data (step (b) above)?

    If all it's doing is sending the same data back (packet-by-packet) the delay could be near 0 [just put the received data directly into the transmit buffer].

    If it's doing an FFT, budget (at least) a few 10s of milliseconds.

    If you have an oscilloscope/logic analyzer, a common technique for measuring computation time is to adopt a spare GPIO pin and set it (e.g.) high at the beginning and low at the end.

  • The data sheet should tell you. If it doesn't, 0 delay should be fine.

  • Hi, 

    I have also used timer for led control in my code as I performing led control along with some other tasks. I have used isr for timer also. Can the timer for led control affect the spi transmit and receive of data sometimes?

    Beacuse sometimes we are getting data like this from msp microcontroller

    TX | 5A 31 33 35 37 FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    TX | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    elapsed time: 0.312349s
    TX | 5A 31 33 35 37 FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
    RX | 00 00 55 24 33 40 10 0B 5B FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 42 00 
    TX | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
    RX | 00 00 55 24 33 40 10 0B 5B FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 42 00 

    Instead of getting data packets like mentioned below:
    TX | 5A 31 33 35 37 FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    TX | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
    RX | 00 00 55 24 33 40 10 0B 5B FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 42 00 

    Please let me know if I have to make some changes.

    Regards

    Abhisek

  • It shouldn't interfere. I think it is time to pull out the scope.

  • At first glance it looks as though sometimes the slave's computation (step (b)) takes longer than expected. Do things improve if the master delays longer before reading the result?

  • Hi bruce,

    I will look into it and let you know.

    Regards

    Abhisek

  • Hi Abhisek,

    Does this issue have been resolved? Do you need futher support?

    Thansk!

    Best Regards

    Johnson

  • Hi Johnson,

    Until now I am not getting any errors.

    If I need further support I will let you know.

    Regards

    Abhisek

**Attention** This is a public forum