From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17663 invoked by alias); 24 Nov 2011 14:41:15 -0000 Received: (qmail 17656 invoked by uid 22791); 24 Nov 2011 14:41:14 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from hagrid.ecoscentric.com (HELO mail.ecoscentric.com) (212.13.207.197) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 24 Nov 2011 14:40:54 +0000 Received: by mail.ecoscentric.com (Postfix, from userid 48) id 85AE22F78010; Thu, 24 Nov 2011 14:40:51 +0000 (GMT) From: bugzilla-daemon@bugs.ecos.sourceware.org To: unassigned@bugs.ecos.sourceware.org Subject: [Bug 1001392] New: Generic 16x5x driver misses Rx timeout condition on LPC1765 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: eCos X-Bugzilla-Component: Serial X-Bugzilla-Keywords: X-Bugzilla-Severity: enhancement X-Bugzilla-Who: bernard.fouche@kuantic.com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: low X-Bugzilla-Assigned-To: unassigned@bugs.ecos.sourceware.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://bugs.ecos.sourceware.org/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Date: Thu, 24 Nov 2011 14:41:00 -0000 Mailing-List: contact ecos-bugs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: ecos-bugs-owner@sourceware.org X-SW-Source: 2011/txt/msg01339.txt.bz2 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 the assignee for the bug.