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 Problem

Other Parts Discussed in Thread: MSP430FG4619, TEST2

Hi, i have some trouble with the communication between to MSP430FG4619. One of them should be the SPI-Master and one the SPI-SLAVE. I plan to connect more than one slave thats the reason for the 4 wire mode. But at the moment only one slave is connected. I can send out data from the master and the slave. But i didn't receive the right values in both direction At the moment i send only dummy values created with a loop. Can anyone give me an advise where is the problem?

Here ist the master code:

#include "msp430xG46x.h"

int i;
char receive_buffer[100];

void main(void){
 
  volatile unsigned int i;

  WDTCTL = WDTPW+WDTHOLD;                   
  FLL_CTL0 |= XCAP14PF;                     

 
  do{                                       
    IFG1 &= ~OFIFG;                         
    for (i = 0x47FF; i > 0; i--);           
  }
  while ((IFG1 & OFIFG));                   
  for(i=2100;i>0;i--);                      

  P2OUT = 0x000;                                                        
  P2DIR = 0x0FF;                    
  P7SEL |= 0x0E;                                                   
  UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;
  UCA0CTL1 |= UCSSEL_2;                          
  UCA0BR0 = 0x02;                              
  UCA0BR1 = 0;                                  
  UCA0MCTL = 0;                                  
  UCA0CTL1 &= ~UCSWRST; 
 
  IE2 |= UCA0RXIE;  
  _BIS_SR(GIE);       
 
  while(1){ 
   P2OUT = 0x0FF;
   for(i=1; i<=9; i++){  
     while (!(IFG2 & UCA0TXIFG));
     UCA0TXBUF=i;
   }
   for(i=20;i>0;i--);
   P2OUT = 0x000;
   for(i=20;i>0;i--);
  }
}

#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
 receive_buffer[i] = UCA0RXBUF;
 i++;
 if(i>20){
   i=0;
 }

}

Thats the slave code

#include "msp430xG46x.h"

int i;
int j=0;
char test[]={0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};
char test2[100];
int main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  FLL_CTL0 |= XCAP14PF;                     // Configure load caps
                                            // Wait for xtal to stabilize
  do{
    IFG1 &= ~OFIFG;                         // Clear OSCFault flag
    for (i = 0x47FF; i > 0; i--);           // Time for flag to set
  }
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?
  for(i=2100;i>0;i--);                      // Now with stable ACLK, wait

  P3SEL |= 0x0F;                                  // P3.3,2,1,0 SPI option select
  UCB0CTL1 = UCSWRST;
  UCB0CTL0 |= UCSYNC+UCCKPL+UCMSB+UCMODE_1;      
            
  UCB0CTL1 &= ~UCSWRST;                           // **Initialize USCI state machine**
  IE2 |= UCB0RXIE;                                // Enable USCI_AB0 RX interrupt
  _BIS_SR(GIE);                                   // enable interrupts
 
  while(1){
  }
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIB0RX_ISR (void){
  test2[j] = UCB0RXBUF;
  while (!(IFG2 & UCB0TXIFG));
  UCB0TXBUF = test[j];
  j++;
  if(j>10){
    j=0;
  }
}

 

  • SPI 4-wire mode has nothing to do with several slaves.

    Even with 3-wire mode you'll most likely need a separate I/O line to select and deselect the slave, synchronize the data transfer and maybe the protocol. It depends on the slave. Some may be permanently selected, some not. For more than one slave, you need additional I/O lines.

    4-wire master mode is for systems with more than one MASTER, as it automatically hibernates the master mode if a different master pulls the 4th line down. It deactivates the output of clock and data.

    It is also used if you are slave, no matter whether you are the only slave or not.
    In slave mode, the STE line will deactivate output lines and clock reception. It will not, however, reset the shift register and clear the buffers (as it should for any slave). You'll need to detect the line state (possibly by connecting it to an interrupt-capable port pin too) and reset the state machine and maybe the software protocol on changes on the STL line.

    Setting up an SPI master is easy (yet you should deeply memorize the SPI connection workflow, as it is a synchronous-bidirectional bus, which means one byte goes, one byte comes and the transmit side is double-buffered)

    Playing an SPI slave, however, is a really difficult thing. as there is no handshaking. The master won't wait for your software. If the clock signal comes, the data must be ready and waiting. No delay, no mercy. Many programmers I've seen won't get it right unless you reduce maximum SPI allowed clock frequency to a few kHz.

    If you want to program both, master and slaves, I recommend using the I2C bus rather than SPI. It is a bit more complicated on the master side, but much easier to implement on the slave side. And it works with several to many slaves too. And it really only requires 2 lines (plus GND). Yet it is limited to 400kHz (SPI does up to 20MHz). Anyway, the slave can make the master wait if necessary.

**Attention** This is a public forum