I2C driver

March 29, 2013 Coded in C for the Atmel AT89
/*
File: I2C_drive.h
*/

#ifndef __I2C_H
#define __I2C_H

#include <AT89X51.H>
#include <INTRINS.H>

typedef unsigned char ubyte;

/*
****************************************************
*       I2C Bus Configuration
*
****************************************************
*/

#define sda P1_0
#define scl P1_1
#define HOLD _nop_(); _nop_(); _nop_()

void send_stop();
void master(ubyte);
void send_byte(ubyte);
void send_data(ubyte, ubyte, ubyte, ubyte *);
ubyte recv_byte(ubyte);
void recv_data(ubyte, ubyte, ubyte, ubyte *);

#endif
----------------------------------------------------------

/*
File: I2C_drive.c
*/

#include "I2C_drive.h"

bit i2c_busy, no_ack, bus_fault;

ubyte bdata a;

sbit LSB=a ^ 0;
sbit MSB=a ^ 7;

/*
************************************
*       Sending Stop Condition
************************************
*/

void send_stop()
{
	sda = 0;
	scl = 1;
	HOLD;
	sda = 1;
	i2c_busy = 0;
}

/*
************************************
*      I2C Start Condition
*
*     NOTE: need to use it.
************************************
*/

void master(ubyte slave_addr)
{
	i2c_busy = 1;
	no_ack = 0;
	bus_fault = 0;
	if(!scl||!sda)
		bus_fault = 1;
	else
	{
		sda = 0;
		HOLD;
		scl = 0;
		HOLD;
		send_byte(slave_addr);
	}
}

/*
************************************
*     Sending a byte on I2C Bus
************************************
*/

void send_byte(ubyte i2c_data)
{
	ubyte i;
	a=i2c_data;
	for(i=0;i<8;i++)
	{
		scl=0;
		HOLD;
		sda=MSB;
		a<<=1;
		_nop_();
		scl=1;
		HOLD;
		scl=0;
	}
	sda = 1;
	scl = 1;
	HOLD;
	if(!sda)
	{
		scl = 0;
		HOLD;
	}
	else
	{
		no_ack = 1;
		scl = 0;
		HOLD;
	}
}

/*
****************************************************
*       Sending data on I2C bus
*
*   Usage:
*         send_data(0xD0,0x10, 0x20, send_buffer)
*
*         0XD0: Slave address, Must me with write bit
*         0x10: Starting address, or sub-address
*         0x20: number of bytes to send
*         send_buffer: adress of the buffer pointer
*
*****************************************************
*/

void send_data(ubyte slave_add, ubyte sub_add, ubyte bytes, ubyte *data_in)
{
	master(slave_add);
	send_byte(sub_add);
	if(no_ack)
		send_stop();
	else
	{
		for(bytes;bytes>0;bytes--)
		{
			send_byte(*data_in++);
			if(no_ack)
				break;
		}
		send_stop();
	}
}

/*
*********************************************
*      Recieve a single byte from I2C Bus
*
*    Note: if you are going to recieve
*          a single byte then the passing
*          argument should be 1.
*
*********************************************
*/

ubyte recv_byte(ubyte cnt)
{
	ubyte i,rcv_data;
	for(i=0;i<8;i++)
	{
		sda=1;
		scl=1;
		HOLD;
		LSB=sda;
		if(i<7)
			a<<=1;
		HOLD;
		scl=0;
		HOLD;
	}
	if(cnt==1)
		sda = 1;
	else
		sda = 0;
	scl =1;
	HOLD;
	scl = 0;
	sda = 1;
	HOLD;
	rcv_data = a;
	return rcv_data;
}

/*
****************************************************
*       Recieving bulk data on I2C bus
*
*   Usage:
*         recv_data(0xD0,0x10, 0x20, send_buffer)
*
*         0XD0: Slave address, Must me with write bit
*         0x10: Starting address, or sub-address
*         0x20: number of bytes to recieve
*         send_buffer: adress of the recieve buffer
*                      pointer
*
*****************************************************
*/

void recv_data(ubyte slave_add, ubyte sub_add, ubyte byte_cnt, ubyte *recv_buf)
{
	ubyte i;
	scl = sda = 1;
	master(slave_add);
	send_byte(sub_add);
	slave_add+=1;
	scl = sda = 1;
	master(slave_add);
	if(no_ack)
	{
		send_stop();
		goto exit;
	}
	for(i=0;i<byte_cnt;i++)
		recv_buf[i]=recv_byte(byte_cnt-i);
	send_stop();
exit:;
}

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;  
  }

}