AnsweredAssumed Answered

UART Auto-RTS trouble with MCF5271

Question asked by Adam Crowder on Jan 5, 2012
Latest reply on Jul 25, 2013 by TomE

I'm having trouble with the UART feature in the MCF5271 which is supposed to de-assert RTS when the transmit buffer goes empty.  The trouble is that it works most of the time--not terribly useful in a CPU...

 

I've had code in place on this hardware for a while using this, but its failure only became apparent when it was used as a 2-wire RS-485 slave device.  In this situation,  when our slave device sends a reply message but does not de-assert RTS at the end, its transmitter remains ON, effectively killing the entire RS-485 network.

 

My ports are configured:

UMR1 = 0x13 (RxRTS OFF)

UMR2 = 0x27 (TxRTS ON)

 

When transmitting a message, I turn on RTS by writing to UOP1, then enable the transmitter by writing 4 to UCR.  Feeding bytes to the transmitter is done by an ISR.  When the ISR is called, and it has no more bytes to send, it calls a function which disables the transmitter (0x8 > UCR).

 

As I mentioned before, this works to disable RTS when transmission is complete...MOST OF THE TIME.  As a Master on the network, failures were probably dismissed (it would appear as if the slave "did not reply" (when in fact it tried, but was swamped on the network), and would recover when the master sent its next message.

 

The bug appears to happen more frequently when Ethernet traffic is being processed.  This does cause extra interrupts (only on RxE, to manage buffer descriptors).  BUT, it does happen with no Ethernet communications directly to the product.  With Ethernet (cable) disconnected it seldom happens, but still it does happen.

 

My current workaround is hideous: foreground code examines both serial ports by calling:

 

void CheckRTS( int CardinalPort) {
    byte Mask;
    static int Counter[4];
    struct PCBT *PCB;
    if( CardinalPort == 1 ) {
        PCB = (struct PCBT *) &PORT1;
        Mask = 0x04;
    } else if (CardinalPort == 2 ) {
        PCB = (struct PCBT *) &PORT2;
        Mask = 0x40;
    } else {
        return;
    }
    if( PCB->RXEPEND ) { // Set TRUE on call to TransmitterDiable
        if( !PCB->TXENAB ) { // Transmitter is not enabled
            if( (__IPSBAR[ 0x100029] & Mask) == 0) { // RTS is on (reading GPIO_PPDSDR_UARTL)
                Counter[CardinalPort]++;
                    if( Counter[CardinalPort] == 3 )
                        iprintf( "\t***Caught a bug (%d)!\n", CardinalPort);
                    else if( Counter[CardinalPort] > 5000 ) {
                        iprintf( "\t*** Turning RTS OFF on port %d\n", CardinalPort);
                        MCF_UART_UOP0(CardinalPort-1) = 1;
                    }
                return;
            }
        }
    }
    Counter[CardinalPort] = 0;
}

This version of the "patch" leaves the broken situation in place for about 3.6 seconds, so I can observe and 'scope it.

 

I've searched the forums for mention of others running into this problem, but found nothing.  Also, we've looked through the hardware errata for this chip.

 

Any help you can provide would be appreciated.

Outcomes