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.

MSP430 SPI link problem

Other Parts Discussed in Thread: MSP430F2418, MSP430F5325

Good day!

I am linking MSP430F2418 and MSP430F5325 with SPI.

I am using USCIB0 on 2418 as master and USCIB1 on 5325 as slave. 2418 has 16mHz crystal as clock source and 5325 is using internal oscillator both on 16mHz MCLK. SPI is set up for MSB first.

When I am testing the link following problem is seen: as slave is receiving data OK, master is receiving data from slave one bit shifted: when slave sent 0xFF, 0x00, master is receiving 0x7F, 0x80. Both sides is configured with UCCKPH set and UCCKPL cleared (different combinations tested), and also different clock rates tested: from 1 to 20 kHz.

what sould I try?

thank you.

  • Oleg Kobrin said:
    Both sides is configured with UCCKPH set and UCCKPL cleared

    This is a rather unusual btu still valid configuration (in most, but by far not all cases, UCCKPL is set and UCCKPH is clear), but if both have the same setting, it should work.
    But...
    What about port pin power-up and initialization? UCCKPL=0 means the clock is high-active. SO on power-up of the master, an already ready slave will se a clock edge when the clock pin goes from low (VC off) to high (VCC off). THen when you initialize the USCI to an idle low clock, it will ower the clock pin again. if you do not properly synchronize master and slave with a chip select signal, the slave has seen a clock pulse the master has never intended to send. And all bits are a bit off. (pun intended)

    Initialization glitches are often unniticed.

    SPI is not auto-synchronized like UAR with its start and stop bit or I2C with its start and stop condition. SPI is a bitstream. The only synchronization for the byte borders is the chip select signal. And in case of the MSP it has to be managed on both sides in software. (e.g. when CS goes low, pull the slave USCI out of reset, when it goes high, put it back into reset, so it ignores all bus activity before and after)

  • This is a rather unusual btu still valid configuration (in most, but by far not all cases, UCCKPL is set and UCCKPH is clear), but if both have the same setting, it should work.

    I tried different configurations, with the same result.

    Of course, all sends is strictly framed with STE (chip select). The slave is configured as 4-wire SPI slave. 

    Moreover, the slave is syncronized normally as it receives data from master correctly, without any bit shifts. Only the master receives data from slave shifted.

  • Oleg Kobrin said:
    Of course, all sends is strictly framed with STE (chip select). The slave is configured as 4-wire SPI slave. 

    Teh STE signal doesn't synchronize to a byte border, it just makes the slave deaf and silent. In theory, you could clear STE mid-byte, make a transfer to a different slave, then resume the operation with the rest of the byte.

    However, if the slave receives correctly, this is rather strange. Well, when master and slave use different clock and polarity settings, this is possible. But since you use same settings on both, I have no idea.

  • And even more: slave monitors STE bit to synchronize, in software.

    Also, I'm using Digilent EE board + WafeForms software to analyze SPI traffic, and it displays correct SPI data only then I set Falling edge clock on master transfers and Rising edge on slave in SPI analizer.

  • Oleg Kobrin said:
    it displays correct SPI data only then I set Falling edge clock on master transfers and Rising edge on slave in SPI analizer.

    Well, SPI analyzer has its own settings for phase and polarity. It of course too has to match the settings in maste rand slave. Note that the TI polarity is inverse to Motorola polarity (The MSP needs UCCKPL set when the motorola notation that most others follow, has CKPL clear)

  • So then, no one can help? The important project is halted due to this problem...

  • Please update my request status

  • Oleg Kobrin said:
    Please update my request status

    Here you can hope to get an answer, not request it.

    Regarding subject: maybe showing your source code can help.

  • ok. on slave:

    in main:

    P4SEL = 0x0F;
    P4DIR = 0x04;
    UCB1CTL0 = UCCKPH | /*UCCKPL |*/ UCMSB | UCMODE_2 | UCSYNC;
    UCB1CTL1 = UCSSEL_2 | UCRXEIE;
    UCB1IE = UCRXIE;

    ISR:

    #pragma vector=USCI_B1_VECTOR
    void __interrupt USCIB1()
    {
       unsigned char cmd[10];
       unsigned char dummy;
       UCB1TXBUF = *(pReadBytes++);
       switch(ProtoStage)
       {

           ...

    then processing starts.

    on master:

    UCB0CTL0 = UCCKPH | /*UCCKPL |*/ UCMSB | UCMST|UCMODE_2 | UCSYNC;
    UCB0CTL1 = UCSSEL_2 | UCRXEIE;

    then, writes start. equivalent to:

    Data[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00};

    WiteSPI(Data, 6);

    Slave responds with 0x01, 0x00, 0xFF, 0x00, but master reads as 0x02, 0x00, 0x7F, 0x10

  • The symptoms appear consistent with the slave feeding its TXBUF late by one SPI clock, due to ISR latency. Part of this might come from using the Rx interrupt, which means the slave has roughly zero time to turn around the next byte after receiving the master's first byte.

    You might get some mileage out of (a) Using the TXIE instead and/or (b) Pre-loading the TXBUF while the slave is idle (assuming the high-level protocol allows this) and/or (c) using DMA.

    Another (somewhat distasteful) option is to introduce artificial delays in the master, between bytes.

  • Sorry, but it is incorrect. As if I write TXBUF after SPI clock starts for the next byte, this byte will be sent on next transfer, but not ot current, shifted. Also RX interrupt is triggered upon receiving the byte, which is about several thousand CPU clocks before next byte transfer started. 

  • Bruce McKenney47378 said:
    The symptoms appear consistent with the slave feeding its TXBUF late by one SPI clock, due to ISR latency. Part of this might come from using the Rx interrupt, which means the slave has roughly zero time to turn around the next byte after receiving the master's first byte.


    Bruce, the symptm you described may happen with the USI module, wher eoyu have to prepare the shift register for the next request and may miss a clock pulse.

    However, teh USCI handles this internally.

    You may lose a complete byte due to RX buffer overflow, but not a single bit. Also, you have the transmission tiem for 8 bits to read from RXBUF before it overflows.

    I'd suspect the phase setting (UCCKPH) and/or the polarity to be wrong. In most (but not all) situations, I found UCCKPL=1 and UCCKPH=0 being the combination to use.
    In case of a wrong phase and/or polarity, it may be that the transfer seems to be working, but there is a race condition that sometimes makes it miss a bit or flip a bit, while for other combinations either master or slave may receive one bit off.

  • Repeatd: I tried with all possible UCCKPL/UCCKPH combinations and with no effect.

  • Oleg Kobrin said:
    Repeatd: I tried with all possible UCCKPL/UCCKPH combinations and with no effect.

    I would test using way slower clock speeds, like 1000 times slower so I know that it's not data signal quality or clock skewing artefact.

  • please, read carefully the topic start! I tried!

  • Oleg Kobrin said:
    please, read carefully the topic start! I tried!

    No, thank you :)

    Next thing for you to try - put some pause after each SPI send to make sure slave keeps-up. If this does not change anything, then start to think that USCI state machine have some unnoticed glitch or well you don't know everything about it - so you for example need to check txbufempty flag before you put data into txbuf, put some more safety code in all places you can think of. UNtil you find the one. Then it's easy to understand what's wrong and fix it.

  • Yes, I did, sorry, forget to notice it in topic starter. I inserted 100000 CPU clocks after each SPI send on master. Nothing changed.

    Tomorrow I'll do the screenshot with oscillogram.

  • Here, the screenshot.

    The first 2 bytes is sent by master and is 0x80, 0x00. After that, slave start transferring 0x01, 0x00, 0xFF, 0x00, and as seen on scope and also in debugger on master, data received is 0x00, 0x80, 0x7F, 0x80

  • Please update my request status.

  • Reminder:

    Please update my request status.

    The important project is completely blocked due to the issue.

  • Oleg Kobrin said:
    Please update my request status.

    Status update:

    Your 'request' was apparently ignored.
    Reason: this is a user/user (engineer-to-engineer) forum. No requests are filed. Only questions are asked and usually answered by other users who are (usually) not TI employees.There is no warranty that you will get an answer to your questions or a solution for your problem. If someone knows an answer, he'll write it. if no, then not.
    You already got some thoughts from people who don't have the hardware you're working on, nor the (complete) source code to analyze the problem. And even if we had, it would be our spare time spent on the problem.

    Oleg Kobrin said:
    The important project is completely blocked due to the issue.

    Important for you, not for us. Bad for you, but nevertheless true. As I said, it is our spare time that we spend here. And if none of us has the time to dig deep into your project, or has the time but still no idea what's wrong, then you won't get an answer (I doubt that 4000 'I have no idea' posts would help you)

**Attention** This is a public forum