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.

MSP430F5503: SPI RX Problem

Part Number: MSP430F5503


Tool/software:

I am using the SPI of my MSP430F5503 as a slave on the UCB1 interface with the following configuration.

 UCB1IFG &= ~UCRXIFG;

    UCB1CTL1 = UCSWRST;                         // Enable SW reset - Starts config mode
    UCB1CTL0 = UCSYNC + UCCKPH + UCMODE_2; 
    UCB1RXBUF = 0x00;
    UCB1TXBUF = 0x00;
    UCB1CTL1 &= ~UCSWRST;               // **Initialize USCI state machine** - restart usci with new settings

    _NOP();
    UCB1IE |= UCRXIE ;        // UCB1 RX & TX Interrupt enable

At the beginning of the program start, the SPI works, and both sending and receiving function without any issues. It does what it is supposed to. The USCI40 error from the Errata Sheet also does not occur, and sending as a slave is not affected.

After an indefinite period, sometimes 2 hours, sometimes 1 day, the microcontroller stops receiving data correctly over SPI. I have checked this with the logic analyzer, see below:

However, instead of receiving 0xBC, the microcontroller receives 0x78—binary, instead of 0b1011 1100, it gets 0b0111 1000. You can see that the byte is suddenly shifted one bit to the left. Resetting the SPI doesn't help; only a restart of the msp430 fixes the problem.

Transmitting over SPI, i.e., TX, still works.

Below I have included the code of my SPI interrupt again. Maybe I am already making a major mistake here.

#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_interrupt(void)
{

    switch(__even_in_range(UCB1IV,4))
    {
        case 0: break;                          // Vector 0 - no interrupt
        case 2:

            //////////////////////////
            //// SPI RX Interrupt ////
            //////////////////////////
//            LPM0_EXIT;

            if(knx_txstate != KNX_TXSTATE_IDLE && knx_txstate != KNX_TXSTATE_WAIT)
            {
                __delay_cycles(200 cyclesPerUs);
                ncn51_tx_nextbyte(true);
            }
            else
            {
                UCB1TXBUF = 0x00;
            }

            // Byte received, read and clear flag
            char rxbyte;
            rxbyte = UCB1RXBUF;
            if(rxbyte == 0xBC){
                knx_txstate = KNX_TXSTATE_WAIT;

            }

            LED2_ON;

            // store into ringbuffer
            if(ringbufferIsFull(&spi_rx_buf) || (utilNormalizeOverflowDiffInt(TA0R, lastReceive) < 1000 ticksPerUs) && knx_txstate != KNX_TXSTATE_IDLE){
            _NOP()
            }
            else{
                lastReceive=TA0R;
                ringbufferPushElement(&spi_rx_buf,(unsigned char *) &rxbyte);

            }
            break;


        case 4:
    //////////////////////////
    //// SPI TX Interrupt ////
    //////////////////////////
        default: break;
    }
}

I've run out of ideas. Maybe someone has ideas or can give me tips on what I can try. If more information is needed, I will, of course, provide it as quickly as possible.

  • Hi,

    Can I see the waveform about wrong data?

    I think it might be due to the timing error for CLOCK, CS and data.

    Regards,

    Zoey

  • Unfortunately, I don't have a picture available at the moment. When the problem occurs, I will take one and share it with you.

  • Error On the left, the image during the occurrence of the error, and on the right, the image when the MSP430 is receiving everything correctly.

  • Sorry, the left image is still 0xBC, so i want to confirm if only MCU will receive the wrong data and Logic analysis will receive the correct data.

  • That is unfortunately the problem I am facing. According to the logic analyzer, the data is completely correct, but at some point, the MCU decides to interpret the data incorrectly and turns a 0xBC into a 0x78.

  • How often is the Master sending?

    That delay (200us?) prior to reading RXBUF is a bit concerning. If the Master sends another byte during  that time I'm pretty sure you'll get that one instead.

    If you really need to delay inside the ISR, I suggest you read RXBUF before doing it.

  • The master sends whenever I press a button. The time between two byte telegrams is 1.2 ms. I moved the 200 microseconds to a timer so that the SPI interrupt is not delayed. 

  • Additionally, I assigned the CS line as an interrupt on port 2.0, and after the pin goes high, I reset the SPI module. This led to the problem occurring more quickly. It also seems to me that the problem occurs faster when the master sends something, and the slave also wants to send something.

  • I have now found out that when the error occurs, the SPI interrupt triggers after the 7th rising clock edge. When it works, it behaves as expected and triggers after the 8th rising edge.I can't explain why it changes.

  • There is an 8th clock edge that you aren't capturing with your logic analyzer but the SPI port is. Probably early as that would explain the bit shifted result.

    Given your hint at a possible data dependency, I suspect right around the time the SPI port enables its SOMI driver when STE is asserted.

  • Unfortunately, I don't see this additional clock on the oscilloscope or in the analog values of the logic analyzer. I have now discovered that the following always happens between 'SPI interrupt triggers after the 8th rising edge' and 'SPI interrupt triggers after the 7th rising edge':

    The master sends two bytes with a 24-microsecond pause, and the slave is busy, so it doesn't trigger the SPI interrupt immediately but later. After the second byte, it doesn't trigger an interrupt anymore, and from then on, all subsequent transmissions always trigger an interrupt on the 7th clock.

  • You seem to be using the STE signal to frame bytes. It doesn't do that on the MSP430. When STE is disabled, it simply pauses the SPI port. When it gets asserted again, the shift register picks up where it stopped.

    This is quite different from what I usually see with sensors and such with an SPI interface.

    Not sure what you mean about the slave being busy and not generating an interrupt. It is going to set RXIFG when a byte arrives. If the code is busy doing something else and doesn't read RXBUF before the next byte arrives, data will be lost. And the overrun flag set.

**Attention** This is a public forum