11 years, 1 month ago.

Error in txIsBusy() ?

I allways use the nice MODSERIAL lib, but now I found a problem with txIsBusy() which I never used before.

Case: Because my 1768 mbed is connected to a RS485 bus with a MAX485 driver, I need to control the transmitter enable input of the MAX485 driver. When mbed has sent its data, I have to switch off the transmitter because only one transmitter can be active on the RS485 A+B lines. For switching off the transmitter, I have to be sure that the mbed UART has sent out all its characters. This is where txIsBusy() is usefull. It should return true when the UART is sending out data.

But I found that txIsBusy() is allways returning false, so the UART is NEVER busy! I found the code for txIsBusy() in MODSERIAL.cpp :

MODSERIAL::txIsBusy( void ) 
{ 
    return ( _LSR & ( 3UL << 5 ) == 0 ) ? true : false; 
} 

I'm not an expert on C syntax, but I think this code will always return false because of two missing brackets. I think it should be :

MODSERIAL::txIsBusy( void ) 
{ 
    return (( _LSR & ( 3UL << 5 )) == 0 ) ? true : false; 
} 

But there is also ANOTHER problem: The function tests BOTH bit 5 (Transmitter Holding Register Empty THRE) and bit 6 (Transmitter Empty TEMT) of the UART Line Status Register (LSR). (see page 307 of LPC1768 manual) I think it is unnecessary to test both bits AND there is a problem involved too: Suppose THRE is 1, meaning the holding reg. is empty, and TEMT is 0 meaning the shiftregister (TSR) is NOT empty yet: the function will return a false in this case, meaning NOT busy and the UART has sent ALL its data but in fact it has NOT ! This is obvious not intended and I think it is best to test only bit 6 (TEMT). When TEMT is equal to 0, the UART is not ready so meaning BUSY. My code to test bit 6 of the LSR (with extra brackets!) would be:

MODSERIAL::txIsBusy( void ) 
{ 
    return (( _LSR & ( 1UL << 6 )) == 0 ) ? true : false; 
} 

This works fine for me and now I REALLY know if the UART has stopped sending! I hope to receive some comment on this, kind regards, L. van der Kolk

Question relating to:

1 Answer

10 years, 2 months ago.

I have just come across the same problem and thankfully Google led me here!

I copied your code (below) and it now works fine now, thanks!

bool
MODSERIAL::txIsBusy( void ) 
{ 
    return (( _LSR & ( 1UL << 6 )) == 0 ) ? true : false; 
} 

Hello Peter, Thanks for your comment, glad it helped you! So far I did'nt receive any comment on this, so I thought maybe I was wrong. Had no time to dive in again. I think I had it posted on the wrong place on this mbed website. It should be corrected in the MODSERIAL library, so maybe you should post it again as a comment on the MODSERIAL library. It's OK for me.

posted by L van der Kolk 03 Feb 2014