Back

//******************************************************************************
//  MSP430F24x Demo - USCI_B0 I2C Slave RX multiple bytes from MSP430 Master &
//                    USCI_A1 SPI Slave RX single bytes simultaneously.
//
//  Description: This demo connects two MSP430's via the I2C bus on channel B0
//  and SPI on channel A1. The master transmits to the slave. This is the slave 
//  code. ACLK = n/a, MCLK = SMCLK = default DCO = ~1.045MHz
//
//  (To be used with msp430F22x2_uscib0_i2c_14.c)
//
//                   MSP430F24x - Slave SPI/I2C
//
//                                    /|\  /|\
//                 -----------------   10k  10k  
//             /|\|              XIN|- |    |
//              | |                 |  |    |
//              --|RST          XOUT|- |    |
//                |                 |  |    |
//                |     P3.1/UCB0SDA|<-|----+-> (Master SDA)
//                |                 |  |    
//                |                 |  |    
//                |     P3.2/UCB0SCL|<-+----->  (Master SCL)
//                |                 |
//                |             P3.6|<- Data In (UCA1SIMO)
//                |                 |
//          LED <-|P1.0         P3.7|-> Data Out (UCA1SOMI)
//                |                 |
//                |          P5.0|-> Serial Clock In (UCA1CLK)
//
//  R. B. Elliott / H. Grewal
//  Texas Instruments Inc.
//  March 2008
//  Built with IAR Embedded Workbench Version: 3.42A
//******************************************************************************
#include "msp430x24x.h"

unsigned char *PRxData;                     // Pointer to RX data
unsigned char RXByteCtr;
volatile unsigned char RxBuffer[128];       // Allocate 128 byte of RAM

void SetupSPI(void);
void SetupI2C(void);

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

  SetupI2C();                    // Configure I2C slave channel B0
  SetupSPI();                    // Configure SPI slave channel A0

  while (1)
  {
    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer
    RXByteCtr = 0;                          // Clear RX byte count
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
                                            // Remain in LPM0 until master
                                            // finishes TX
    __no_operation();                       // Set breakpoint >>here<< and read
  }                                         // read out the RxData buffer
}

//------------------------------------------------------------------------------
// The USCI_B0 data ISR is used to move received data from the I2C master
// to the MSP430 memory.
//------------------------------------------------------------------------------
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  *PRxData++ = UCB0RXBUF;                   // Move RX data to address PRxData
  RXByteCtr++;                              // Increment RX byte count
}

//------------------------------------------------------------------------------
// The USCI_B0 state ISR is used to wake up the CPU from LPM0 in order to
// process the received data in the main program. LPM0 is only exit in case
// of a (re-)start or stop condition when actual data was received.
//------------------------------------------------------------------------------
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{

  UCB0STAT &= ~(UCSTPIFG + UCSTTIFG);       // Clear interrupt flags
  if (RXByteCtr)                            // Check RX byte counter
    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0 if data was
}                                           // received

// Echo character
#pragma vector=USCIAB1RX_VECTOR
__interrupt void USCI1RX_ISR (void)
{
  while (!(UC1IFG & UCA1TXIFG));              // USCI_A1 TX buffer ready?
  UCA1TXBUF = UCA1RXBUF;
}


void SetupSPI(void){
  P3SEL |= 0x0C0;                           // P3.6,7 USCI_A1 option select
  P5SEL |= 0x01;                            // P5.0 USCI_A1 option select
  UCA1CTL1 = UCSWRST;                       // **Put state machine in reset**
  UCA1CTL0 |= UCCKPL + UCMSB + UCSYNC;      // 3-pin, 8-bit SPI master
  UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UC1IE |= UCA1RXIE;                        // Enable USCI1 RX interrupt
}

void SetupI2C(void){
  P3SEL |= 0x06;                            // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMODE_3 + UCSYNC;             // I2C Slave, synchronous mode
  UCB0I2COA = 0x48;                         // Own Address is 048h
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  UCB0I2CIE |= UCSTPIE + UCSTTIE;           // Enable STT and STP interrupt
  IE2 |= UCB0RXIE;                          // Enable RX interrupt

}