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.

MSP430FR6989: UART (UCA1) and LPM

Part Number: MSP430FR6989

Dear, 

For a project I'm working with UART (on my MSP430FR6989) via UCA1. I work the UART with the ACLK, and I'm using/going to use the SMCLK for timing at 16MHz. 
For the UART, I used the example code and changed it accordingly. However it has the following line in it : __bis_SR_register(LPM3_bits | GIE);, which puts on the LPM3 mode. However, I don not want to go into LP mode because I need the processor running at 16MHz for tasks (and the SMCLK). Whenever I erase the "LPM3_bits l", from this line (and thus don not let it go into LP mode), I still get through something via UART, but it is unreadable. Why is this?

There is also a main.c code which calls all these function as you see underneath, in chronological order.

void init_GPIO(void){
    //WDTCTL = WDTPW | WDTHOLD;                 // Stop Watchdog

    // Configure GPIO
    P3SEL0 |= BIT4 + BIT5;                    // eUSCI_A1 UART
    P3SEL1 &= ~(BIT4 + BIT5);                 // eUSCI_A1 UART
    PJSEL0 |= BIT4 | BIT5;                    // Configure XT1 pins for ACLK

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

void init_clocks (void){


    // Configure one FRAM waitstate as required by the device datasheet for MCLK
    // operation beyond 8MHz _before_ configuring the clock system.
    FRCTL0 = FRCTLPW | NWAITS_1;

    // XT1 Setup
    CSCTL0_H = CSKEY >> 8;                                // Unlock CS registers
    CSCTL1 = DCOFSEL_4 | DCORSEL;                         // Set DCO to 16MHz
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK; //ACLK with LFXTCLK, SLCK with DCO, MCLK with DCO
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;                 // Set all dividers
    CSCTL4 &= ~LFXTOFF;
    do
    {
       CSCTL5 &= ~LFXTOFFG;                      // Clear XT1 fault flag
       SFRIFG1 &= ~OFIFG;
    }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    CSCTL0_H = 0;                             // Lock CS registers
}

void init_communication(void)
{


   // Configure one FRAM waitstate as required by the device datasheet for MCLK
   // operation beyond 8MHz _before_ configuring the clock system.
   FRCTL0 = FRCTLPW | NWAITS_1;

   // XT1 Setup
   CSCTL0_H = CSKEY >> 8;                                // Unlock CS registers
   CSCTL1 = DCOFSEL_4 | DCORSEL;                         // Set DCO to 16MHz
   CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK; //ACLK with LFXTCLK, SLCK with DCO, MCLK with DCO
   CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;                 // Set all dividers
   CSCTL4 &= ~LFXTOFF;
   do
   {
      CSCTL5 &= ~LFXTOFFG;                      // Clear XT1 fault flag
      SFRIFG1 &= ~OFIFG;
   }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
   CSCTL0_H = 0;                             // Lock CS registers

   // Configure USCI_A1 for UART mode
   UCA1CTLW0 = UCSWRST;                      // Put eUSCI in reset
   UCA1CTLW0 |= UCSSEL__ACLK;                // CLK = ACLK
   UCA1BR0 = 3;                              // 9600 baud
   UCA1MCTLW |= 0x5300;                      // 32768/9600 - INT(32768/9600)=0.41
   // UCBRSx value = 0x53 (See UG)
   UCA1BR1 = 0;
   UCA1CTL1 &= ~UCSWRST;                     // Initialize eUSCI
   UCA1IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

   __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, interrupts enabled
   __no_operation();
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A1_VECTOR))) USCI_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
  {
    case USCI_NONE: break;
    case USCI_UART_UCRXIFG:
      while(!(UCA1IFG&UCTXIFG));
      UCA1TXBUF = 0x55; // for debugging reasons
      __no_operation();
      break;
    case USCI_UART_UCTXIFG: break;
    case USCI_UART_UCSTTIFG: break;
    case USCI_UART_UCTXCPTIFG: break;
  }
}

With kind reagerds and thanks in advance,
Yannick

  • Hi Yannick,

    There is a constraint in the system clock setting procedure if you are using 16 MHz. Please see the example at http://dev.ti.com/tirex/explore/node?node=AMrEoz4vamU2IFWu3UQ7VA__IOGqZri__LATEST, Please see the function initClockTo16MHz(). The relevant comments are below:

    // Per Device Errata set divider to 4 before changing frequency to
    // prevent out of spec operation from overshoot transient

    The code is in the example at the link in the function. It is possible that the system clock setting is not set correctly based on the comments in the system clock configuration.

    You are also configuration the system clock in both init_clocks() & init_communication(). What is the need to do this in different places. Is it not sufficient to configure it in just one place?

    Srinivas

  • Hi Srinivas, 

    Thanks for pointing out my error for setting the clock to 16MHz and setting the clock twice. This has now been taken care off. (See new code below).
    However, my initial error is still there. When I remove the LPM mode, the only thing Putty prints out is "jibberish" a.k. unreadable dots, instead of a "U". 
    Any suggestions for this? 

    With kind regards,
    Yannick

    PS: the new code:

    void init_GPIO(void){
        //WDTCTL = WDTPW | WDTHOLD;                 // Stop Watchdog
    
        // Configure GPIO
        P3SEL0 |= BIT4 + BIT5;                    // eUSCI_A1 UART
        P3SEL1 &= ~(BIT4 + BIT5);                 // eUSCI_A1 UART
        PJSEL0 |= BIT4 | BIT5;                    // Configure XT1 pins for ACLK
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    }
    
    void init_clocks (void){
    
        // Configure one FRAM waitstate as required by the device datasheet for MCLK
        // operation beyond 8MHz _before_ configuring the clock system.
        FRCTL0 = FRCTLPW | NWAITS_1;
    
        // Clock System Setup
        CSCTL0_H = CSKEY_H;                     // Unlock CS registers
        CSCTL1 = DCOFSEL_0;                     // Set DCO to 1MHz
        // Set SMCLK = MCLK = DCO, ACLK = LFXTCLK (VLOCLK if unavailable)
        CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
        // Per Device Errata set divider to 4 before changing frequency to
        // prevent out of spec operation from overshoot transient
        CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4;   // Set all corresponding clk sources to divide by 4 for errata
        CSCTL1 = DCOFSEL_4 | DCORSEL;           // Set DCO to 16MHz
        // Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
        __delay_cycles(60);
        CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers to 1 for 16MHz operation
    
        CSCTL4 &= ~LFXTOFF;
        do
        {
        CSCTL5 &= ~LFXTOFFG;                      // Clear XT1 fault flag
        SFRIFG1 &= ~OFIFG;
        }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
        CSCTL0_H = 0;                             // Lock CS registerss
    }
    
    void init_communication(void)
    {
       // Configure USCI_A1 for UART mode
       UCA1CTLW0 = UCSWRST;                      // Put eUSCI in reset
       UCA1CTLW0 |= UCSSEL__ACLK;                // CLK = ACLK
       UCA1BR0 = 3;                              // 9600 baud
       UCA1MCTLW |= 0x5300;                      // 32768/9600 - INT(32768/9600)=0.41
       // UCBRSx value = 0x53 (See UG)
       UCA1BR1 = 0;
       UCA1CTL1 &= ~UCSWRST;                     // Initialize eUSCI
       UCA1IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
    
       __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, interrupts enabled  --> remove the LPM3-mode
       __no_operation();
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A1_VECTOR
    __interrupt void USCI_A1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_A1_VECTOR))) USCI_A1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
      {
        case USCI_NONE: break;
        case USCI_UART_UCRXIFG:
          while(!(UCA1IFG&UCTXIFG));
          UCA1TXBUF = 0x55; // for debugging reasons
          __no_operation();
          break;
        case USCI_UART_UCTXIFG: break;
        case USCI_UART_UCSTTIFG: break;
        case USCI_UART_UCTXCPTIFG: break;
      }
    }

  • Hi Yannick,

    I think there is a problem with this setting:

    -----------------------------------------------------------------

       UCA1MCTLW |= 0x5300;                      // 32768/9600 - INT(32768/9600)=0.41
       // UCBRSx value = 0x53 (See UG)

    -----------------------------------------------------------------

    The UG says the following: "(1) The UCBRSx setting in one row is valid from the fractional portion given in that row until the one in the next row".

    For 0.41, it should be set to 0x92. The 0x92 is valid for fractional portion between 0.4003 to 0.4286.

    Srinivas

**Attention** This is a public forum