EmbeddedRelated.com

PGA117 driver

April 9, 2013 Coded in C for the TI MSP430
#define READ 0x6A00
#define WRITE 0x2A00
#define NOP WRITE 0x0000
#define SDN_DIS 0xE100
#define SDN_EN 0xE1F1

#define GAIN_1		0
#define GAIN_2		1
#define GAIN_4		2
#define GAIN_8		3
#define GAIN_16		4
#define GAIN_32		5
#define GAIN_64		6
#define GAIN_128	7

#define CS BIT0
#define DI BIT1
#define DO BIT2

void write_pga(unsigned int value);
void set_ch_gain(unsigned int ch,unsigned int gain);
void config_spi();

void config_spi()
{
	P1DIR |= 0x01;                            // P1.0 output
	P3SEL |= 0x0C;                            // P3.2,3 USCI_B0 option select
	P3DIR |= 0x01;                            // P3.0 output direction
	UCB0CTL0 |= UCMSB + UCMST + UCSYNC;       // 3-pin, 8-bit SPI mstr, MSB 1st
	UCB0CTL1 |= UCSSEL_2;                     // SMCLK
	UCB0BR0 = 0x02;
	UCB0BR1 = 0;
	UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
}

void write_spi(char data)
{
	UCB0TXBUF = data;                  // Byte to SPI TXBUF
	while (!(IFG2 & UCB0TXIFG));       // USCI_A0 TX buffer ready?
}

void write_pga(unsigned int value)
{
	P3OUT &= ~CS;
	write_spi(value>>8);
	write_spi(value);
	P3OUT |= CS;
}

void set_ch_gain(unsigned int ch,unsigned int gain)
{
	unsigned int command;
	command = gain<<4;
	command += ch;
	command +=WRITE;
	write_pga(command);

}

Complex serial port driver with feedback acceptance.

March 29, 20131 comment Coded in C for the TI MSP430
/*
Developed By: Dinesh SB
E-Mail: dinesh.badkas0809@gmail.com
*/

#include "msp430.h"

#define initialDelay 50000

unsigned int k,ADC12temp = 0,PotTemp = 0;;
unsigned char AdcDec[4],PotDec[4];;
volatile unsigned int i,j,m = 0,n = 0;
unsigned char IMUTemp = 0;
unsigned char IMURazorBuffer[35];

void IMU_Buffering(void);
void FSR_Read(void);
void Switch_Position_Read(void);
void Battery_Monitoring(void);
void Pot_Read(void);
void PC_UART_Transmit(unsigned char);
void Bluetooth_UART_Transmit(unsigned char);
void delayGen(unsigned int tcount);
void startTB(unsigned int,unsigned int,unsigned int);
void StartVibration(unsigned int);

unsigned char tmp;
static unsigned int module = 0;
unsigned int delay = 0, tone = 0;
static unsigned int cmdRcvd =0;
static unsigned int delayFinished =0;
static unsigned int multiDigitDelay = 0;
static unsigned int previousDelayDigit =0;
static unsigned int digitCnt = 0;
static unsigned int digit3Rcvd = 0;
static unsigned int pDetected = 0;
static unsigned int eDetected = 0;
static unsigned int time;

static unsigned int vModule = 0;
unsigned int vDelay = 0;
static unsigned int VCmdRcvd =0;
static unsigned int VDigitCnt =0;
static unsigned int VMultiDigitDelay = 0;
static unsigned int VPreviousDelayDigit =0;
static unsigned int iDetected = 0;
static unsigned int bDetected = 0;

static unsigned int UART_Select = 0;

/*******************************************************************************

 * Function :		Board_Init

 * Description: 	This function initializes GPIOs

 * Input parameters :   None

 * Output parameters :  None

*******************************************************************************/
void Board_Init(void)
{
  //P8DIR |= BIT0;                            //P8.0 LED 1
  //P8OUT &= ~BIT0;                           //LED 1 OFF

  P7DIR |= BIT3;                            //P7.3 LED 2
  P7OUT &= BIT3;                            //LED 2 off

  P1DIR = 0x3F;                             //P1.6,7 AS input 
  P1REN = 0xC0;                             //enable pullup/down reg.
  P1OUT = 0xC0;                             //select pull-up reg.

  P2DIR = 0x00;                             //P2.0-7 as input
  P2REN = 0xFF;                             //enable pullup/down reg.
  P2OUT = 0xFF;                             //select pull-up reg.

  P6DIR |= BIT6;                            //AMP_SD pin as O/P
  P6OUT &= ~BIT6;                           //SHUTDOWN disabled

  P4SEL |= BIT4;                            //select TB4
  P4DIR |= BIT4;                            //To take PWM @ pin configure that pin HIGH

  P3DIR |= BIT0;                            //LED_BATMON on P3.0
  P3OUT &= ~BIT0;                           //LED_BATMON OFF

  P7DIR |= BIT5;                            //P7.5 configued as output
  P7OUT &= ~BIT5;                           //P7.5 made 0 to sink current

  P4DIR |= BIT6;                            //vibration motor
  P4OUT &= ~BIT6;
  
  P6SEL |= BIT7;                            //select A7_____Vout_FSR pin 
  P7SEL |= BIT4;                            //select A12____VBat_Mon.
  P6SEL |= BIT5;                            //select A5_____POT

  P10DIR &= ~BIT1;                          //mechanical switch detection; P10.1
  P10REN |= BIT1;                           //enable register
  P10OUT |= BIT1;                           //select pull-up register
}

/*******************************************************************************

 * Function :		ADC12_Init

 * Description: 	This function initializes ADC12 peripheral

 * Input parameters :   None

 * Output parameters :  None

*******************************************************************************/
void ADC12_Init(void)
{
  ADC12CTL0 &= ~ADC12ENC;                                                                     //DISABLE ADC12 FOR CONFIGURATION
  P5SEL |= BIT0;                                                                              // select P5.0 for Veref+.
  ADC12CTL0 = ADC12SHT0_8 + ADC12ON + ADC12MSC;
  ADC12MCTL0 = ADC12SREF_2 | ADC12INCH_7;                                                     //FSR__A7
  ADC12MCTL1 = ADC12SREF_2 | ADC12INCH_12;                                                    //BAT-MON.__A12
  ADC12MCTL2 = ADC12EOS | ADC12SREF_2 | ADC12INCH_5;                                          //POT__A5
  ADC12CTL1 = ADC12CSTARTADD_0|ADC12SHS_0|ADC12SHP|ADC12DIV_0|ADC12SSEL_0|ADC12CONSEQ_1;      //ADC12CONSEQ_1 = SEQUENCE OF CHANNELS. .... 

  for (k = 0x4600; k; k--);                                                                   // Delay approx. = 368 ms for needed ref start-up.
  ADC12CTL0 |= ADC12ENC;                                                                      //ENABLE ADC12 for working
}

/*******************************************************************************

 * Function :		PC_UART_Init

 * Description: 	This function initializes USCI_A0; connected to PC

 * Input parameters :   None

 * Output parameters :  None

*******************************************************************************/
void PC_UART_Init(void)                       //USB-serial UART
{
  P3SEL |= BIT4 | BIT5;                       //USCI_A0 ... RXD TXD SELECT 
  UCA0CTL0 &= 0x00;                           //USCYNC = 0 ....... for UART mode.
  UCA0CTL1 |= UCSWRST;                     
  UCA0CTL1 |= UCSSEL_2;                       //select SMCLK = 1 MHz
  UCA0BR0 = 0x09;                             //115200 baud rate..
  UCA0BR1 = 0x00;
  UCA0MCTL = 0x00;
  UCA0CTL1 &= ~UCSWRST;                       //Initialize USCI state machine**
  //UCA0IE |= UCRXIE;                         //Enable USCI_A0 RX interrupt
}

/*******************************************************************************

 * Function :		IMU_UART_Init

 * Description: 	This function initializes USCI_A1; connected to IMU Razor
                        Sensor Board.

 * Input parameters :   None

 * Output parameters :  None

*******************************************************************************/
void IMU_UART_Init(void)                      //IMU UART
{
  P5SEL |= BIT6 | BIT7;
  UCA1CTL0 &= 0x00;
  UCA1CTL1 |= UCSWRST;                     
  UCA1CTL1 |= UCSSEL_2;
  UCA1BR0 = 0x12;                             //57600 baud rate..
  UCA1BR1 = 0x00;
  UCA1MCTL = 0x00;
  UCA1CTL1 &= ~UCSWRST;
}

/*******************************************************************************
 
 * Function :		Bluetooth_UART_Init
 
 * Description: 	This function initializes USCI_A2; connected to 
                        Bluetooth module.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
void Bluetooth_UART_Init(void)                //bluethooth UART
{
  P9SEL |= BIT4 | BIT5;            
  UCA2CTL0 &= 0x00;
  UCA2CTL1 |= UCSWRST;                     
  UCA2CTL1 |= UCSSEL_2;                  
  UCA2BR0 = 0x09;                             //115200 baud rate..
  UCA2BR1 = 0x00;
  UCA2MCTL = 0x00;
  UCA2CTL1 &= ~UCSWRST;
  //UCA2IE |= UCRXIE;
}

void main(void)
{
  volatile unsigned int loop_var;

  WDTCTL = WDTPW + WDTHOLD;                                 //WDT made off

  for(loop_var = 0;loop_var < initialDelay;loop_var++);    //approx. 1 sec.
  for(loop_var = 0;loop_var < initialDelay;loop_var++);    //approx. 1 sec.
  for(loop_var = 0;loop_var < initialDelay;loop_var++);    //approx. 1 sec.
  
/*
  do                                                        //for to stabilize the oscillator
  {
    UCSCTL7 &= ~(XT1LFOFFG + DCOFFG);                       //clear XT1, DCO fault flags
    SFRIFG1 &= ~OFIFG;                                      //clear oscillator fault flag.
    for(loop_var = 0x47FF;loop_var > 0;loop_var--);         //delay approx. = 368 ms
  }while((SFRIFG1 & OFIFG));                                //loop till crystal oscillator stabilizes.
*/
  Board_Init();
  ADC12_Init();
  IMU_UART_Init();
  PC_UART_Init();
  Bluetooth_UART_Init();

  __bis_SR_register(GIE);                                   //set Global Interrupt Enable
  //for (k = 0x4600; k; k--);                               //delay to initialize IMU sensor board  

while(1)
{
  if(0x02 & P10IN)                        //P10.1 = 1 ---- for bluetooth
  {
    UART_Select = 1;
    UCA0IE &= ~UCRXIE;
    UCA2IE |= UCRXIE;
  }
  else                                    //P10.1 = 0 ---- for PC
  {
    UART_Select = 0;
    UCA0IE |= UCRXIE;
    UCA2IE &= ~UCRXIE;
  }

  switch(UART_Select)
  {
  case 0:                                       //PC UART selected

          IMU_Buffering();
          n = 0;
          while(IMURazorBuffer[n] != '\r')
          {
            PC_UART_Transmit(IMURazorBuffer[n]);
            n++;
          }

          PC_UART_Transmit(';');
          PC_UART_Transmit('F');
          PC_UART_Transmit('S');
          PC_UART_Transmit('R');
          PC_UART_Transmit(':');

          FSR_Read();
          for(i=0;i<4;i++)                            //FSR decimal transmit
          {
            PC_UART_Transmit(AdcDec[3-i]);
          }

          PC_UART_Transmit(';');
          PC_UART_Transmit('P');
          PC_UART_Transmit('O');
          PC_UART_Transmit('T');
          PC_UART_Transmit(':');
          Pot_Read();
          for(i=0;i<4;i++)                            //POT decimal transmit
          {
            PC_UART_Transmit(PotDec[3-i]);
          }

          PC_UART_Transmit(';');
          PC_UART_Transmit('S');
          PC_UART_Transmit('W');
          PC_UART_Transmit('I');
          PC_UART_Transmit('T');
          PC_UART_Transmit('C');
          PC_UART_Transmit('H');
          PC_UART_Transmit('E');
          PC_UART_Transmit('S');
          PC_UART_Transmit(':');

          Switch_Position_Read();
          PC_UART_Transmit(';');

          Battery_Monitoring();
          PC_UART_Transmit('\n');
          PC_UART_Transmit('\r');

   break;

  case 1:                                        //Bluetooth UART selected

          IMU_Buffering();
          n = 0;
          while(IMURazorBuffer[n] != '\r')
          {
            Bluetooth_UART_Transmit(IMURazorBuffer[n]);
            n++;
          }

          Bluetooth_UART_Transmit(';');
          Bluetooth_UART_Transmit('F');
          Bluetooth_UART_Transmit('S');
          Bluetooth_UART_Transmit('R');
          Bluetooth_UART_Transmit(':');

          FSR_Read();
          for(i=0;i<4;i++)                           //FSR decimal transmit
          {
            Bluetooth_UART_Transmit(AdcDec[3-i]);
          }

           Bluetooth_UART_Transmit(';');
           Bluetooth_UART_Transmit('P');
           Bluetooth_UART_Transmit('O');
           Bluetooth_UART_Transmit('T');
           Bluetooth_UART_Transmit(':');
           Pot_Read();
           for(i=0;i<4;i++)                          //POT decimal transmit
           {
              Bluetooth_UART_Transmit(PotDec[3-i]);
           }

           Bluetooth_UART_Transmit(';');
           Bluetooth_UART_Transmit('S');
           Bluetooth_UART_Transmit('W');
           Bluetooth_UART_Transmit('I');
           Bluetooth_UART_Transmit('T');
           Bluetooth_UART_Transmit('C');
           Bluetooth_UART_Transmit('H');
           Bluetooth_UART_Transmit('E');
           Bluetooth_UART_Transmit('S');
           Bluetooth_UART_Transmit(':');

           Switch_Position_Read();
           Bluetooth_UART_Transmit(';');

           Battery_Monitoring();
           Bluetooth_UART_Transmit('\n');
           Bluetooth_UART_Transmit('\r');
  break;

  default:
    break;
}//switch

}//while(1)

}//main

/*******************************************************************************
 
 * Function :		PC_UART_Transmit
 
 * Description: 	This function transmits data to USCI_A0.
 
 * Input parameters :   unsigned char PC_Transmit_char
  					
 * Output parameters :  None
  					
*******************************************************************************/
void PC_UART_Transmit(unsigned char PC_Transmit_char)
{
  while (!(UCA0IFG&UCTXIFG));                           //wait for TxBuf to become empty
  UCA0TXBUF = PC_Transmit_char;
}

/*******************************************************************************
 
 * Function :		Bluetooth_UART_Transmit
 
 * Description: 	This function transmits data to USCI_A2.
 
 * Input parameters :   unsigned char BL_Transmit_char
  					
 * Output parameters :  None
  					
*******************************************************************************/
void Bluetooth_UART_Transmit(unsigned char BL_Transmit_char)
{
  while (!(UCA2IFG&UCTXIFG));                          //wait for TxBuf to become empty
  UCA2TXBUF = BL_Transmit_char;
}

/*******************************************************************************
 
 * Function :		Pot_Read
 
 * Description: 	This function converts pot`s digitalized value 
                        to decimal.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
void Pot_Read(void)
{
  PotTemp = ADC12MEM2;                      //collect digitalized O/P of POT

  for(i=0;i<4;i++)                          //convert to Decimal
  {
    PotDec[i]=(PotTemp%10) + 0x30;          //for HEX->ASCII conversion
    PotTemp = PotTemp/10;                   //for HEX->Decimal conversion
  }
}

/*******************************************************************************
 
 * Function :		IMU_Buffering
 
 * Description: 	This function does the buffering of packets coming from 
                        IMU Razor Sensor Board.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
void IMU_Buffering(void)
{
  //P8OUT |= BIT0;              //LED on
  m = 0;
  IMUTemp = 'd';               //for safety purpose
  while(1)
	{
          
            while(IMUTemp != '!')                           //wait till '!' to be received
            {
              if(UCA1IFG&UCRXIFG)
	      {IMUTemp = UCA1RXBUF;}
            }
            
			do                                  //collect a complete packet of IMU Razor. 
			{   
		          IMURazorBuffer[m] = IMUTemp;
                          while(!(UCA1IFG&UCRXIFG));
		          IMUTemp = UCA1RXBUF;
                          m++;
			}while((IMUTemp != '!'));
                        IMURazorBuffer[m] = '\0';
          
			break;
	}
  
  //P8OUT &= ~BIT0;       //LED off
}

/*******************************************************************************
 
 * Function :		FSR_Read
 
 * Description: 	This function converts FSR`s digitalized value 
                        to decimal.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
void FSR_Read(void)
{
  ADC12CTL0 |= ADC12SC;                     //start conversion for 3 channels - A7 & A12 & A5
  ADC12temp = 0;         
  while(ADC12CTL1 & ADC12BUSY);             //wait till conversion ends

  ADC12temp = ADC12MEM0;                    //collect converted O/P of FSR

  for(i=0;i<4;i++)                          //convert to Decimal
  {
  AdcDec[i]=(ADC12temp%10) + 0x30;          //for HEX->ASCII conversion
  ADC12temp = ADC12temp/10;                 //for HEX->Decimal conversion
  }
}

/*******************************************************************************
 
 * Function :		Battery_Monitoring
 
 * Description: 	This function checks the battery voltage.
                        Assume Battery deferres @ 2.75V
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
void Battery_Monitoring(void)
{
  if(ADC12MEM1 <= 0x11D)                    //considering Vbat_min.= 2.75V
  {
     P3OUT |= BIT0;                         //LED_BATMON ON
     if(UART_Select == 0)
     PC_UART_Transmit('1');
     else
     Bluetooth_UART_Transmit('1');
  }
  else
  {
    P3OUT &= ~BIT0;                        //LED_BATMON OFF
    if(UART_Select == 0)
    PC_UART_Transmit('0');
    else
    Bluetooth_UART_Transmit('0');
  }
}

/*******************************************************************************
 
 * Function :		Switch_Position_Read
 
 * Description: 	This function sends the status of all switches of 
                        the switch board.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
void Switch_Position_Read(void)
{
    if(!(0x40 & P1IN))                        //SW2-P1.6
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x80 & P1IN))                      //SW3-P1.7
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x01 & P2IN))                      //SW4-P2.0
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x02 & P2IN))                      //LEFT-P2.1
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x04 & P2IN))                      //RIGHT-P2.2
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');                  
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x08 & P2IN))                      //SELECT-P2.3
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x10 & P2IN))                      //UP-P2.4
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x20 & P2IN))                      //DOWN-P2.5
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
     {
       if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }

    if(!(0x80 & P2IN))                      //SW6-P2.7
    {
      if(UART_Select == 0)
      PC_UART_Transmit('1');
      else
      Bluetooth_UART_Transmit('1');
    }
      else
      {
        if(UART_Select == 0)
        PC_UART_Transmit('0');
        else
        Bluetooth_UART_Transmit('0');
      }
}

/*******************************************************************************
 
 * Function :		startTB
 
 * Description: 	This function starts the TIMER_B & speaker 
                        on speaker sound request.
 
 * Input parameters :   unsigned int count0,unsigned int count1,unsigned int delayTime
  					
 * Output parameters :  None
  					
*******************************************************************************/
void startTB(unsigned int count0,unsigned int count1,unsigned int delayTime)
{
  TBCCR0 = count0;                            // PWM Period
  TBCCTL4 = OUTMOD_7;                         // CCR4 reset/set
  TBCCR4 = count1;                            // CCR4 PWM duty cycle	
  TBCTL = TBSSEL_2 + MC_1;                    // SMCLK, upmode
  delayGen(delayTime);
}

/*******************************************************************************
 
 * Function :		delayGen
 
 * Description: 	This function starts the TIMER_A1 on speaker sound request.
 
 * Input parameters :   unsigned int tcount
  					
 * Output parameters :  None
  					
*******************************************************************************/
void delayGen(unsigned int tcount)
{
  //P8OUT ^= BIT0;
  TA1CCR0 = tcount;                         //Timer_A1 compare count
  TA1CCTL0 |= CCIE;                         //enable Timer_A1 Interrupt
  TA1CTL = TASSEL_1 + ID_3 + MC_2;          //Select ACLK, divider 8, Continuous mode
}

/*******************************************************************************
 
 * Function :		TIMER1_A0_ISR
 
 * Description: 	This ISR function stops the TIMER_A1.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
  //P7OUT ^= BIT3;
  TA1CCTL0 &= ~CCIE;                          //clear Timer_A1 interrupt flag
  TA1CTL |= TACLR;                            //clears all counts of Timer_A1
  TA1CTL &= MC_0;                             //Stop Timer_A1
  TBCTL |= TBCLR;                             //clears all counts of Timer_B
  TBCTL &= MC_0;                              //Stop Timer_B
  module = 0;                                 
  digitCnt = 0;
  digit3Rcvd = 0;
  pDetected = 0;
  eDetected = 0;                              //clear all static global flags for safety purpose
}

/*******************************************************************************
 
 * Function :		StartVibration
 
 * Description: 	This function starts the Vibration motor & TIMER_A0
                        on vibration motor request.
 
 * Input parameters :   unsigned int tcount
  					
 * Output parameters :  None
  					
*******************************************************************************/
void StartVibration(unsigned int vtime)
{
  volatile unsigned int x,y;
  
  P4OUT |= BIT6;                                //start vibration motor
  //P7OUT &= ~BIT3;

  TA0CCR0 = (vtime*4);                          //Initialize Timer_A0 compare count 
  TA0CCTL0 |= CCIE;                             //Enable Timer_A0 interrupt flag 
  TA0CTL = TASSEL_1 + ID_3 + MC_2;              //Select ACLK, divider 8, Continuous mode
}

/*******************************************************************************
 
 * Function :		TIMER0_A0_ISR
 
 * Description: 	This ISR function stops the TIMER_A0.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
  //P7OUT ^= BIT3;
  P4OUT &= ~BIT6;                           //turn off vibration motor.
  TA0CCTL0 &= ~CCIE;                        //clear Timer_A0 interrupt flag
  TA0CTL |= TACLR;                          //clear Timer_A0
  TA0CTL &= MC_0;                           //stop Timer_A0
  vModule = 0;                            
  iDetected = 0;
  bDetected = 0;                            //clear all static global flags for safety purpose
}

/*******************************************************************************
 
 * Function :		USCI_A0_ISR
 
 * Description: 	ISR function of USCI_A0.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
#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
    
    tmp = UCA0RXBUF;
    while (!(UCA0IFG&UCTXIFG));
    UCA0TXBUF = tmp;

    if((tmp == 's')/* | (tmp == 'S')*/)
    {
      module = 1;
      cmdRcvd = 0;
      delay = 0;
      previousDelayDigit = 0;
      delayFinished = 0;
      multiDigitDelay = 0;
      tone = 0;
      digitCnt = 0;
      digit3Rcvd = 0;
      pDetected = 0;
      eDetected = 0;
      break;
    }
    if((tmp == 'v') /*|(tmp == 'V')*/)
    {
      vModule = 1;
      VCmdRcvd = 0;
      vDelay = 0;
      VPreviousDelayDigit = 0;
      VMultiDigitDelay = 0;
      VDigitCnt = 0;
      iDetected = 0;
      bDetected = 0;
      break;
    }
       if(module == 1 )                             
       {
	  if((cmdRcvd != 1) &  (tmp == 'p') & (pDetected != 1) & (tmp != ','))
          {
            pDetected = 1;
	  //break;
	  }
	  if((cmdRcvd != 1) &  (tmp == 'e') & (pDetected == 1) & (eDetected != 1) & (tmp != ','))
          {
            eDetected = 1;
	  //break;
	  }
	  
          if((cmdRcvd != 1) & (tmp == ',') & (digit3Rcvd != 1) & (pDetected == 1) & (eDetected == 1))
          {
	    cmdRcvd = 1;
	    //break;
	  }
           	  
          if((cmdRcvd == 1) & (digitCnt <= 3) & (tmp >= '0') & (tmp <= '9') & (digit3Rcvd != 1) & (pDetected == 1) & (eDetected == 1))
          {
          digitCnt++;
	  delay = tmp - '0'; 
          if(digitCnt == 1)
          {
            multiDigitDelay = delay * 100;
            previousDelayDigit = multiDigitDelay;
          }
          if(digitCnt == 2)
          {
            multiDigitDelay = previousDelayDigit + (delay * 10);
            previousDelayDigit = multiDigitDelay;
          }
          if(digitCnt == 3)
          {
            multiDigitDelay = previousDelayDigit + delay;
            digit3Rcvd = 1;
          }
	  //break;
	  }
          
	  if((cmdRcvd == 1) & (digit3Rcvd == 1) & (tmp== ',') & (delayFinished != 1) & (pDetected == 1) & (eDetected == 1))
          {
            delayFinished = 1;
	    //break;		  		
	  }
            	  
	  if((delayFinished == 1) & (tmp >= '1') & (tmp <= '3') & (pDetected == 1) & (eDetected == 1))
          {
	    tone = tmp;
          
            time = multiDigitDelay * 4;              //delay is in msec. if you want delay in sec. make "time = delay * 4000;"
            TA1CTL |= TACLR;
            TBCTL |= TBCLR;
            if(tone == '1')
            {
              startTB(1023,256,time);
              //break;
            }
            if(tone == '2')
            {
              startTB(332,167,time);
              //break;
            }
            if(tone == '3')
            {
              startTB(255,64,time);
              //break;
            }
          }
      }

      if( vModule == 1)
      {
	if( (VCmdRcvd != 1) &  (tmp =='i') & (iDetected != 1)  & (tmp != ','))
        {
          iDetected = 1;
	  break;
	}
	if( (VCmdRcvd != 1) &  (tmp =='b') & (iDetected == 1)  & (bDetected != 1) & (tmp != ','))
        {
          bDetected = 1;
	  break;
	}
        
	if( (VCmdRcvd != 1) & (tmp == ',') & (iDetected == 1)  & (bDetected == 1))
        {
	  VCmdRcvd = 1;
	  break;
	}
	if((VCmdRcvd == 1) & (VDigitCnt <= 3 ) & (iDetected == 1)  & (bDetected == 1))
          {
          VDigitCnt++;
	  vDelay = tmp - '0'; 
          if(VDigitCnt == 1)
          {
            VMultiDigitDelay = vDelay * 100;
            VPreviousDelayDigit = VMultiDigitDelay;
          }
          if(VDigitCnt == 2)
          {
            VMultiDigitDelay = VPreviousDelayDigit + (vDelay * 10);
            VPreviousDelayDigit = VMultiDigitDelay;
          }
          if(VDigitCnt == 3)
          {
            VMultiDigitDelay = VPreviousDelayDigit + vDelay;
            {StartVibration(VMultiDigitDelay);}
          }
	  break;
	  }

      }
    break;
  case 4:

    break;                             // Vector 4 - TXIFG
  default: break;  
  }

}

/*******************************************************************************
 
 * Function :		USCI_A2_ISR
 
 * Description: 	ISR function of USCI_A2.
 
 * Input parameters :   None
  					
 * Output parameters :  None
  					
*******************************************************************************/
#pragma vector = USCI_A2_VECTOR
__interrupt void USCI_A2_ISR (void)
{
  switch(__even_in_range(UCA2IV,4))
  {
  case 0:break;                             // Vector 0 - no interrupt
  case 2:                                   // Vector 2 - RXIFG
    
    tmp = UCA2RXBUF;
    while (!(UCA2IFG&UCTXIFG));
    UCA2TXBUF = tmp;

    if((tmp == 's') /*| (tmp == 'S')*/)
    {
      module = 1;
      cmdRcvd = 0;
      delay = 0;
      previousDelayDigit = 0;
      delayFinished = 0;
      multiDigitDelay = 0;
      tone = 0;
      digitCnt = 0;
      digit3Rcvd = 0;
      pDetected = 0;
      eDetected = 0;
      break;
    }
    if((tmp == 'v') /*|(tmp == 'V')*/)
    {
      vModule = 1;
      VCmdRcvd = 0;
      vDelay = 0;
      VPreviousDelayDigit = 0;
      VMultiDigitDelay = 0;
      VDigitCnt = 0;
      iDetected = 0;
      bDetected = 0;
      break;
    }
       if(module == 1 )
       {
	  if((cmdRcvd != 1) &  (tmp == 'p') & (pDetected != 1) & (tmp != ','))
          {
            pDetected = 1;
	  //break;
	  }
	  if((cmdRcvd != 1) &  (tmp == 'e') & (pDetected == 1) & (eDetected != 1) & (tmp != ','))
          {
            eDetected = 1;
	  //break;
	  }
	  
          if((cmdRcvd != 1) & (tmp == ',') & (digit3Rcvd != 1) & (pDetected == 1) & (eDetected == 1))
          {
	    cmdRcvd = 1;
	    //break;
	  }
           	  
          if((cmdRcvd == 1) & (digitCnt <= 3) & (tmp >= '0') & (tmp <= '9') & (digit3Rcvd != 1) & (pDetected == 1) & (eDetected == 1))
          {
          digitCnt++;
	  delay = tmp - '0'; 
          if(digitCnt == 1)
          {
            multiDigitDelay = delay * 100;
            previousDelayDigit = multiDigitDelay;
          }
          if(digitCnt == 2)
          {
            multiDigitDelay = previousDelayDigit + (delay * 10);
            previousDelayDigit = multiDigitDelay;
          }
          if(digitCnt == 3)
          {
            multiDigitDelay = previousDelayDigit + delay;
            digit3Rcvd = 1;
          }
	  //break;
	  }
          
	  if((cmdRcvd == 1) & (digit3Rcvd == 1) & (tmp== ',') & (delayFinished != 1) & (pDetected == 1) & (eDetected == 1))
          {
            delayFinished = 1;
	    //break;		  		
	  }
            	  
	  if((delayFinished == 1) & (tmp >= '1') & (tmp <= '3') & (pDetected == 1) & (eDetected == 1))
          {
	    tone = tmp;
          
            time = multiDigitDelay * 4;              //delay is in msec. if you want delay in sec. make "time = delay * 4000;"
            TA1CTL |= TACLR;
            TBCTL |= TBCLR;
            if(tone == '1')
            {
              startTB(1023,256,time);
              //break;
            }
            if(tone == '2')
            {
              startTB(332,167,time);
              //break;
            }
            if(tone == '3')
            {
              startTB(255,64,time);
              //break;
            }
          }
      }

      if( vModule == 1)
      {
	if( (VCmdRcvd != 1) &  (tmp =='i') & (iDetected != 1)  & (tmp != ','))
        {
          iDetected = 1;
	  break;
	}
	if( (VCmdRcvd != 1) &  (tmp =='b') & (iDetected == 1)  & (bDetected != 1) & (tmp != ','))
        {
          bDetected = 1;
	  break;
	}
        
	if( (VCmdRcvd != 1) & (tmp == ',') & (iDetected == 1)  & (bDetected == 1))
        {
	  VCmdRcvd = 1;
	  break;
	}
	if((VCmdRcvd == 1) & (VDigitCnt <= 3 ) & (iDetected == 1)  & (bDetected == 1))
          {
          VDigitCnt++;
	  vDelay = tmp - '0'; 
          if(VDigitCnt == 1)
          {
            VMultiDigitDelay = vDelay * 100;
            VPreviousDelayDigit = VMultiDigitDelay;
          }
          if(VDigitCnt == 2)
          {
            VMultiDigitDelay = VPreviousDelayDigit + (vDelay * 10);
            VPreviousDelayDigit = VMultiDigitDelay;
          }
          if(VDigitCnt == 3)
          {
            VMultiDigitDelay = VPreviousDelayDigit + vDelay;
            {StartVibration(VMultiDigitDelay);}
          }
	  break;
	  }

      }
    break;
  case 4:

    break;                             // Vector 4 - TXIFG
  default: break;  
  }

}

MSP430 SPI-Master IO without interrupt

Guenther Klenner March 23, 2013 Coded in C++ for the TI MSP430
/**
 * @file SPI.h
 * Control's for the SPI
*/

#ifndef FILE_SPI_H
#define FILE_SPI_H

class SPI
{
public:

	/**
	 * @brief   Init for SPI
	 * @details
	 * @param   void
	 * @return  void
	 */
	static void _Init(void);

	/**
	 * @brief   Send data to Display
	 * @details
	 * @param   unsigned char msg - Message send to Display
	 * @return  void
	 */
	static void LCD_DataOut(unsigned char msg);

	/**
	 * @brief   Send data to Display
	 * @details Display mode must be set
	 * @param   char* msg - Message send to Display
	 * @param   int Length - Length of message send to Display
	 * @return  void
	 */
	static void LCD_DataOut(char *msg, int Length);

	/**
	 * @brief   Send command to Display
	 * @details
	 * @param   unsigned char msg - Message send to Display
	 * @return  void
	 */
	static void LCD_CommOut(unsigned char msg);

private:
	typedef enum {ModeIdle, ModeLCD, ModeMem} SPI_Modes;
	static SPI_Modes SPI_Mode;
	/**
	 * It configures SPI in a mode to communicate to the selected device
	 * @param Mode This defines the mode to configure.
	 */
	static void ConfigSPI(SPI_Modes Mode);

	/**
	 * It performs data exchange via SPI for a given number of inputs and outputs
	 * @param TX	pointer to transmit buffer or 0. if 0 then a dummy byte is sent (0x81)
	 * @param RX	pointer to receive buffer or 0
	 * @param IOcount total number of receive and transmit bytes
	 */
	static void DoSPI_IO(char* TX, char* RX, int IOcount);

};

#############################################

/**
 * @file SPI.c
 * Control's for the SPI
*/

#include "SPI.h"
#include "msp430.h"

#define ArrayLength(array) (sizeof(array)/sizeof(array[0]))
/// Macro to set a bit y in variable x
#define SETB(x,y)       (x |= (1 << y))
/// Macro to reset a bit y in variable x
#define CLRB(x,y)       (x &= ~(1 << y))

	SPI::SPI_Modes SPI::SPI_Mode;

	/**
	 * @brief   Init for SPI
	 * @details
	 * @param   void
	 * @return  void
	 */
	void SPI::_Init(void)
	{
		SPI_Mode = ModeIdle;
	}

	/**
	 * @brief   Send data to Display
	 * @details Display mode must be set
	 * @param   unsigned char msg - Message send to Display
	 * @return  void
	 */
	void SPI::LCD_DataOut(unsigned char msg) //Data Output Serial Interface
	{
		ConfigSPI(ModeLCD);
		CLRB(P3OUT,4);			//Chip Select = Active, CS = 0
		SETB(P2OUT,7);				//A0 = Data, A0 = 1
	    /* Software delay for selection line to settle */
	    __delay_cycles(25);

		while (UCBUSY & UCB0STAT);	// Wait until SPI is no longer busy
		UCB0TXBUF = msg;				// Transmit Message
		while (UCBUSY & UCB0STAT);  // Wait until SPI is no longer busy

		SETB(P3OUT,4);				//after 1 byte, Chip Select = inactive, CS =1
	}

	/**
	 * @brief   Send data to Display
	 * @details Display mode must be set
	 * @param   char* msg - Message send to Display
	 * @param   int Length - Length of message send to Display
	 * @return  void
	 */
	void SPI::LCD_DataOut(char *msg, int Length) //Data Output Serial Interface
	{
		ConfigSPI(ModeLCD);
		CLRB(P3OUT,4);			//Chip Select = Active, CS = 0
		SETB(P2OUT,7);				//A0 = Data, A0 = 1
	    /* Software delay for selection line to settle */
	    __delay_cycles(25);
		DoSPI_IO(msg, 0, Length);
		SETB(P3OUT,4);				//after 1 byte, Chip Select = inactive, CS =1
	}

	/**
	 * @brief   Send command to Display
	 * @details Display mode must be set
	 * @param   unsigned char msg - Message send to Display
	 * @return  void
	 */
	void SPI::LCD_CommOut(unsigned char msg) //Command Output Serial Interface
	{
		ConfigSPI(ModeLCD);
		CLRB(P3OUT,4);				//Chip Select = Active, CS = 0
		CLRB(P2OUT,7);				//A0 = Command, A0 = 0
	    /* Software delay for selection line to settle */
	    __delay_cycles(25);

		while (UCBUSY & UCB0STAT);	// Wait until SPI is no longer busy
		UCB0TXBUF = msg;				// Transmit Message
		while (UCBUSY & UCB0STAT);	// Wait until SPI is no longer busy

		SETB(P3OUT,4);				//after 1 byte, Chip Select = inactive, CS = 1

	}
	/**
	 * It configures SPI in a mode to communicate to the selected device
	 * @param Mode This defines the mode to configure.
	 */
	void SPI::ConfigSPI(SPI_Modes Mode)
	{
		if(SPI_Mode == Mode)
			return;
		switch(Mode)
		{
		case ModeLCD:
			/*******************************************************
			 * 			USCI - SPI configuration for LCD				   *
			 *******************************************************/

		    UCB0CTL1 = UCSWRST;                      	// **Reset USCI state machine**
			// UCMST = Master Mode Selected
			// UCCKPH = Data is captured on the first UCLK edge and changed on the following edge.
			// ~UCCKPL = The inactive state is low.
			// UCMSB = MSB first
			// UCSYNC = Synchronous mode
			// 8 bit data, 3 pin SPI
			UCB0CTL0 = UCMST+UCCKPH+UCMSB+UCSYNC;

			UCB0CTL1 |= UCSSEL_2;                     // SMCLK clock source
		    UCB0BR0 |= 0x03;                          // SPI Clk = SMCLK / 3 = 1 MHz
		    UCB0BR1 = 0;
		    UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
		    break;

		case ModeMem:
			/*******************************************************
			 * 			USCI - SPI configuration for Memory				   *
			 *******************************************************/

		    UCB0CTL1 = UCSWRST;                      	// **Reset USCI state machine**
			// UCMST = Master Mode Selected
			// UCCKPH = Data is captured on the first UCLK edge and changed on the following edge.
			// ~UCCKPL = The inactive state is low.
			// UCMSB = MSB first
			// UCSYNC = Synchronous mode
			// 8 bit data, 3 pin SPI
			UCB0CTL0 = UCMST+UCCKPH+UCMSB+UCSYNC;

			UCB0CTL1 |= UCSSEL_2;                     // SMCLK clock source
		    UCB0BR0 |= 0x01;                          // SPI Clk = SMCLK / 1 = 3 MHz
		    UCB0BR1 = 0;
		    UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
		    break;

		case ModeIdle:
		default:
			Mode = ModeIdle;
			break;
		}
		SPI_Mode = Mode;
	}

	/**
	 * It performs data exchange via SPI for a given number of inputs and outputs
	 * @param TX	pointer to transmit buffer or 0. if 0 then a dummy byte is sent (0x81)
	 * @param RX	pointer to receive buffer or 0
	 * @param IOcount total number of receive and transmit bytes
	 */
	void SPI::DoSPI_IO(char* TX, char* RX, int IOcount)
	{
		volatile int dummy = 0x81;
		if((TX == 0) && (RX == 0)) return;

		while(IOcount > 0)
		{
			if(UCB0IFG & UCTXIFG)
			{
				if(TX == 0)
					UCB0TXBUF = dummy;	// dummy write
				else
				{
					UCB0TXBUF = *TX++;
					IOcount--;
				}
			}
			if(UCB0IFG & UCRXIFG)
			{
				if(RX == 0)
					dummy = UCB0RXBUF;	// dummy read
				else
				{
					*RX++ = UCB0RXBUF;
					IOcount--;
				}
			}
		}
		while (UCBUSY & UCB0STAT);	// Wait until SPI is no longer busy
		dummy = UCB0RXBUF;	// dummy read to empty any remaining data in RX buffer
	}

Delay for MSP430

March 12, 20132 comments Coded in C for the TI MSP430
void configureClocks();
void delay_ms(unsigned int ms);
void delay_us(unsigned int us);

void configureClocks()
{
     WDTCTL = WDTPW + WDTHOLD;          // Stop WDT
     BCSCTL1 = CALBC1_1MHZ;
     DCOCTL = CALDCO_1MHZ;

 }

void delay_us(unsigned int us)
{
	while (us)
	{
		__delay_cycles(1); // 1 for 1 Mhz set 16 for 16 MHz
		us--;
	}
}

void delay_ms(unsigned int ms)
{
	while (ms)
	{
		__delay_cycles(1000); 1000 for 1MHz and 16000 for 16MHz
		ms--;
	}
}

DS18B20 Interfacing

January 15, 20132 comments Coded in C for the TI MSP430
float get_temp(void);
void reset_18B20(void);
void send_18B20(char data);
unsigned int read_18B20(void);

#define ONE_WIRE_PIN BIT4
#define ONE_WIRE_IN P1IN
#define ONE_WIRE_OUT P1OUT
#define ONE_WIRE_DIR P1DIR

float get_temp(void)
{
    unsigned int temp;
    reset_18B20();
    send_18B20(0xcc);   //send CCH,Skip ROM command
    send_18B20(0x44);
    delay_us(100);

    reset_18B20();
    send_18B20(0xcc);   //send CCH,Skip ROM command
    send_18B20(0xbe);

    temp = read_18B20();
    return((float)temp/8.0);

}

void reset_18B20(void)
{
    ONE_WIRE_DIR |=ONE_WIRE_PIN;
    ONE_WIRE_OUT &= ~ONE_WIRE_PIN;
    __delay_cycles(500);
    ONE_WIRE_OUT |=ONE_WIRE_PIN;
    ONE_WIRE_DIR &= ~ONE_WIRE_PIN;
    __delay_cycles(500);
}

void send_18B20(char data)
{
    char i;

    for(i=8;i>0;i--)
    {
    	ONE_WIRE_DIR |=ONE_WIRE_PIN;
        ONE_WIRE_OUT &= ~ONE_WIRE_PIN;
        __delay_cycles(2);
        if(data & 0x01)
        {
            ONE_WIRE_OUT |= ONE_WIRE_PIN;
        }
        __delay_cycles(60);
        ONE_WIRE_OUT |= ONE_WIRE_PIN;
        ONE_WIRE_DIR &= ~ONE_WIRE_PIN;
        data >>=1;
    }
}

unsigned int read_18B20()
{
    char i;
    unsigned int data=0;

    for(i=16;i>0;i--)
    {
    	ONE_WIRE_DIR |= ONE_WIRE_PIN;
        ONE_WIRE_OUT &= ~ONE_WIRE_PIN;
        __delay_cycles(2);
        ONE_WIRE_OUT |=ONE_WIRE_PIN;
        ONE_WIRE_DIR &= ~ONE_WIRE_PIN;
        __delay_cycles(8);
        if(ONE_WIRE_IN & ONE_WIRE_PIN)
        {
            data |=0x8000;
        }
        data>>=1;
        __delay_cycles(120);
    }
    return(data);
}