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.

MSP430F2013 Slave Problems

Other Parts Discussed in Thread: MSP430F2013

Hi, I have a MSP430F2013 running as SPI slave. My issue is, when I send a 2Byte message to my slave, it writes the 2Byte answer in the USIR register, but sends back the the lower answerbyte as higher byte, and the upper byte from the master as lower byte.

I dont understand whats going on there... Would somebody help me please?

#include <msp430x20x3.h>
#include <msp430.h>
void spi_out(void);
volatile int test = 0x00;

//#######################################
//##################  !!! Nützliche Beispiele !!!   
//############# usi_03.c /
//#######################################

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

  BCSCTL1 = CALBC1_1MHZ;        // Master clk auf 1MHz setzen um Stromsparend zu arbeiten
  DCOCTL = CALDCO_1MHZ;     
  BCSCTL3 = LFXT1S_2;          // Setze LFTX1 auf VLO = 12kHz 
 
  //#########################  ADC setup  ###################################

  SD16CTL  =  SD16REFON + SD16SSEL_2;
  SD16INCTL0 =  SD16INCH_0;                        // Auswahl ADC0(Pin:1.0+1.1)
  SD16CCTL0  =  SD16UNI + SD16IE + SD16OSR_32;
  SD16AE  = SD16AE0;                     //schaltet digitale Schaltung für diesen Pin ein
 
  //#########################  SPI setup  ###################################
  
  USICTL0 = USIPE7 + USIPE6 + USIPE5 + USIOE + USIGE; // Port, SPI Slave
  USICTL1 =  USIIE;               // Counter interrupt, flag
                                            //   remains set
  USICTL0 &= ~USISWRST;
  USICNT = 16;                              // init-load counter
  USICNT |= USI16B;                         // 16-bit-transmission
  USICTL0 &= ~USISWRST;
  USICKCTL |= USICKPL;
    __bis_SR_register(LPM0_bits + GIE);  

 //#########################  Main  ###################################
 
}
// USI interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USI_VECTOR))) universal_serial_interface (void)
#else
#error Compiler not supported!
#endif
{
  if (0x9959 == USISR)
  {
//    SD16CCTL0 &= ~ SD16IFG;               // clear ADC Interrupt Flag
 //   SD16CCTL0 |= SD16SC;                  // AD Wandler starten
  //  while (!(SD16CCTL0 & SD16IFG));       // AD Wandlung fertig ?
    USISR = 0x3456;  
     USICNT = 16;
  }
  else
  {
    USISR = 0xABCD;
    USICNT = 16;
  }
}


  • This is an endianess problem.

    When you write a 16 bit value into the USI register, then the USI will send it with the highest bit first. So the other side receives the upper 8 bits, then the lower 8 bits. If the receiver doesn’t support 16 bit operation, it will receive them as two bytes with 8 bit each. High byte first. However, most systems natively use little endian numbers. So when the bytes are stored in memory in the order they are received, then the lower byte in memory will be the upper byte of the 16 bit value you sent. Which is opposite to the native format an INT is stored in memory (low byte first) on a little-endian system like the MSP.

    The same problem happens when sharing binary data between systems with different endianess. For this reason, most libraries for network transfers have conversion functions (htons - host-to-network-short) which will, depending on system type, either swap the bytes or simply return the passed parameter.

     One more thing, you shouldn’t write a count to USICNT and then OR the USI16B bit in. You should write both, count and USI16B bit simultaneously. Because the very moment you write the count, a transmission may start, and it will be an 8 bit transmission then because USI16B is not yet set..

**Attention** This is a public forum