EmbeddedRelated.com
The 2024 Embedded Online Conference

Complex serial port driver with feedback acceptance.

March 29, 20131 comment Coded in C for the TI MSP430

BRIEF:

The main internsion to write this code was to gather data from all sensors & peripherals and perpare a packet to send to a desktop application via serial port. And secondly, desktop application can also give feedbacks (2 types actually) to our uc based on which corresponding loads should be activated.

Details:

The project was in 3 stages actually.
First stage was controlled by another uc (AVR) containing 4 sensors (e.g. accelerometer, magnetometer..). That AVR was sending real time output of its sensors via serial port at 57600 baud rate, in the form of some predefined packet structure.
In Second stage (who`s code is given below) was a separate platform (MSP430F5438) interfaced with stage one and some other sensors (e.g. FSR, potentiometer, 10 s/w..) and 2 loads (vibration motor, speaker). The job of MSP430 uc was to collect packets from stage one at 57600 baud rate, append data from its sensors and further send the modified packet to desktop serial port with 115200 baud rate.
The main headache was to buffer the packet coming from stage one, collect other data, modify packet but send packet at different baud to stage 3.
Stage 3 was application on desktop (some 3-D game based training) supposed to accept packets from stage 2. consume it for it`s purpose, and if something goes wrong send feedback to stage 2. Based on stage 3 feedback MSP430 uc was intended to run vibration motor for specified seconds & speaker the alarm with options of 3 tones (2Khz, 5KHz, 7KHz) for specified seconds in the feedback. Feedback was accepted as interrupts.

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

}

The 2024 Embedded Online Conference