Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

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.

USCI SPI slave mode and UCCKPH

Other Parts Discussed in Thread: MSP430F5529, MSP430G2553, MSP430FR5969

Having followed some forum threads about difficulties with USCI SPI slave mode, I noticed a few responses refer to an issue or limitation with the use of UCCKPH in slave mode. Unfortunately there didn't seem to be any precise information on what this problem might be. It's not listed on any errata sheet (EDIT: now logged as USCI40) and the comments about it on the forum are pretty vague.

I spent some time looking into this to see if I could reproduce the problem, and perhaps find a workaround (other than "don't use UCCKPH").

It turns out that there is indeed an issue that needs to be considered when using slave mode with UCCKPH set. There's a significant difference in the USCI's behaviour depending on the UCCKPH setting, which manifests when the firmware fails to load TXBUF in time.

The simplest way to demonstrate this is with a test program that loads TXBUF only once after taking the USCI out of reset, then busy-waits:

#include <msp430g2553.h>

void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;

    // Configure USCIB0 for 3-wire SPI, CLK idle low, SOMI/MOSI stable on CLK falling edge
    UCB0CTL1  = UCSWRST;
    UCB0CTL0  = UCSYNC | UCMODE_0 | UCMSB /*| UCCKPH*/;
    P1SEL     = BIT5 | BIT6 | BIT7;
    P1SEL2    = BIT5 | BIT6 | BIT7;
    UCB0CTL1 &= ~UCSWRST;

    while((UC0IFG & UCB0TXIFG) == 0);

    UCB0TXBUF = 0xD3;

    while(1);
}

Hook up a logic analyser to P1.5/P1.7 and feed a suitable clock source in at P1.5. The clock line needs to be held low before the USCI comes out of reset to avoid desynchronisation.

Here are the results, first with UCCKPH clear:

UCCKPH clear

TXBUF is initially set before the clock train begins. TXIFG goes high while the first byte is being shifted out, but by the ninth rising clock edge the TXBUF hasn't been set again. With UCCKPH clear, in this situation the USCI just shifts out the same byte over and over again.

Now with UCCKPH set:

UCCKPH set

Here the USCI "falls behind" the input clock by one cycle for each byte. Effectively it switches to a "nine bits per byte" cycle, repeating the LSB of the TXBUF value. To the master it appears that the slave's output is getting rotated to the right.

Obviously this test isn't very representative of real world use. It's more likely that the firmware will keep up with the incoming clock most of the time, only falling behind occasionally.

To simulate that I set up a program that writes a sequence of bytes to TXBUF. The SPI clock is set such that the transmit loop never falls behind, except there's a variable delay which is inserted before one of the writes in the sequence. Running this test repeatedly with an increasing delay shows the consequences of delivering a single byte to the TXBUF late:

(Correct sequence is 0x56, 0x6E, 0x1C, 0xA8, 0xD3, 0xAD)

Play UCCKPH clear anim

With UCCKPH clear the results aren't too bad. The signal timing is always valid, and the USCI doesn't get into an invalid state. It outputs one or more repeated bytes and occasionally loses a byte, but subsequent bytes are output correctly. If the high-level protocol is robust enough this could be handled without needing to reset the USCI.

Now compare that to what happens with UCCKPH set:

Play UCCKPH set anim

As the delay crosses the boundary into the next byte the transition on the data line is pushed back. Eventually it reaches the rising clock edge (where the data line should be stable). Then the USCI switches to repeating the LSB of the last byte and outputs the next byte one clock cycle late. When the delay extends past the next clock edge it changes to repeating the last byte (still one cycle late). That leaves the USCI state offset from the clock, and all subsequent transmissions are garbled even if the TXBUF is set in time. The only certain way to recover from this is to reset the USCI.

To summarise, there is an issue with using the USCI as SPI slave when UCCKPH is set. It only occurs if the firmware fails to set TXBUF in time, but can result in subsequent transmission being corrupted until the next USCI reset. The MSP430F5529 and MSP430G2553 both exhibit this behaviour.

Workarounds:

  1. Don't set UCCKPH high in slave mode (requires the master's clock phase be changed to match)
  2. Ensure the firmware always loads TXBUF in time when UCCKPH is set

The good news is that the "enhanced" eUSCI in the FRAM range doesn't suffer from this problem to quite the same degree. There's some limited violation of signal timing but the eUSCI's internal state machine remains in-sync with the clock. It also doesn't ever "lose" a byte when it repeats. I'll post the images for that later.

  • Here are the corresponding captures for the eUSCI on MSP430FR5969.

    In the first test case (with TXBUF only set once) the eUSCI gives the same results whether UCCKPH is set or cleared. As expected, the value written to TXBUF is sent repeatedly.

    The second test is where things get more interesting. First with UCCKPH clear:

    There are no signal timing violations, and best of all the eUSCI doesn't occasionally "lose" a byte after the TXBUF update deadline is missed. It appears that the timing of when TXIFG gets set and when the TXBUF is transferred to the shift register has changed. Both actions now occur on the same clock edge, which closes the one cycle window where a byte written late to TXBUF would be lost on USCI.

    And now with UCCKPH set:

    The good news is that the eUSCI state machine remains in sync with the input clock even if TXBUF is set late. Unfortunately the signal timing glitch is worse than before. Now it extends for a whole clock cycle instead of half a cycle. In the worst case, as seen by the master the MSB of an affected byte is replaced by the LSB of the previous one.

    Although the issues are less severe on eUSCI, the signal timing glitch can still corrupt the MSB of a late byte when UCCKPH is set. That being the case the same workarounds apply as on USCI:

    1. Don't set UCCKPH high in slave mode (requires the master's clock phase be changed to match)
    2. Ensure the firmware always loads TXBUF in time when UCCKPH is set
  • Hi Robert,

    Thank you for your very detailed post.  Please allow me to add some additional comments on why the USCI module behaves this way.

    The reason data is frequently delayed on the SOMI line when the USCI is configured as a 3-wire SPI slave with the UCCKPH bit set is there is nothing that tells USCI module to start outputting the first bit when the SPI transaction starts.  Normally, the rising or falling edge of SPI clock would trigger the module to put the bit on the SOMI line.  However, when UCCKPH is set, the clock is delayed 1/2 clock cycle, meaning this trigger no longer exists.  This timing diagram is taken from the F5xx/6xx users guide and shows that in either SPI Clock waveform with UCCKPH set, there is nothing that would trigger the module to start outputting data.

    The obvious next question is "why allow for this mode then, if it is known to not work correctly?"  The answer is that we allow four different SPI Clock configurations (with UCCKPH and UCCKPL bits) so that there is always at least one configuration that will work for any scenario, communicating with any device, with the 430 in master or slave mode.  The intent was NOT that all four configurations will work in every scenario.

    Thanks,

    Mike Pridgen
    Texas Instruments

  • Hi Mike,

    I've seen that explanation before, but it doesn't actually match the behaviour of the USCI hardware.

    Here's the picture showing slave mode with UCCKPH set, and TXBUF only set once:

    UCCKPH set

    This is actually in three-wire mode as far as the USCI is concerned; the CS channel is only present on the capture as my protocol analyser requires it to decode SPI traffic. I initialise the USCI while the clock line is held low, and TXBUF is set well before the first clock cycles arrive.

    If you look at the SDIO line you can see that it is set high before the first clock cycle. As soon as the USCI comes out of reset and the initial value of TXBUF is set it begins to output the first bit. This means the first bit is already on the line ready to be sampled by the master on the first edge of the clock.

    The full timing diagram in the F5xx/6xx users guide looks like this:

    This shows that with UCCKPH set the first bit of the first byte is output before the first clock edge. The first bit gets set up at the same time as two other events: UCxSTE being set to low and data being moved into TXBUF.

    The diagram doesn't tell you which one of these actions causes the others, but from everything I've observed it's the write to TXBUF which causes the first bit to be output in slave mode.

    Furthermore, I've verified that slave mode with UCCKPH set works correctly as long as the deadline for setting TXBUF is always met. If I change the test firmware to repeatedly set TXBUF to 0xD3 instead of only setting it once, then both modes produce the correct output.

  • Hi Robert,

    My apologies, I misunderstood your original question.  I did some quick bench testing with a F5529, and verified that in slave mode, with UCCKPH = 1, when you modify the contents of TXBUF, it loads the first bit onto the SOMI line.  Additional testing showed (as you posted), when the contents of TXBUF are not updated, the first byte is correct, but the data gets consecutively shifted to the right for subsequent bytes.  However, if TXBUF is updated between bytes, the data always appears correct on the SOMI line.

    I will get confirmation, but my suspicion is this has something to do with the way the module handles loading the TX data into the shift register and populates the SOMI line with the first bit when the UCCKPH bit is set.  I will update further when I get confirmation.

    For now, please update the contents of TXBUF before every transaction to ensure proper data handling if UCCKPH must be set to 1 when the 430 is a slave.

    Mike

  • Thanks Mike. Can you also look into this for the eUSCI module (less severe symptoms, but a similar issue)?

  • This issue is now covered by item USCI40 in the errata sheets.

    There isn't an erratum listed yet for the related eUSCI issue, but that's much less severe and only occurs when TXBUF load timing is already marginal.

**Attention** This is a public forum