This is the mail archive of the ecos-bugs@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug 1001392] New: Generic 16x5x driver misses Rx timeout conditionon LPC1765


Please do not reply to this email. Use the web interface provided at:
http://bugs.ecos.sourceware.org/show_bug.cgi?id=1001392

           Summary: Generic 16x5x driver misses Rx timeout condition on
                    LPC1765
           Product: eCos
           Version: 3.0
          Platform: All
        OS/Version: Other
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: low
         Component: Serial
        AssignedTo: unassigned@bugs.ecos.sourceware.org
        ReportedBy: bernard.fouche@kuantic.com
                CC: ecos-bugs@ecos.sourceware.org
             Class: Advice Request


Hello.

I've found an issue with the generic 16x5x serial driver while working
with a NXP LPC1765. The situation is the following: I'm doing the
usual program/flash/debug cycle. I work with eCos from CVS.

In some circumstances, I halt the target while there are pending
bytes in the Rx FIFO of a channel of the serial controller.

Then I 'soft reset' (using OpenOCD) the target to rerun the software
(of after reflashing code). At that point the serial driver may fall
in a never ending loop there (from
devs/serial/generic/16x5x/current/src/ser_16x5x.c):

    SER_16X5X_READ_ISR(base, _isr);
    while ((_isr & ISR_nIP) == 0) {
        switch (_isr&0xE) {
        case ISR_Rx:
        case ISR_RxTO:
        {
            cyg_uint8 _lsr;
            unsigned char c;
            HAL_READ_UINT8(base+REG_lsr, _lsr);
            while(_lsr & LSR_RSR) {
                HAL_READ_UINT8(base+REG_rhr, c);
                (chan->callbacks->rcv_char)(chan, c);
                HAL_READ_UINT8(base+REG_lsr, _lsr);
            }
            break;
        }
     ... more code ...

The code above assumes that the timeout condition (case ISR_RxTO) implies that
(_lsr & LSR_RSR) is also true, while with the LPC1765, I'm able to get a
timeout but ( _lsr & LSR_RSR) is false.

Here is _isr (aka IIR: Interrupt Indication Register) (on LPC1765
there are 4 bytes between each register, hence the x4 multiplier):

#define REG_isr SER_REG(2)    // Interrupt status register
#define REG_lsr SER_REG(5)    // Line status register

(gdb) printf "0x%08X=%X\n",base+(4*2),*(base+(4*2))
0x4009C008=CC

The lower byte (0x0C) shows:

- interrupt flag set (bit 0 value is 0)
- Character Time-out Indicator (bits 1-3: 110)

Here is _lsr:

(gdb) printf "0x%08X=%X\n",base+(4*5),*(base+(4*5))
0x4009C014=60

Bit 0 is zero: no character is ready for reading...

However emptying the Rx FIFO will reset the timeout condition.

If I manually read the data register...

(gdb) printf "0x%08X=%X\n",base+(4*0),*(base+(4*0))
0x4009C000=0

then the timeout condition is removed:

(gdb) printf "0x%08X=%X\n",base+(4*2),*(base+(4*2))
0x4009C008=C1

There are many different chips based on the 16550 design, with many
different bugs. It's difficult to know if this is a MCU bug or a
'feature' since I found no datasheet, whatever the manufacturer, explicitely
stating that a rx timeout condition must also raise bit 0 of LSR.

The proposed fix is very simple, just change de while() loop to a
do()while loop, to always read at least a byte from the FIFO :

    while ((_isr & ISR_nIP) == 0) {
        switch (_isr&0xE) {
        case ISR_Rx:
        case ISR_RxTO:
        {
            cyg_uint8 _lsr;
            unsigned char c;
            do{
                HAL_READ_UINT8(base+REG_rhr, c);
                (chan->callbacks->rcv_char)(chan, c);
                HAL_READ_UINT8(base+REG_lsr, _lsr);
            }
            while(_lsr & LSR_RSR);
            break;
        }

It's even a bit quicker if a single byte is in the FIFO because _lsr is updated
only once.

-- 
Configure bugmail: http://bugs.ecos.sourceware.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]