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.

SPI Communication between two MSP430F5438s

Other Parts Discussed in Thread: MSP430F5438A

 

Hi

I am trying to communicate between two MSP430F5438s  using SPI.  I tried with my code . It was not working  . So i tried using example code (TI)which is pasted below . Still it was not working .I doubt there might be a problem in hardware connection between two MCs. regarding hardware , I connected using 3 wire mode which connects SIMO(master p3.4)-SIMO (Slave p3.4) , SOMI(master p3.5)-SOMI (Slave p3.5) and clocks using p3.0(master )- p3.0(slave)  and necessary power suppply to both the controllers . please let me know if there is any hardware problem  or any code issue .

 

I have used following master code :

 

#include "msp430x54xA.h"

unsigned char MST_Data,SLV_Data;

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

  P1OUT |= 0x02;                            // Set P1.0 for LED
                                            // Set P1.1 for slave reset
  P1DIR |= 0x03;                            // Set P1.0-2 to output direction
  P3SEL |= 0x31;                            // P3.5,4,0 option select

  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;    // 3-pin, 8-bit SPI master
                                            // Clock polarity high, MSB
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 0x02;                           // /2
  UCA0BR1 = 0;                              //
  UCA0MCTL = 0;                             // No modulation
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

  P1OUT &= ~0x02;                           // Now with SPI signals initialized,
  P1OUT |= 0x02;                            // reset slave

  __delay_cycles(100);                      // Wait for slave to initialize

  MST_Data = 0x01;                          // Initialize data values
  SLV_Data = 0x00;                          //

  while (!(UCA0IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
  UCA0TXBUF = MST_Data;                     // Transmit first character

  __bis_SR_register(LPM0_bits + GIE);       // CPU off, enable interrupts
}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
  switch(__even_in_range(UCA0IV,4))
  {
    case 0: break;                          // Vector 0 - no interrupt
    case 2:                                 // Vector 2 - RXIFG
      while (!(UCA0IFG&UCTXIFG));           // USCI_A0 TX buffer ready?

      if (UCA0RXBUF==SLV_Data)              // Test for correct character RX'd
        P1OUT |= 0x01;                      // If correct, light LED
      else
        P1OUT &= ~0x01;                     // If incorrect, clear LED

      MST_Data++;                           // Increment data
      SLV_Data++;
      UCA0TXBUF = MST_Data;                 // Send next value

      __delay_cycles(40);                   // Add time between transmissions to
                                            // make sure slave can process information
      break;
    case 4: break;                          // Vector 4 - TXIFG
    default: break;
  }
}

 

 

 

also the save code is :

 

#include "msp430x54xA.h"

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

  while(!(P3IN&0x01));                      // If clock sig from mstr stays low,
                                            // it is not yet in SPI mode
  P3SEL |= 0x31;                            // P3.5,4,0 option select
  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL0 |= UCSYNC+UCCKPL+UCMSB;          // 3-pin, 8-bit SPI slave,
                                            // Clock polarity high, MSB
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4, enable interrupts
}

// Echo character
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
  switch(__even_in_range(UCA0IV,4))
  {
    case 0:break;                             // Vector 0 - no interrupt
    case 2:                                   // Vector 2 - RXIFG
      while (!(UCA0IFG&UCTXIFG));             // USCI_A0 TX buffer ready?
      UCA0TXBUF = UCA0RXBUF;
      break;
    case 4:break;                             // Vector 4 - TXIFG
    default: break;
  }
}

 

with this code dumped on master and slave UCs ,, and connections as told , I am not able to communicate between the two controllers . Please suggest some breakthrough .

Thanks

Karthik

 

 

 

  • The hardware connection sounds okay. Do you have a common ground? (Sometimes people power both sides with separate supplies and forget that the signal lines require a ground connection)

    The sample code, if you didn't change it, should run. It was apparently written for the 5438A, but the differences to the 5438 AFAIK do not affect the USCI operation.

    However...

    after resetting the slave, you should wait a little bit longer. The manual states that code execution of the begins from PUC in less than 5µs, but a hardware reset by RST pin additionally executes the boot code. And also, before your program starts, teh C startup code is executed. Together, this might easily exceed the 100 clock cycles (which are only 100 clock cycles on the slave too, assuming that both run on same default frequency, which also isn't necessarily the case)

  • Thank you for reply .

    I have connected both the grounds of two Ucs  and it was not working ...Do I need to do something with STE ? I did not use it because i am using 3 wire mode  as i am using one master one slave ..Please update me with hardware changes if any . Also as you said regarding clock cycles , do i need to change something over code also .

    Thanks

     Karthik

     

  • Hi Michael

     Any update from ur side  to change  code ...im damn stuck over here ...

  • any update michael ??

  • Sorry, weekend - and it begines a 'few' hours earlier here in Germany :)

    You don't need STE (or 4 wire mode) if there is only one master and one slave. STE is only required when having a multi-master system (so one master can shut-up the other) or if the MSP acts as one of several slaves. And even then it's not really required, it just relaxes the timing a bit.

    Use 3-wire mode if you only have a 1:1 master/slave setup. Or if the MSP is the only master.

    What I noticed, the master code seesm to control (reset) the slave using P1.1 GPIO pin. Seemingly connected to the slaves RST pin. Hence my suggestion to give the slave more time to start up after setting P1.1.

    Also, the slave checks the P3.0 pin, whih is the clock signal. However, this is weird, since if there is an SPi clock signal already, the slave might be too late initializing its USCI, and miss the first data bit. Again, a longer delay, before startign the first transfer might help.

    SPI itself has no direct syncing mechanism (other than UART with ist start/stop bits or I2C with ist start/stop condition). That means, if the slave misses a bit or detects a bit where there is none, then all future communication will be off by this bit.
    Such a misudnerstanding may happen during port pin initialization. The init state of the masters port pins before SPI is enabled can be interpreted by the slave as valid bits. And future communication is broken then.

    The demo code seems to 'correct' this  by keeping th eslave in reset state (using P1.1) until the master SPi is set up.

    The usual way SPI does this is by a separate CS (chip select) signal. If this signal goes high, it tells the slave to reset its low level protocol, disable its outputs and abort any multi-byte high-level protocol transfer.
    When CS goes low, the slave will activate its output and also prepare immediately (!) for sending the first byte out, as soon as the master begins clocking (usually, slaves define a minimum delay between CS low and the first SPI clock pulse).

    Each slave gets its own CS signal, so on an SPi bus there can be as many slaves as you can provide individual CS signals.

    The STE pin (in 4-wire mode) is a help to perform the 'shut up' operation imemdiately, fi the masters CS signal is conencted. It is, however, still needed to detect this condition and reset the USCI and abort any incomplete high-level transfer by software.

    For anything beyond this generic explanation, I'd need to know what exactly happens when your code executes. Like a capture form a logic analyzer/digital memory scope

  • Sai Karthik said:

     Hi

    I am trying to communicate between two MSP430F5438s  using SPI.  I tried with my code . It was not working  . So i tried using example code (TI)which is pasted below . Still it was not working .I doubt there might be a problem in hardware connection between two MCs. regarding hardware , I connected using 3 wire mode which connects SIMO(master p3.4)-SIMO (Slave p3.4) , SOMI(master p3.5)-SOMI (Slave p3.5) and clocks using p3.0(master )- p3.0(slave)  and necessary power suppply to both the controllers . please let me know if there is any hardware problem  or any code issue .

     

    Hai Sai,

    i am also trying to do SPI communication between two MSP430F5438A boards.

    actually, In EXP-MSP430F5438A board P3.4 and P3.5 pins they given out so we can connect to other board but P3.0 pin is not given out side.

    how did u connect P3.0 Master to P3.0 slave pin..???? 

**Attention** This is a public forum