Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: [lpc2000] UART TX FIFO and INTs problem - SOLVED

2004-02-22 by Bill Knight

Kris
  Thanks for spotting this.  It's the old spurious interrupt problem.
The fix is to disable global interrupts around the first read-modify-write
instruction.  Doing the direct write (U0IER = xxx) can still allow the problem
to happen.  What happens is the interrupt occurs and is recognized while
the masking instruction is executing but before it has completed.  Then
when the instruction does complete, the interrupt can't find the vector
so uses the default.  So to fix:

Disable global interrupts
mask interrupt
Enable global interrupts

do your stuff
unmask interrupt

NOTE: I don't think this last modification of the mask register needs
protection.  Someone correct me if I am wrong.


Regards
-Bill Knight
R O SoftWare



On Mon, 23 Feb 2004 02:09:38 +1100, microbit wrote:

Hi all,

This s a hairy one - ARM Gurus, please read this !!!
(Bill, this will cause a problem in your UART package too, since you
set VicDefVectAddr to the Reset Vector, and you also use a RMW
operation on UxIER)

I figured out why I was getting "resets" while UART0 is TXing
interrupt driven.
The problem only occurs when I disable the THE interrupt by masking :

U0IER &= ~ 0x02;    /* Disable THE */
......
U0IER |= 0x02;

When I disable and then re-enable THE interrupts with a direct write :

U0IER = 0x01;        /* Disable THE, leave RDA enabled */
.....
U0IER = 0x03;        /* Reenable THE */

I didn't get these "resets".

This is the problem :
-----------------------

I didn't have VicDefVectAddr specified, so it was set to its default 0x00000000
address. (All IRQs are disabled, except for VIC Channel # 6)
While U0IER &= ~ 0x02 is executing, there MUST be a few cycles where the THE
is disabled, BUT the interrupt asserts at the right moment, hence causing a non-vectored
assertion.... (which of course vectors to 0x000000, and ultimately results in a RESET)
Is this a known problem on the VIC ?
Is this normal on the VIC ?

I put in a "dummy" function default_IRQ_handler() so I can break on it, and when it hits
that function, VicRawIntr reads 0x3008.
If I merely indicate on a LED when that function is hit, but then return from interrupt, the
execution happpily picks up after the U0IER &=~0x02; statement, and things run as good as gold.
NO TX interrupts were missed by the looks of it, since the non-vectored dummy function doesn't
service or alter anything, the pending interrupt must be serviced when THE is re-emabled.

Are there any ARM gurus here that can shed some light on this ?
I've been just about driven to tears over this problem.
I can't just use a direct write (I have an interrupt on the other UART in RX, and that operates on
a CRC function, the RF transmit function needs to operate on the same CRC function, so I need
masking of the Interrupt Enables, rather than directly setting/clearing all INT sources on UxIER)

As far as I'm concerned this classifies as a silicon BUG, since UxIER bits cannot assert themselves,
and it is indeed a R/W register.

BTW : How do I work out with VicRawIntr (0x3008 in my case) which Slot/Int is asserted ?
I can't find a bitmap on it.

Best regards,
Kris

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.