Forums

Lost UART1 IRQ?

Started by vajper0 July 19, 2005
I'm writing a driver for UART1 on a LPC2138. So far most things seems
to work (considering the crappy hardware capabilities). My current
problem is that I loose interrupts when receiving data.

I run the UART in 115200bps and my ISR takes care of all IRQs except
the modem status ones that are not enabled. If I send a block of a
couple of hundreds characters, sometimes one RDA IRQ is lost. I know
this because the missing data always are the size of the Rx trigger level.

The ISR reads the U1IIR once in the beginning, compares the register
data to the different IRQ types in priority order. The first matching
type is handled (and the IRQ resetted), the U1IIR is then read again
and so on. When no more pending IRQs, the ISR is exited. When a

Am I missing something essential?


An Engineer's Guide to the LPC2100 Series

--- In lpc2000@lpc2..., "vajper0" <ph@w...> wrote:
> I'm writing a driver for UART1 on a LPC2138. So far most things
seems
> to work (considering the crappy hardware capabilities). My current
> problem is that I loose interrupts when receiving data.
>
> I run the UART in 115200bps and my ISR takes care of all IRQs except
> the modem status ones that are not enabled. If I send a block of a
> couple of hundreds characters, sometimes one RDA IRQ is lost. I know
> this because the missing data always are the size of the Rx trigger
level.
>
> The ISR reads the U1IIR once in the beginning, compares the register
> data to the different IRQ types in priority order. The first
matching
> type is handled (and the IRQ resetted), the U1IIR is then read again
> and so on. When no more pending IRQs, the ISR is exited. When a
>
> Am I missing something essential?

I am also doing the same type of situation on a 2119. When it works
it works great but when it doesn't well it just doesn't work. There
is errata on the UART1 for the 2119 but I should be working around
it. I found that if I could send a continual stream of data and it
linked from the start it would usually work without issue. If I
place the serial link after the fact it only seems to work 1/4 of the
time if that.

I wish I could be of more help to you other then to say you are not
the only one and I have been able to reproduce it on a LPC2119. I am
very interested in hearing any possible solutions.


--- In lpc2000@lpc2..., "genie_23432" <pascal_poirier@h...>
wrote:
> --- In lpc2000@lpc2..., "vajper0" <ph@w...> wrote:
> > I'm writing a driver for UART1 on a LPC2138. So far most things
> seems
> > to work (considering the crappy hardware capabilities). My current
> > problem is that I loose interrupts when receiving data.
> >
> > I run the UART in 115200bps and my ISR takes care of all IRQs
except
> > the modem status ones that are not enabled. If I send a block of a
> > couple of hundreds characters, sometimes one RDA IRQ is lost. I
know
> > this because the missing data always are the size of the Rx
trigger
> level.
> >
> > The ISR reads the U1IIR once in the beginning, compares the
register
> > data to the different IRQ types in priority order. The first
> matching
> > type is handled (and the IRQ resetted), the U1IIR is then read
again
> > and so on. When no more pending IRQs, the ISR is exited. When a
> >
> > Am I missing something essential?
>
> I am also doing the same type of situation on a 2119. When it
works
> it works great but when it doesn't well it just doesn't work.
There
> is errata on the UART1 for the 2119 but I should be working around
> it. I found that if I could send a continual stream of data and it
> linked from the start it would usually work without issue. If I
> place the serial link after the fact it only seems to work 1/4 of
the
> time if that.
>
> I wish I could be of more help to you other then to say you are not
> the only one and I have been able to reproduce it on a LPC2119. I
am
> very interested in hearing any possible solutions.

Added info I forgot to include.

In my case I find that the UART1 U1FCR bit FIFO Enable is often
cleared randomly. I also find that the U1FCR Tx FIFO Reset bit gets
set high randomly, usually along with the clearing of the enable
bit. I have not been able to determine what is causing these bits to
change since I only touch then in setup and to flush the receive FIFO
if a receive error occurs (even without an error the still change).
The UART usually seems to keep working after the fifo bit goes low
but every time the UART does not work the FIFO enable bit does appear
to be zero.

Anyone have any ideas on what I am doing wrong to cause the setup
bits to change on their own?


--- In lpc2000@lpc2..., "vajper0" <ph@w...> wrote:
> I'm writing a driver for UART1 on a LPC2138. So far most things seems
> to work (considering the crappy hardware capabilities). My current
> problem is that I loose interrupts when receiving data.
>
> I run the UART in 115200bps and my ISR takes care of all IRQs except
> the modem status ones that are not enabled. If I send a block of a
> couple of hundreds characters, sometimes one RDA IRQ is lost. I know
> this because the missing data always are the size of the Rx trigger
level.
>
> The ISR reads the U1IIR once in the beginning, compares the register
> data to the different IRQ types in priority order. The first matching
> type is handled (and the IRQ resetted), the U1IIR is then read again
> and so on. When no more pending IRQs, the ISR is exited. When a
>
> Am I missing something essential?

Hello,

I use a 2132, but the initial development was done on a 2138
evaluation board from keil, the M something 2130.
I have interrupt comm at 115200, and do not seem to miss any.
Do you enable the FIFO? If so, do you empty the FIFO each RX data
IRQ? If so, do you also enable the TIMEOUT IRQ and collect the
remainder data (less than one FIFO).
In my application, I set the FIFO to 14 bytes (the maximum).
In the IRQ I loop until the IIR reads no pending.
As this application also uses rs485 half duplex, I thought the TEMPT
(transmitter empty) bit could generate an interrupt, and the
direction could be dropped changed back to listen. But it does not, so
on tx complete, a flag is set, and the timer IRQ looks for the TEMPT
bit and does it's thing.
A similar thing to detect when the line is available, each RX IRQ,
set the 'receiving' flag, and mark the time of the reception. When 'a
certain amount of time has passed without receiving characters' could
be a clear channel.
A slight modification of this was, when the TIMEOUT interrupt
occurs, this indicates clear channel of at least '3.5' character
times, and this can be used. Well infact it is used, but the other
method also remains, as what if the last block of received data is
exactly one FIFO long, then no TIMEOUT IRQ will come, and so the timer
method of clear channel detection is used. This is controlled by a
single flag and a time of last reception value.

Anything else?
Being at home now, the code is not available, but I could send
something tomorrow when I get to work. But really, it's not that
difficult.

Dave




> Do you enable the FIFO? If so, do you empty the FIFO each RX data
> IRQ? If so, do you also enable the TIMEOUT IRQ and collect the
> remainder data (less than one FIFO).

The FIFO is enabled.When I get a RDA IRQ I read 14 bytes (FIFO
threshold). When I get a CTI I read until the LSR0-bit is cleared.
Maybee I should try the same loop when I get the RDA IRQ to be sure
there aren't another full FIFO? If that's the case, shouldn't that
generate another pending RDA IRQ?

/PH


vajper0 <ph@ph@....> schrieb am Tue, 19 Jul 2005 13:32:39 -0000:
>
> The FIFO is enabled.When I get a RDA IRQ I read 14 bytes (FIFO
> threshold).

Do you really read 14 bytes or until the UART indicates FIFO empty ?
You might have received a 15th byte.
--
42Bastian Schick



--- In lpc2000@lpc2..., "Dave" <dgsomerton@w...> wrote:
> --- In lpc2000@lpc2..., "vajper0" <ph@w...> wrote:
> > I'm writing a driver for UART1 on a LPC2138. So far most things
seems
> > to work (considering the crappy hardware capabilities). My current
> > problem is that I loose interrupts when receiving data.
> >
> > I run the UART in 115200bps and my ISR takes care of all IRQs
except
> > the modem status ones that are not enabled. If I send a block of a
> > couple of hundreds characters, sometimes one RDA IRQ is lost. I
know
> > this because the missing data always are the size of the Rx
trigger
> level.
> >
> > The ISR reads the U1IIR once in the beginning, compares the
register
> > data to the different IRQ types in priority order. The first
matching
> > type is handled (and the IRQ resetted), the U1IIR is then read
again
> > and so on. When no more pending IRQs, the ISR is exited. When a
> >
> > Am I missing something essential?
>
> Hello,
>
> I use a 2132, but the initial development was done on a 2138
> evaluation board from keil, the M something 2130.
> I have interrupt comm at 115200, and do not seem to miss any.
> Do you enable the FIFO? If so, do you empty the FIFO each RX data
> IRQ? If so, do you also enable the TIMEOUT IRQ and collect the
> remainder data (less than one FIFO).
> In my application, I set the FIFO to 14 bytes (the maximum).
> In the IRQ I loop until the IIR reads no pending.
> As this application also uses rs485 half duplex, I thought the
TEMPT
> (transmitter empty) bit could generate an interrupt, and the
> direction could be dropped changed back to listen. But it does not,
so
> on tx complete, a flag is set, and the timer IRQ looks for the TEMPT
> bit and does it's thing.
> A similar thing to detect when the line is available, each RX IRQ,
> set the 'receiving' flag, and mark the time of the reception.
When 'a
> certain amount of time has passed without receiving characters'
could
> be a clear channel.
> A slight modification of this was, when the TIMEOUT interrupt
> occurs, this indicates clear channel of at least '3.5' character
> times, and this can be used. Well infact it is used, but the other
> method also remains, as what if the last block of received data is
> exactly one FIFO long, then no TIMEOUT IRQ will come, and so the
timer
> method of clear channel detection is used. This is controlled by a
> single flag and a time of last reception value.
>
> Anything else?
> Being at home now, the code is not available, but I could send
> something tomorrow when I get to work. But really, it's not that
> difficult.
>
> Dave

Firstly I figured out one of my issues. I was trying to setup a HDLC-
ish style link since I need to send packets of data. I was using the
7E for the flag and idle in the link as specified. Figured out if
you send a constant stream of these its very easy for the UART to mis-
interpret the start bit and receive F9 characters instead of 7E. I
changed the flag character and this changed some of my issues but not
all.

With that said I still have all the other issues related to
interrupts and errors. What I do is check the U1IIR and then go to
the proper subroutine depending on what interrupt it specifies. In
the transmit routine I send out the buffered data or idle characters
till the TX FIFO is full. In the receive routine I read all the
characters till the RDA bit goes low in the U1LSR register therefor
emptying the RX FIFO. I suspect I do not use the character timeout
much since I am sending idle characters to ensure the link is always
active so I can tell if the link is broken as soon as it occurs.
Once these subroutines are done I go back to the main interrupt
service routine and check to see if another serial interrupt is
pending and process it also.

I also check for errors in U1LSR as I am reading data and am clearing
them by reading and discarding the data. I also was flushing the RX
FIFO but commented that part out for the moment incase that was the
cause of some of my issues.

Any info you can give me would be great. Thank you.

Pascal


--- In lpc2000@lpc2..., 42Bastian Schick <bastian42@m...> wrote:

> Do you really read 14 bytes or until the UART indicates FIFO empty ?
> You might have received a 15th byte.

I always read 14 bytes. If there are more data in the FIFO I get that
the next time I get a Rx IRQ.

/PH


Hi again!

I just rewrote much of the UART code to slim it down and make it more
efficient. It was rather crappy because it was using a buffer library
that I couldn't modify. Removed that buffer and wrote a simple ring
buffer. Also modded the code to read more than the 14 bytes when a RDA
IRQ occured (now reads until LSR0 is cleared).

Guess what? Now it works flawlessly!

Another good thing is that I just checked the Philips website (haven't
looked there for a couple of weeks) and found a newly published Users
Manual for the LPC213x series. It describes a new UART register that
can be used to halt the Tx FIFO without resetting it. Extremly useful
when implementing flow control :)

Thanx for the help!

/PH


--- In lpc2000@lpc2..., "vajper0" <ph@w...> wrote:
> Hi again!
>
> I just rewrote much of the UART code to slim it down and make it more
> efficient. It was rather crappy because it was using a buffer library
> that I couldn't modify. Removed that buffer and wrote a simple ring
> buffer. Also modded the code to read more than the 14 bytes when a RDA
> IRQ occured (now reads until LSR0 is cleared).
>
> Guess what? Now it works flawlessly!
>
> Another good thing is that I just checked the Philips website (haven't
> looked there for a couple of weeks) and found a newly published Users
> Manual for the LPC213x series. It describes a new UART register that
> can be used to halt the Tx FIFO without resetting it. Extremly useful
> when implementing flow control :)
>
> Thanx for the help!
>
> /PH

Glad to hear that you solved your issue. I did have a few minor issues
in my code that where causing me grief. But one fundimental thing I
have yet to solve with my issu is why my FIFO is getting disabled by
itself. Most of the time when I currently have an issue the U1FCR0 bit
is cleared and the U1FCR2 bit is set (this last bit should be auto
clearing). I have no idea how this is happening since I not modifying
those two bits at any point except during setup. I do use the fifo rx
flush in certain cases but have breakpoints set and they never get
triggered when this happens.

Also worth noting is I am currently getting into an infinite loop
trying to service my serial interrupt. I end up getting into a case
where the CTI interrupt is set in the IIR register stating there are
characters to be read from the FIFO. The problem is that according to
the LSR0 bit there is no data in the fifo. I have tried reading fake
data and have tried flushing the fifo but nothing seems to clear this
interrupt from the IIR register. Any ideas what I am missing here? I
am going to play around with it some more today and hopefully find
something but any suggestions would be helpful.

Loosing hairs by the handful... :^)