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.

MSP430G2553 SPI slave & master bug

Other Parts Discussed in Thread: MSP430G2553

Hello,

I have two MSP430 Launchpads worrking as master and slave. The code usa for testing is simple: the master sends one byte and the slave echoes.

The master is sending properly, as I've verified it with the oscilloscope; the slave however sends the bits shifted a random number of bits left or rigth. The problem only happens when the system is working with UCCKPH=1. If not, it works perfectly with both reading and sending properly.

I've checked the errata on the MSP430G2553 and there is a bug related to UCCKPH, but I'm not sure whether it aplies to this, nor do I understand the proposed workaround.

Below is the code for the slave Laucnhpad.

Thanks,

Federico

#include <msp430.h> 

/*
 * main.c
 */

void main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer

    while (!(P1IN & BIT4));

P1SEL = BIT1 + BIT2 + BIT4 + BIT5;
P1SEL2 = BIT1 + BIT2 + BIT4 + BIT5;

	
	UCA0CTL1 = UCSWRST;

	UCA0CTL0 |= UCMSB + UCSYNC + UCMODE1 + UCCKPH;

	UCA0CTL1 &= ~UCSWRST;
	
	IE2 |= UCA0RXIE;
    __bis_SR_register(GIE);


    while(1);
}
// Echo character
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR (void)
{
	while(1)
	{
		if(UCA0TXIFG)
		{
			UCA0TXBUF = UCA0RXBUF;
			break;
		}

	}
}

 

  • Hi Federico!

    With your while( 1 )-loop inside the ISR, the MSP will transmit bytes over and over again once it has received one single byte. Remember that UCA0TXIFG is set when the transmit buffer is empty and ready to receive a new byte. It is a self runner in your case and you will never leave the ISR again. At the point where the first byte was received, you are starting to endlessly transmitting bytes back. Remove the while( 1 )-loop in the ISR.

    Dennis
  • Hi Dennis,

    the break statemente should make the program leave the while and therefore the ISR once the UCA0TXBUF is loaded.

    Besides, the problem I have is that the slave is sending bytes wrong only when UCCKPH is set, otherwhise that same code works perfectly. I believe is has to do with a bug reported in http://www.ti.com/lit/er/slaz440g/slaz440g.pdf
    For example, if it has to send 10101111, it may sometimes send 11010111 or even 11111010.

    Regards,

    Federico

  • Federico Silva78 said:
    the break statemente should make the program leave the while

    Oh, I missed that, sorry! Then why do you have the while( 1 ) in there at all? Only to wait for a free TX buffer? Waiting loops inside an ISR will destroy all the benefits of interrupts ;\

    Federico Silva78 said:
    Besides, the problem I have is that the slave is sending bytes wrong only when UCCKPH is set

    Did you check the transmission with an oscilloscope already?

    Federico Silva78 said:
    I believe is has to do with a bug reported in http://www.ti.com/lit/er/slaz440g/slaz440g.pdf

    Possible - I guess you mean USCI40?

    Dennis

  • Great resource, Robert - thanks for sharing!
  • Thanks Robert and Denis,

    I did verify on the oscilloscope. That post is exactly the problem in hand.

    However, I don't fully understand the solution. How would my code be modified to work properly?

    Regards,

    Federico
  • Hi Frederico,

    I think there are two problem areas. First, TXBUF isn't loaded as soon as the eUSCI leaves reset. I think that will cause USCI40 on the first byte transfer, giving a 1-bit offset for the rest of the communication sequence. After that you're only setting TXBUF after RXIFG is asserted. That's about one bitclock cycle before the eUSCI needs to transfer the TXBUF into the shift register, so you miss the deadline again and hit USCI40.

    I think the transmission looks a bit like this right now, with the echoes shifted right by two bits initially:

    Master: A5 B4 C3 D2 E1 F0 (Arbitrary hexadecimal test data values)
    Slave:  xx xx 29 6D 30 F4 (xx means TXBUF not set, probably sends 00)
    

    It would be good to see scope traces of a test sequence to confirm how much offset you're getting and whether it increases for each byte transferred.

    I'm not certain of a good fix for this, but I'd start by loading TXBUF with a value as soon as the USCI is initialised. TXIFG goes high as soon as the module is taken out of reset, so you need to set TXBUF before the master starts to clock the next byte transfer. The first byte of clock from the master will cause the slave to send this initial value while the first byte from the master is still incoming.

    Then I think you'll have to load TXBUF again before the master has finished transferring its first byte. TXIFG goes high again just after the TXBUF is copied to the shift register.

    From that point on you can echo back the characters from the master. There will be a lag of two bytes between the master transmitting a value and the slave sending it back, but the TXBUF write deadline should be hit reliably.

    Those changes should make the transfers line up like this:

    Master: A5 B4 C3 D2 E1 F0 (Arbitrary hexadecimal test data values)
    Slave:  00 00 A5 B4 C3 D2 (sending two zero bytes before the echo begins)
    

**Attention** This is a public forum