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.

Problem setting UART interruption in MSP430FG4618

Other Parts Discussed in Thread: SIMPLICITI, MSP430FG4618

I am trying to set the interruption of the UART port in the MSP430FG4618. The same microcontroller is also using Simpliciti.

The configuration of the UART port is the following:

void UartInit(void)
{    
   UCA0CTL1 |= UCSWRST;      //Configure the USCI with the reset bit held high
   P4SEL &= ~0x0C0;          //P4.7,6 != USCI_A0 RXD/TXD
   P2SEL |= 0x30;            //Set the USCI to use P2.4 and P2.5 for RX/TX
   UCA0CTL1 |= UCSSEL_2;     //Use SMCLK
   UCA0BR0 = 0x45;           //Set Bit Rate to 115200bps with a 8Mhz clock
   UCA0BR1 = 0x00;
   UCA0MCTL = 0x4A;          //Modulation
   UCA0CTL1 &= ~UCSWRST;     //Done configuring so take USCI out of reset
   IFG2 &= ~UCA0RXIFG;
   IE2 |= UCA0RXIE;          //Enable USCI_A0 RX interrupt <-- THIS IS THE PROBLEM
}

The UART port receives and transmits data without any problem if the line "IE2 |= UCA0RXIE;" is commented.

But once I configure the interruption using that line, then the port does not receive anything (with and without using the "#pragma vector=USCIAB0RX_VECTOR     __interrupt void USCIA0RX_ISR (void)" interruption function).

Any suggestion to solve this issue would be great.

Thanks in advance.

gus

  • Do you globally enable interrupts at all? (e.g. with _EINT() or _bis_SR_register(GIE) or such)

    If you enable itnerrupts globally, and enable RX interrupt, and do not have an ISR for it, the CPU will crash.

    If you have the ISR, it should be called when a byte was received. However, it should read RSBUF or at least clear RXIFG befor exiting. Or it will be called over and over again, stopping main.

  • Thanks for answering. About the question, I have enabled the interruptions using _EINT() or _bis_SR_registers(GIE).

    According to your comment, I have a ISR for it, which is the following:

    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCIA0RX_ISR (void)
    {
           while( IFG2 & UCA0RXIFG );
           {
                 ......
           } 
           IFG2 &= ~UCA0RXIFG;
    }

    And even that it does not work.

    More suggestion would be great, thanks in advance.

    gus.

  • gchaconr said:
           while( IFG2 & UCA0RXIFG );
           {
                 ......
           } 
           IFG2 &= ~UCA0RXIFG;

    This is too much. When the while loop exits, UCA0RXIFG is clear. If you manually clerar it then, you best case do a NOP, but worst case clear teh signal that another byte has just arrived.
    And if the RXIFG bti is not cleare dinside the while (w.g. by reading RXBUF), then the while will loop forever anyway.

    However, the ISR should be called as soon as a byte arrived.

  • By the way, I am using "BSP_Init()" from Simpliciti at the beginning of the code to init the MSP430FG4618, and immediately after that I use this function:

    void McuInit(void)
    {
        _DINT();
        WDTCTL = WDTPW + WDTHOLD;               //Stop WDT
        FLL_CTL0 = (DCOPLUS | XCAP18PF);       //Enable Frequency Multiplier (DCO+) and XIN/XOUT caps to 18pF
        SCFI0 = (FLLD_2 | FN_8);               //Set Multiplier to 2, and DCO range to 8MHz nominal
        SCFQCTL = 121;                         //7.995392Mhz Operation with No Modulation
        
        UartInit();
        _EINT();
    }

    to make sure that the UART works as I expect. I am not sure if this could be problem, but when I comment the line "IE2 |= UCA0RXIE;" I do not have any problem in communication via using Simpliciti and via the UART port.

    Thanks in advance for any suggestion.

    gus


  • #include <msp430xg46x.h>

    int main(void)
    {
      volatile unsigned int i;

      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      P4SEL |= 0x03;                            // P4.1,0 = USART1 TXD/RXD
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
      for (i = 0x47FF; i > 0; i--);             // Time for flag to set
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

      ME2 |= UTXE1 + URXE1;                     // Enable USART1 TXD/RXD
      U1CTL |= CHAR;                            // 8-bit character
      U1TCTL |= SSEL1 + SSEL0 + URXSE;          // UCLK = SMCLK, start edge detect
      U1BR0 = 0x37;                             // 1MHz 19200
      U1BR1 = 0x00;                             // 1MHz 19200
      U1MCTL = 0x6B;                            // 1MHz 19200 modulation
      U1CTL &= ~SWRST;                          // Initialize USART state machine
      IE2 |= URXIE1;                            // Enable USART1 RX interrupt

      for (;;)
      {
        while (!(U1TCTL & TXEPT));              // Confirm no TXing before --> LPM3
        _DINT();                                // Disable interrupts for flag test
        _NOP();
        if (!(U1TCTL & SSEL0))
         _BIS_SR(LPM0_bits + GIE);              // RX'ing char, LPM, int's active
        else
         _BIS_SR(LPM3_bits + GIE);              // Enter LPM3, int's active
      }
    }

    #pragma vector=USART1RX_VECTOR
    __interrupt void usart1_rx (void)
    {
      if ((IFG2 & URXIFG1))                     // Test URXIFG0
      {
        while (!(IFG2 & UTXIFG1));              // USART1 TX buffer ready?
        U1TXBUF = U1RXBUF;                      // RXBUF0 to TXBUF0
        _BIC_SR_IRQ(LPM3_bits);                 // Exit LPM3 after reti
        U1TCTL |= SSEL0;                        // SSEL0 = 1, no RX activity
      }
      else                                      // Start edge
      {
        U1TCTL &= ~URXSE;                       // Clear URXS signal
        U1TCTL |= URXSE;                        // Re-enable edge detect
        _BIC_SR_IRQ(SCG1 + SCG0);               // DCO reamins on after reti
        U1TCTL &= ~SSEL0;                       // SSEL0= 0, RX activity
      }
    }
     

    use this code this is verifed so set boad rate at 9600

    vasant mangale

    mit coe

    alandi pune

  • Thanks for the code you posted, but it didn't work at all.

  • gchaconr said:
    I am using "BSP_Init()" from Simpliciti at the beginning of the code to init the MSP430FG4618, and immediately after that I use this function:

    Well, it can be a conflict between your setup and the SimpliciTI. Maybe your ISR is destroying information that the SimpiciTI requires for oepration. Keep in mind that on 2x and 4x family the interrupt vectors are shared between USCI modules and split for RX and TX.

    I don't have any experience with SimpliciTI, so I cannot help you there.

  • Thanks for answering, but I have finally found the problem.

    I changed the ISR as follows:

    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCIA0RX_ISR (void)
    {
           if( IFG2 & UCA0RXIFG )
           {
                 ......

                IFG2 &= ~UCA0RXIFG;
           } 
    }

    and with that the interruption problem is solved, instead of using the previous code which will keep running a while loop forever in the ISR. I think someone made a comment before about that but I didn't realize it until now.

**Attention** This is a public forum