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.

Not Answered! Loop Back with RS422 --- I came to this point!

For the Loop Back Test I came to the following code. I still have not got it to work!

#include "msp430f47197.h"
int y;
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog
  
   P1SEL  |=  BIT6 + BIT7;  // P1.1 UCA1RXD/TXD input
  
   UCA1CTL1 |=  UCSSEL_2 + UCSWRST;  // USCI Clock = SMCLK,USCI_A0 disabled
   UCA1BR0   =  104;                 // 104 From datasheet table-  
   UCA1BR1   =  0;                   // -selects baudrate =9600,clk = SMCLK
   UCA1MCTL  =  UCBRS_1;             // Modulation value = 1 from datasheet
  // UCA0STAT |=  UCLISTEN;            // loop back mode enabled 
   UCA1CTL1 &= ~UCSWRST;             // Clear UCSWRST to enable USCI_A0
      
  //---------------- Enabling the interrupts ------------------//

 
   
   UC1IE |= UCA1TXIE;                  // Enable the Transmit interrupt
   UC1IE |= UCA1RXIE;                  // Enable the Receive  interrupt
   _BIS_SR(GIE);                     // Enable the global interrupt
      
 
   _BIS_SR(LPM0_bits + GIE);         // Going to LPM0
}

  //-----------------------------------------------------------------------//
  //                Transmit and Receive interrupts                        //
  //-----------------------------------------------------------------------//

  #pragma vector = USCIAB1TX_VECTOR
  __interrupt void TransmitInterrupt(void)
  {
    UCA1TXBUF  = '1';
   
  }

  #pragma vector = USCIAB1RX_VECTOR
  __interrupt void ReceiveInterrupt(void)
  {
   
   UC1IFG &= ~UCA1RXIFG; // Clear RX flag 
   if (UCA1RXBUF == '1')
   {

     y++;
   }
  }

When I have loop back ON  the code does not go to the

"

 #pragma vector = USCIAB1RX_VECTOR

"

But when it is connected to the Hyper Terminal and sees '1', it goes to the interrupt!

  • Also, I realized that I cannot have the following code if I want to have loop Back! Because, loopback cannot interrupt the TX and then ask for RX!

    #pragma vector = USCIAB1RX_VECTOR
      __interrupt void ReceiveInterrupt(void)
      {
       
       UC1IFG &= ~UCA1RXIFG; // Clear RX flag 
       if (UCA1RXBUF == '1')
       {
    
         y++;
       }

    Because the way I send from Hyper is totally different than from the Loopback!

    However, I don't know what to use instead!

  • where is the trigger of the first txifg?, to set of the chain reaction.
  • Oh! You mean I miss the flag set for TX?!
  • Something needs to set it off, so in main write a char to TXBUF.
    Or set IFG bit (e.g faking that something triggered a IRQ)
  • Then should I remove TXBUF from the interrupt then?

  • You want that the tx-uart to continuously to send '1'
    once a char is transferred to the pipeline the txbuff is ready for another char it will generate a irq.

    But you must see that the isr just sitting there by itself will not start this chain-reaction.

    UC1IE |= UCA1TXIE; // Enable the Transmit interrupt
    UC1IFG |= UCA1TXIFG; // trigger chain-reaction <<<<<<<<<

    P.S this is not needed: UC1IFG &= ~UCA1RXIFG; // Clear RX flag 
    Reading RXBUF clears it.

  • There could be something wrong with me today.

    I disagree with what Tony said about TXD needing something else to start the chain reaction in that ISR. I think that IFG is already set by the UART setup routine to begin with.

    I also disagree with what CaEngneer said about the RX ISR cannot be used.

    As for the original code posted, I think the loop-back (line #13) was commented out and that is why it does not loop back.
  • old_cow_yellow said:
    I think the loop-back (line #13) was commented out and that is why it does not loop back.

    No! We used the hardware loopback not the software one! That's why I commented out! We need to have the RX what we had sent through TX! But it does not!

  • The code looks good at first.
    The 'BIS_SR(GIE)" is superfluous and may even be dangerous in ode rsituations, as it allows interrupts before oyu catually enter LPM. Depending on the code, your interrup that ends LMP may be executed before you actually enter LPM, leadign to a deadlock. But here it is no problem.
    As a mater of fact, it happens here right now. When UCSWRST is cleared, TXIFG is instantly set (since TXBUF is empty). This starts the sending loop. So like OCY said, no need to manually trigger anything.
    However, Tony is right about manually clearing RXIFG - it already happens when you read RXBUF in the next line.

    BUT, as we now know the transmission is RS422. I don't see any handling of the transmit/receive enable controls of the RS422 drivers. Are they always enabled (no controls at all)? Or are their control lines hardwired to VCC/GND?
    If you connect TX with RX, did you check polarity twice? What about termination resistors and line biasing?
    You may hook a scope to the TX and RX lines to see what really happens. Also, checking the RS422 lines could reveal interesting details including echoes, bad signal edges, whatever.

    A possible problem is the baudrate. Are you sure the device runs on 1MHz by default? The 4x family has an FLL but it requries an activated 32kHz crystal and I don't see any code dealign with the clock system.
    However, for a loopback test this is unimportant, as the RX runs on the same baudrate as the TX, no matter what it might be.
  • Michael,

    Thanks for your reply, I did the following changes. And like the previous time I have nothing. However, when I use my other device which has Loop back + battery power, sometimes I receive garbage!!! such as A with two dots on top and Y with two dots on top! (extended Ascii chart)

    I believe that I do not have enough time to grab what I have sent through TX!

    As you said my Simple loop back has only TX(+ to +) and RX(- to -) but in the battery powered the ground which is pin 5 is also considered!

    That's why you talk about resistors and biasing! I guess the bias is now OK but my buffer is getting garbage!

    Oh I see the baud rate, I did not check for that!  UCA1BR0!

    Um..... I am getting closer I guess!

    #include "msp430f47197.h"
    int y;
    void main(void)
    {
       WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog
      
       P1SEL  |=  BIT6 + BIT7;  // P1.1 UCA1RXD/TXD input
      
       UCA1CTL1 |=  UCSSEL_2 + UCSWRST;  // USCI Clock = SMCLK,USCI_A0 disabled
       UCA1BR0   =  104;                 // 104 From datasheet table-  
       UCA1BR1   =  0;                   // -selects baudrate =9600,clk = SMCLK
       UCA1MCTL  =  UCBRS_1;             // Modulation value = 1 from datasheet
      // UCA0STAT |=  UCLISTEN;            // loop back mode enabled 
       UCA1CTL1 &= ~UCSWRST;             // Clear UCSWRST to enable USCI_A0
          
      //---------------- Enabling the interrupts ------------------//
    
     // UCA1TXBUF = 'B';
       
       UC1IE |= UCA1TXIE;                  // Enable the Transmit interrupt
       UC1IE |= UCA1RXIE;                  // Enable the Receive  interrupt
       _BIS_SR(GIE);                     // Enable the global interrupt
    //    while (!(UC1IFG & UCA1TXIFG));       
      // UCA1TXBUF = 'A';                  // Transmit a byte 
    //      __delay_cycles(1000);
       
       
       
       
       _BIS_SR(LPM0_bits + GIE);         // Going to LPM0
    }
    
      //-----------------------------------------------------------------------//
      //                Transmit and Receive interrupts                        //
      //-----------------------------------------------------------------------//
    
      #pragma vector = USCIAB1TX_VECTOR
      __interrupt void TransmitInterrupt(void)
      {
        UCA1TXBUF  = '@';
       while (!(UC1IFG & UCB1TXIFG));
       UC1IE &= ~UCB1TXIE;
       UC1IFG &= ~UCB1TXIFG;
       __bic_SR_register_on_exit(LPM0_bits);
      }
    
      #pragma vector = USCIAB1RX_VECTOR
      __interrupt void ReceiveInterrupt(void)
      {
       
       UC1IFG &= ~UCA1RXIFG; // Clear RX flag 
       if (UCA1RXBUF == '@')
       {
    //   goto TT; 
       y++;
        // __delay_cycles(1000);
       }
      }

  • This does not make sense to me!!!

    I changed the code to the following and with playing the wire ( figure) I get those garbage!

    #include "msp430f47197.h"
    int y;
    void main(void)
    {
       WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog
      
       P1SEL  |=  BIT6 + BIT7;  // P1.1 UCA1RXD/TXD input
      
       UCA1CTL1 |=  UCSSEL_2 + UCSWRST;  // USCI Clock = SMCLK,USCI_A0 disabled
       UCA1BR0   =  104;                 // 104 From datasheet table-  
       UCA1BR1   =  0;                   // -selects baudrate =9600,clk = SMCLK
       UCA1MCTL  =  UCBRS_1;             // Modulation value = 1 from datasheet
       UCA1CTL1 &= ~UCSWRST;             // Clear UCSWRST to enable USCI_A0
          
      //---------------- Enabling the interrupts ------------------//
    
    
       
       UC1IE |= UCA1TXIE;                  // Enable the Transmit interrupt
       UC1IE |= UCA1RXIE;                  // Enable the Receive  interrupt
       _BIS_SR(GIE);                     // Enable the global interrupt
    
       
       while (1)
       {
         
         UCA1TXBUF  = '1'; 
     
       
       
         
      
       }
       
       
      
    }
    
      //-----------------------------------------------------------------------//
      //                Transmit and Receive interrupts                        //
      //-----------------------------------------------------------------------//
    
    
      #pragma vector = USCIAB1RX_VECTOR
      __interrupt void ReceiveInterrupt(void)
      {
        UC1IFG &= ~UCA1RXIFG; // Clear RX flag 
       if (UCA1RXBUF == '1')
       {
         
         y++;
       } 
        
      }


  • Getting garbage usually is a sign of a wrong baudrate. But in your case, TX and RX baudrate are always the same. Another possible reason could be a disabled transmitter and missing biasing resistors. So the RX side is just receiving noise from EMI, which sometimes seems to be a valid UART byte frame.

    Biasing resistors are a pull-up of the + line to VCC and the - line to GND, so if no transmitter is on, the line is in a defined state and not floating.
    Also, a shorting resistor between the two line eiminates echoes. In our RS485, we have 1k to VCC and GND and 470R between the lines. That means, when no transmitter is on, the A line is on 3V and the B line on 2V, giving a comfortable 1V signal difference (0.2V is the usual threshold) while shorting all EMI.

    When you send form PC to the device, the PC transmitter is on and you receive valid data.
    Did you ever receive anything on the PC from the MSP?

**Attention** This is a public forum