EmbeddedRelated.com
Forums
Memfault Beyond the Launch

uart tx dropping output

Started by netnimble December 26, 2005
Hello,
I'm doing uart output, and it works properly about 99% of the time.
But every once in a while, I am losing half a line of output.
I've tried to isolate the problem by simplifiing the program to just
be a loop outputting chars on uart0.  I count the number of characters
output via
my u0putc() routine, the number of tx interrupts, and the number of
characters output directly (not buffered).  
It always adds up correctly, i.e., as far as my program knows, it
is outputting all the characters.  My guess now is that is must be
a problem on the other end loosing them.  The other end was a windows
program, but my tests are using just a Win98 HyperTerminal window.
I also used the file copy to make sure it wasn't just the display,
and the file also has the characters lost.   

I'm thinking that somehow its an xon/xoff issue, that I'm not getting
the xoff.  I tried the hyperterm settings with no flow control, and
hardware, and xon/xoff, and it seems to make no difference.  I expected
to get a control-s input char with xon/xoff, but never see it.

Anyone seen something similiar?   Any ideas?  99% is not good enough!
I have no control over the application on the other side of the uart.

thanks for any assistance!

Jack





Beginning Microcontrollers with the MSP430

A little more info.  A tried another terminal program and see the same
results.  I do get an XOFF input, but that is if I hold the scrollbar
and let the terminal buffer fill up which is different than just a
line getting characters lost.  Also, 99% is too low, it's more like
99.999% work right, one 10's of chars out of 100000 chars get lost.
I'm wondering if somehow my buffer or variables are getting changed.
I've included the code below if it might help debug this purplexing
problem.  thanks again for any input.

int u0putc(char ch)
{
  int next;

  u0txcnt++;

 again:
  IE1 &= ~UTXIE0 ;   // disable TX interrupts

  next = u0txtail + 1;
  if (next == U0TXBUFSIZE)
    next = 0;

  // is buffer empty?
  if (u0txhead == u0txtail) {
    u0txbuf[u0txhead] = ch;
    u0txtail = next;
    TXBUF0 = ch;  // start output
    u0txnow++;
  }
  // is buffer full?
  else if (next == u0txhead) {
    // wait until head pointer increments
    IE1 |= UTXIE0;        // enable TX interrupts to allow head advance
    while (next == u0txhead) {
      // do nothing while we wait..
      u0busy++;
    }
    goto again;  // try it again with interrupts disabled
  }
  // add to end of queue
  else {
    u0txbuf[u0txtail] = ch;
    u0txtail = next;
  }
  IE1 |= UTXIE0;        // enable TX interrupts
}


//
// tx interrupt occurs once transmit buffer is cleared
// We can then do the next buffered character if any left
// 
interrupt (UART0TX_VECTOR) u0tx(void)
{
  int next;
  char ch;

  // add a check if tx every busy, debug shows u0txwait always zero.
  while (U0TCTL & TXEPT) { 
    u0txwait++;
  }

  // bump head to next char
  u0txhead = u0txhead + 1;
  if (u0txhead == U0TXBUFSIZE)
    u0txhead = 0;

  if (u0txhead != u0txtail) { // buffer not empty
    ch = u0txbuf[u0txhead]; // get next char
    // debug shows u0txint count matches  u0txcnt + u0txnow
    // which indicates all characters are getting sent 
   u0txint++;
    TXBUF0 = ch; // restart output
    // u0txbuf[u0txhead] = 'X'; // wipe it 
  }
}



>- In msp430@msp4..., "netnimble"
<netnimble@y...> wrote:
>
> Hello,
> I'm doing uart output, and it works properly about 99% of the time.
> But every once in a while, I am losing half a line of output.
> I've tried to isolate the problem by simplifiing the program to just
> be a loop outputting chars on uart0.  I count the number of characters
> output via
> my u0putc() routine, the number of tx interrupts, and the number of
> characters output directly (not buffered).  
> It always adds up correctly, i.e., as far as my program knows, it
> is outputting all the characters.  My guess now is that is must be
> a problem on the other end loosing them.  The other end was a windows
> program, but my tests are using just a Win98 HyperTerminal window.
> I also used the file copy to make sure it wasn't just the display,
> and the file also has the characters lost.   
> 
> I'm thinking that somehow its an xon/xoff issue, that I'm not
getting
> the xoff.  I tried the hyperterm settings with no flow control, and
> hardware, and xon/xoff, and it seems to make no difference.  I expected
> to get a control-s input char with xon/xoff, but never see it.
> 
> Anyone seen something similiar?   Any ideas?  99% is not good enough!
> I have no control over the application on the other side of the uart.
> 
> thanks for any assistance!
> 
> Jack
>





Hello Jack,

a problem that once happened to me was that I forgot to wait for the Tx 
buffer to be empty before transmitting the next character. So, I just 
added a while loop waiting for the UTXIFG flag to turn on again. Maybe 
this is missing in your program, when you transmit a character with the 
Tx interrupt disabled.

Regards,
Adriano.

netnimble wrote:
> A little more info.  A tried another terminal program and see the same
> results.  I do get an XOFF input, but that is if I hold the scrollbar
> and let the terminal buffer fill up which is different than just a
> line getting characters lost.  Also, 99% is too low, it's more like
> 99.999% work right, one 10's of chars out of 100000 chars get lost.
> I'm wondering if somehow my buffer or variables are getting changed.
> I've included the code below if it might help debug this purplexing
> problem.  thanks again for any input.
> 
> int u0putc(char ch)
> {
>   int next;
> 
>   u0txcnt++;
> 
>  again:
>   IE1 &= ~UTXIE0 ;   // disable TX interrupts
> 
>   next = u0txtail + 1;
>   if (next == U0TXBUFSIZE)
>     next = 0;
> 
>   // is buffer empty?
>   if (u0txhead == u0txtail) {
>     u0txbuf[u0txhead] = ch;
>     u0txtail = next;
>     TXBUF0 = ch;  // start output
>     u0txnow++;
>   }
>   // is buffer full?
>   else if (next == u0txhead) {
>     // wait until head pointer increments
>     IE1 |= UTXIE0;        // enable TX interrupts to allow head advance
>     while (next == u0txhead) {
>       // do nothing while we wait..
>       u0busy++;
>     }
>     goto again;  // try it again with interrupts disabled
>   }
>   // add to end of queue
>   else {
>     u0txbuf[u0txtail] = ch;
>     u0txtail = next;
>   }
>   IE1 |= UTXIE0;        // enable TX interrupts
> }
> 
> 
> //
> // tx interrupt occurs once transmit buffer is cleared
> // We can then do the next buffered character if any left
> // 
> interrupt (UART0TX_VECTOR) u0tx(void)
> {
>   int next;
>   char ch;
> 
>   // add a check if tx every busy, debug shows u0txwait always zero.
>   while (U0TCTL & TXEPT) { 
>     u0txwait++;
>   }
> 
>   // bump head to next char
>   u0txhead = u0txhead + 1;
>   if (u0txhead == U0TXBUFSIZE)
>     u0txhead = 0;
> 
>   if (u0txhead != u0txtail) { // buffer not empty
>     ch = u0txbuf[u0txhead]; // get next char
>     // debug shows u0txint count matches  u0txcnt + u0txnow
>     // which indicates all characters are getting sent 
>    u0txint++;
>     TXBUF0 = ch; // restart output
>     // u0txbuf[u0txhead] = 'X'; // wipe it 
>   }
> }
> 
> 
> 
> 
>>- In msp430@msp4..., "netnimble" <netnimble@y...> wrote:
>>
>>Hello,
>>I'm doing uart output, and it works properly about 99% of the time.
>>But every once in a while, I am losing half a line of output.
>>I've tried to isolate the problem by simplifiing the program to
just
>>be a loop outputting chars on uart0.  I count the number of characters
>>output via
>>my u0putc() routine, the number of tx interrupts, and the number of
>>characters output directly (not buffered).  
>>It always adds up correctly, i.e., as far as my program knows, it
>>is outputting all the characters.  My guess now is that is must be
>>a problem on the other end loosing them.  The other end was a windows
>>program, but my tests are using just a Win98 HyperTerminal window.
>>I also used the file copy to make sure it wasn't just the display,
>>and the file also has the characters lost.   
>>
>>I'm thinking that somehow its an xon/xoff issue, that I'm not
getting
>>the xoff.  I tried the hyperterm settings with no flow control, and
>>hardware, and xon/xoff, and it seems to make no difference.  I expected
>>to get a control-s input char with xon/xoff, but never see it.
>>
>>Anyone seen something similiar?   Any ideas?  99% is not good enough!
>>I have no control over the application on the other side of the uart.
>>
>>thanks for any assistance!
>>
>>Jack
>>
> 
> 
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 

Hi,
after a quick look at your code i got the impression you are not 
handshaking at all.

With a MS Windows PC you cannot do that. MS Windows occasionally doesn't 
receive on serial input lines, since that interface is considered 
obsolete resp. low priority.

You can use some kind of ACK/NAK protocol to solve this, eventually 
repeating important data. Or use some USB-RS232 adapter instead, that 
should be more reliable in that respect, especially when running at high 
baud rates.

Regards,
D. Teuchert

netnimble wrote:

>A little more info.  A tried another terminal
program and see the same
>results.  I do get an XOFF input, but that is if I hold the scrollbar
>and let the terminal buffer fill up which is different than just a
>line getting characters lost.  Also, 99% is too low, it's more like
>99.999% work right, one 10's of chars out of 100000 chars get lost.
>I'm wondering if somehow my buffer or variables are getting changed.
>I've included the code below if it might help debug this purplexing
>problem.  thanks again for any input.
>
>int u0putc(char ch)
>{
>  int next;
>
>  u0txcnt++;
>
> again:
>  IE1 &= ~UTXIE0 ;   // disable TX interrupts
>
>  next = u0txtail + 1;
>  if (next == U0TXBUFSIZE)
>    next = 0;
>
>  // is buffer empty?
>  if (u0txhead == u0txtail) {
>    u0txbuf[u0txhead] = ch;
>    u0txtail = next;
>    TXBUF0 = ch;  // start output
>    u0txnow++;
>  }
>  // is buffer full?
>  else if (next == u0txhead) {
>    // wait until head pointer increments
>    IE1 |= UTXIE0;        // enable TX interrupts to allow head advance
>    while (next == u0txhead) {
>      // do nothing while we wait..
>      u0busy++;
>    }
>    goto again;  // try it again with interrupts disabled
>  }
>  // add to end of queue
>  else {
>    u0txbuf[u0txtail] = ch;
>    u0txtail = next;
>  }
>  IE1 |= UTXIE0;        // enable TX interrupts
>}
>
>
>//
>// tx interrupt occurs once transmit buffer is cleared
>// We can then do the next buffered character if any left
>// 
>interrupt (UART0TX_VECTOR) u0tx(void)
>{
>  int next;
>  char ch;
>
>  // add a check if tx every busy, debug shows u0txwait always zero.
>  while (U0TCTL & TXEPT) { 
>    u0txwait++;
>  }
>
>  // bump head to next char
>  u0txhead = u0txhead + 1;
>  if (u0txhead == U0TXBUFSIZE)
>    u0txhead = 0;
>
>  if (u0txhead != u0txtail) { // buffer not empty
>    ch = u0txbuf[u0txhead]; // get next char
>    // debug shows u0txint count matches  u0txcnt + u0txnow
>    // which indicates all characters are getting sent 
>   u0txint++;
>    TXBUF0 = ch; // restart output
>    // u0txbuf[u0txhead] = 'X'; // wipe it 
>  }
>}
>
>
>
>  
>
>>- In msp430@msp4..., "netnimble" <netnimble@y...> wrote:
>>
>>Hello,
>>I'm doing uart output, and it works properly about 99% of the time.
>>But every once in a while, I am losing half a line of output.
>>I've tried to isolate the problem by simplifiing the program to
just
>>be a loop outputting chars on uart0.  I count the number of characters
>>output via
>>my u0putc() routine, the number of tx interrupts, and the number of
>>characters output directly (not buffered).  
>>It always adds up correctly, i.e., as far as my program knows, it
>>is outputting all the characters.  My guess now is that is must be
>>a problem on the other end loosing them.  The other end was a windows
>>program, but my tests are using just a Win98 HyperTerminal window.
>>I also used the file copy to make sure it wasn't just the display,
>>and the file also has the characters lost.   
>>
>>I'm thinking that somehow its an xon/xoff issue, that I'm not
getting
>>the xoff.  I tried the hyperterm settings with no flow control, and
>>hardware, and xon/xoff, and it seems to make no difference.  I expected
>>to get a control-s input char with xon/xoff, but never see it.
>>
>>Anyone seen something similiar?   Any ideas?  99% is not good enough!
>>I have no control over the application on the other side of the uart.
>>
>>thanks for any assistance!
>>
>>Jack
>>
>>    
>>
>
>
>
>
>
>
>
>.
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>  
>





Adriano, thanks for the suggestion.
There should never be any need to wait for the xmit flag in u0putc because it
only outputs a character if the buffer is empty, which means that no characters
would have been output previously.
Once it outputs the character, it has put something in the buffer, and only the
tx interrupt routine "removes" something from the buffer when the
intterupt
occurs.
But I'll put in check anyway to see if it ever triggers,
stranger things have happened..

Jack


>>>
a problem that once happened to me was that I forgot to wait for the Tx 
buffer to be empty before transmitting the next character. So, I just 
added a while loop waiting for the UTXIFG flag to turn on again. Maybe 
this is missing in your program, when you transmit a character with the 
Tx interrupt disabled.



Jack,
Maybe you should check the voltage levels of RS232 TX line along the whole
communication. I have seen a level shifter with bad oscillator (that
converts the 3.3V supply to +10/-10V necessary for RS232 levels) that failed
to provide the voltage in the end of a communication package. For RS232 the
minimum levels should be -3V and +3V but there are receivers that does not
accept this low voltage.
-Augusto


-----Mensagem original-----
De: msp430@msp4... [mailto:msp430@msp4...] Em nome de kelly
murray
Enviada em: sexta-feira, 30 de dezembro de 2005 01:06
Para: msp430@msp4...
Assunto: [msp430] Re: Re: uart tx dropping output


Adriano, thanks for the suggestion.
There should never be any need to wait for the xmit flag in u0putc because
it
only outputs a character if the buffer is empty, which means that no
characters
would have been output previously.
Once it outputs the character, it has put something in the buffer, and only
the
tx interrupt routine "removes" something from the buffer when the
intterupt
occurs.
But I'll put in check anyway to see if it ever triggers,
stranger things have happened..

Jack


>>>
a problem that once happened to me was that I forgot to wait for the Tx 
buffer to be empty before transmitting the next character. So, I just 
added a while loop waiting for the UTXIFG flag to turn on again. Maybe 
this is missing in your program, when you transmit a character with the 
Tx interrupt disabled.





.

 
Yahoo! Groups Links



 



-- 

 



Memfault Beyond the Launch