This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR5969: MSP430 Voice control Over bluetooth

Part Number: MSP430FR5969
Other Parts Discussed in Thread: MSP430G2553, , MSP430G2253

Tool/software: Code Composer Studio

In my project, l am doing MSP430 voice control over Bluetooth, using a HC05 Bluetooth module and an Android App. In this, I will control the LED present on MSP430 board using bluetooth HC05 from my phone. I referred this project from this tutorial  But here the board is MSP430G2553 and i am using MSP430FR5969, so the pin configuration is totally different and i am very confused what changes i should make to make this code work.

I have very llittle knowledge of MSP430. I initially thought it won't be that difficult, but i am really feeling helpless in this situation. Please help me with the relevant changes required. Here i am using bluetooth HC05 in place of HC06.

This is the code which is given in tutorial-

/*
* MSP430G2253 USCI-A UART code
* Anthony Scranney
* www.Coder-Tronics.com
* October 2014
*
* The code can be used to interface with the HC06 Bluetooth adpator board.
* The code waits for data to be received which then calls the UART interrupt,
* the received buffer is then assigned to the variable Rx_Data. Rx_Data is
* used in a switch case statment to action various functions depending on the
* ASCII code received over Bluetooth.
*/

#include <msp430g2253.h>

unsigned char Rx_Data = 0; // Byte received via UART
unsigned int count = 0; // Used for the flashing LED demonstration

int main(void)
{
/*** Set-up system clocks ***/
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
if (CALBC1_1MHZ == 0xFF) // If calibration constant erased
{
while (1); // do not load, trap CPU!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;
/*** Set-up GPIO ***/
P1SEL = BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD
P1SEL2 = BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD
P1DIR |= BIT6 + BIT0; // P1.6 set as output
P1OUT &= ~(BIT6 + BIT0); // P1.6 set low
/*** Set-up USCI A ***/
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 104; // 1MHz 9600
UCA0BR1 = 0; // 1MHz 9600
UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled

while(1)
{
switch (Rx_Data)
{
case 0x41: // ON Command
//while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
//UCA0TXBUF = 0x41; // Send 8-bit character
TA0CCTL0 &= ~CCIE; // Disable Timer0_A interrupts
P1SEL &= ~BIT6; // P1.6 selected as GPIO
P1OUT |= BIT6 + BIT0; // P1.0 and P1.6 set high

break;

case 0x42: // OFF Command
//while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
//UCA0TXBUF = 0x42; // Send 8-bit character
TA0CCTL0 &= ~CCIE; // Disable Timer0_A interrupts
P1SEL &= ~BIT6; // P1.6 selected as GPIO
P1OUT &= ~(BIT6 + BIT0); // P1.0 and P1.6 set low
break;

case 0x46: // FLASH Command
//while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
//UCA0TXBUF = 0x46; // Send 8-bit character
/*** Timer0_A Set-Up ***/
TA0CCR0 |= 10000-1; // Counter value
TA0CCTL0 |= CCIE; // Enable Timer0_A interrupts
TA0CTL |= TASSEL_2 + MC_1; // ACLK, Up Mode (Counts to TA0CCR0)
/*** Timer0_A Set-Up ***/
break;

case 0x3E: // INCREASE Command
break;

case 0x3C: // DECREASE Command
break;

case 0x31: // 1 Command
break;

case 0x32: // 2 Command
break;

case 0x33: // 3 Command
break;

case 0x34: // 4 Command
break;

case 0x35: // 5 Command
break;

default: break;
}
__bis_SR_register(LPM0_bits); // Enter LPM0, interrupts enabled
}
}

// USCI A interrupt handler
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCI0RX_ISR (void)
#else
#error Compiler not supported!
#endif
{
Rx_Data = UCA0RXBUF; // Assign received byte to Rx_Data
__bic_SR_register_on_exit(LPM0_bits); // Wake-up CPU
}

#pragma vector=TIMER0_A0_VECTOR // Timer0 A0 interrupt service routine
__interrupt void Timer0_A0 (void) {

count++;
if (count == 10)
{
P1OUT ^= BIT0 + BIT6; // P1.0 Toggle (Red LED)
count =0;
}
}

and i am getting these errors:

Description Resource Path Location Type
#10010 errors encountered during linking; "uart.out" not built uart C/C++ Problem
<a href="file:/c:/ti/ccsv6/tools/compiler/dmed/HTML/10234.html">#10234-D</a> unresolved symbols remain uart C/C++ Problem
unresolved symbol BCSCTL1, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol CALBC1_1MHZ, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol CALDCO_1MHZ, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol DCOCTL, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol IE2, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol P1DIR, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol P1OUT, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol P1SEL, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol P1SEL2, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol UCA0BR0, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol UCA0BR1, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol UCA0CTL1, first referenced in ./main.obj uart C/C++ Problem
unresolved symbol UCA0MCTL, first referenced in ./main.obj uart C/C++ Problem

  • Hello Mahima,

    Let me take a look and see if I can resolve the differences for you.
  • Yeah.. Please do so..

    Thank you 

  • Hello Mahima,

    I went through the code and replaced the clock startup and UART configuration and interrupts with example code provided in the MSPWARE library for the MSP430FR5969 peripherals.  I would recommend downloading it either separately or install in Code Composer Studio and make use of all the really helpful examples.

    The code compiles.  It's up to you to get it running the way you want.

    Hope this helps.

    // Example code pieces from MSPWARE MSP430FR5969 peripheral example code.
    
    #include <msp430.h> 
    
    
    unsigned char Rx_Data = 0; // Byte received via UART
    unsigned int count = 0; // Used for the flashing LED demonstration
    
    int main(void)
    {
        /*** Set-up system clocks ***/
        WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    
        /*** Set-up GPIO ***/
    
        P2SEL1 = BIT5 | BIT6; // P2.5 = TXD, P2.6 = RXD
    
        P1DIR |= BIT6 | BIT0; // P1.6 set as output
        P1OUT &= ~(BIT6 + BIT0); // P1.6 set low
    
        // Disable the GPIO power-on default high-impedance mode to activate
         // previously configured port settings
         PM5CTL0 &= ~LOCKLPM5;
    
         // Clock System Setup
         CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
         CSCTL1 = DCOFSEL_6;                       // Set DCO to 8MHz
         CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO
                                                   // ACLK = VLOCLK
         CSCTL3 = DIVA__1 | DIVS__8 | DIVM__1;     // Set all dividers to 1
         CSCTL0_H = 0;                             // Lock CS registers
    
    
        /*** Set-up USCI A ***/
         // Configure USCI_A0 for UART mode
         UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset
         UCA0CTLW0 |= UCSSEL__SMCLK;               // CLK = SMCLK
         // Baud Rate calculation
         // 8000000/(16*9600) = 52.083
         // Fractional portion = 0.083
         // User's Guide Table 21-4: UCBRSx = 0x04
         // UCBRFx = int ( (52.083-52)*16) = 1
         UCA0BR0 = 52;                             // 8000000/16/9600
         UCA0BR1 = 0x00;
         UCA0MCTLW |= UCOS16 | UCBRF_1;
         UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
         UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
    
        __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled
    
        while(1)
        {
            switch (Rx_Data)
            {
                case 0x41: // ON Command
                //while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
                //UCA0TXBUF = 0x41; // Send 8-bit character
                TA0CCTL0 &= ~CCIE; // Disable Timer0_A interrupts
                P1SEL1 &= ~BIT6; // P1.6 selected as GPIO
                P1OUT |= BIT6 + BIT0; // P1.0 and P1.6 set high
    
                break;
    
                case 0x42: // OFF Command
                //while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
                //UCA0TXBUF = 0x42; // Send 8-bit character
                TA0CCTL0 &= ~CCIE; // Disable Timer0_A interrupts
                P1SEL1 &= ~BIT6; // P1.6 selected as GPIO
                P1OUT &= ~(BIT6 + BIT0); // P1.0 and P1.6 set low
                break;
    
                case 0x46: // FLASH Command
                //while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
                //UCA0TXBUF = 0x46; // Send 8-bit character
                /*** Timer0_A Set-Up ***/
                TA0CCR0 |= 10000-1; // Counter value
                TA0CCTL0 |= CCIE; // Enable Timer0_A interrupts
                TA0CTL |= TASSEL_2 + MC_1; // ACLK, Up Mode (Counts to TA0CCR0)
                /*** Timer0_A Set-Up ***/
                break;
    
                case 0x3E: // INCREASE Command
                break;
    
                case 0x3C: // DECREASE Command
                break;
    
                case 0x31: // 1 Command
                break;
    
                case 0x32: // 2 Command
                break;
    
                case 0x33: // 3 Command
                break;
    
                case 0x34: // 4 Command
                break;
    
                case 0x35: // 5 Command
                break;
    
                default: break;
                }
                __bis_SR_register(LPM0_bits); // Enter LPM0, interrupts enabled
                }
            }
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(UCA0IV, USCI_UART_UCTXCPTIFG))
      {
        case USCI_NONE: break;
        case USCI_UART_UCRXIFG:
          Rx_Data = UCA0RXBUF;
          __bic_SR_register_on_exit(LPM0_bits); // Wake-up CPU
          break;
        case USCI_UART_UCTXIFG: break;
        case USCI_UART_UCSTTIFG: break;
        case USCI_UART_UCTXCPTIFG: break;
      }
    }
    
    
    #pragma vector=TIMER0_A0_VECTOR // Timer0 A0 interrupt service routine
    __interrupt void Timer0_A0 (void) {
    
    count++;
    if (count == 10)
    {
    P1OUT ^= BIT0 + BIT6; // P1.0 Toggle (Red LED)
    count =0;
    }
    }
    
    

  • Thank you so much. I tried that code and it compiled without error. But when i am giving voice commands on the android app.It's not executing those commands. There is no error coming on app or program, but it's not working the way it supposed to do. So, i checked the output GPIO pin which was p1.6 ,which did not make sense to me as it is supposed to be connected to LED inbuilt on board. So, i changed the output GPIO pin to p1.0

    #include <msp430.h>


    unsigned char Rx_Data = 0; // Byte received via UART
    unsigned int count = 0; // Used for the flashing LED demonstration

    int main(void)
    {
    /*** Set-up system clocks ***/
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    /*** Set-up GPIO ***/

    P2SEL1 = BIT5 | BIT6; // P2.5 = TXD, P2.6 = RXD

    P1OUT &= ~0x01;// P1.0 set as output

    P1DIR |= 0x01; // P1.6 set low

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Clock System Setup
    CSCTL0_H = CSKEY >> 8; // Unlock CS registers
    CSCTL1 = DCOFSEL_6; // Set DCO to 8MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set SMCLK = MCLK = DCO
    // ACLK = VLOCLK
    CSCTL3 = DIVA__1 | DIVS__8 | DIVM__1; // Set all dividers to 1
    CSCTL0_H = 0; // Lock CS registers


    /*** Set-up USCI A ***/
    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST; // Put eUSCI in reset
    UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK
    // Baud Rate calculation
    // 8000000/(16*9600) = 52.083
    // Fractional portion = 0.083
    // User's Guide Table 21-4: UCBRSx = 0x04
    // UCBRFx = int ( (52.083-52)*16) = 1
    UCA0BR0 = 52; // 8000000/16/9600
    UCA0BR1 = 0x00;
    UCA0MCTLW |= UCOS16 | UCBRF_1;
    UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
    UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt

    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled

    while(1)
    {
    switch (Rx_Data)
    {
    case 0x41: // ON Command
    //while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
    //UCA0TXBUF = 0x41; // Send 8-bit character
    TA0CCTL0 &= ~CCIE; // Disable Timer0_A interrupts
    P1SEL1 &= ~BIT0; // P1.6 selected as GPIO
    P1OUT |= BIT0; // P1.0 and P1.6 set high

    break;

    case 0x42: // OFF Command
    //while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
    //UCA0TXBUF = 0x42; // Send 8-bit character
    TA0CCTL0 &= ~CCIE; // Disable Timer0_A interrupts
    P1SEL1 &= ~BIT6; // P1.6 selected as GPIO
    P1OUT &= ~(BIT0); // P1.0 and P1.6 set low
    break;

    case 0x46: // FLASH Command
    //while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
    //UCA0TXBUF = 0x46; // Send 8-bit character
    /*** Timer0_A Set-Up ***/
    TA0CCR0 |= 10000-1; // Counter value
    TA0CCTL0 |= CCIE; // Enable Timer0_A interrupts
    TA0CTL |= TASSEL_2 + MC_1; // ACLK, Up Mode (Counts to TA0CCR0)
    /*** Timer0_A Set-Up ***/
    break;

    case 0x3E: // INCREASE Command
    break;

    case 0x3C: // DECREASE Command
    break;

    case 0x31: // 1 Command
    break;

    case 0x32: // 2 Command
    break;

    case 0x33: // 3 Command
    break;

    case 0x34: // 4 Command
    break;

    case 0x35: // 5 Command
    break;

    default: break;
    }
    __bis_SR_register(LPM0_bits); // Enter LPM0, interrupts enabled
    }
    }


    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch(__even_in_range(UCA0IV, USCI_UART_UCTXCPTIFG))
    {
    case USCI_NONE: break;
    case USCI_UART_UCRXIFG:
    Rx_Data = UCA0RXBUF;
    __bic_SR_register_on_exit(LPM0_bits); // Wake-up CPU
    break;
    case USCI_UART_UCTXIFG: break;
    case USCI_UART_UCSTTIFG: break;
    case USCI_UART_UCTXCPTIFG: break;
    }
    }


    #pragma vector=TIMER0_A0_VECTOR // Timer0 A0 interrupt service routine
    __interrupt void Timer0_A0 (void) {

    count++;
    if (count == 10)
    {
    P1OUT ^= BIT0 + BIT6; // P1.0 Toggle (Red LED)
    count =0;
    }
    }

    But the problem is it is still not working. What should i do? What can be the error now?

    please help.
  • Ok, then what you will need to do is somehow check that there is communication between the BLE module and the MSP.
    If you have a scope or some type of logic probe, check the RX pin in the MSP to see if the pin toggles when you send Android command.
    If you don't have any way to probe the RX pin then try setting a breakpoint in the USCI_A0_ISR to see if an interrupt is generated. This is an indirect way to see if data is coming in.

    Also, after taking a second look at the code, I see in the default statement of the switch that the MSP is put back into LPM0 but the GIE (global interrupt) is not re-enabled. Try replacing that line with:

    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled
  • Hello Mahima,

    Its been sometime since we have received a response so I will assume you have everything working and will resolve this issue.
  • Sorry, I was busy with academic work this week. I could not implement the solution which u suggested. I will try it this weekend and will tell you the current status of the project. Thank you so much for your kind support.

  • Hi Mahima,

    I was checking to see if have made any progress.
  • Yes. Thank you for your help . 

**Attention** This is a public forum