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 microbit

Hi all,

Well, here'e some feedback to this bizarre issue.
Everything was already volatile, except for the local "temp" variable.
Refer the earlier example below :

> > > UINT temp;
> > >
> > > /* Handle TX buffer wrap */
> >temp = (tx_head+1)%RS232_SIZE;
> > >
> > > /* Disable TX interrupts */
> > > U0IER = 0x01;
> > >
> > > /* Circ buffer not empty ? */
> > > if (comm_tx_running)
> > >     {
> > >     comm_tx[tx_head] = (UCHAR)ch;
> > >     tx_head = temp;
> > >     }
> > > else
> > >     {
> > >     comm_tx_running = 1;
> > >     U0THR = ch;
> > >     }
> > >
> > > /* Reenable TX interrupts */
> > > U0IER = 0x03;
> > > return (ch);

Declaring "temp" volatile didn't help a bit, on the contrary, some tests
started
exhibiting default_IRQs, whereas before they didn't.

It MUST be that the compiler is changing the sequence of things (when I
single step
at C level, it's certainly all over the place) - despite the volatiles.
In any case, even so, I don't get why that should have a bearing on reading
the head_pointer
and increment/wrapping it, and then inside the protected part using the
current pointer, and then
updating it
- VERSUS -
Post incrementing on tx_head while doing the write to comm_tx[] TX buffer.

I must assume that Bill Knight's original speculation that direct writes to
eg. UxIER still
*can* cause "spurious interrupts" is correct.
There must be a mechanism where the write instruction is still be in
execution unit while a
vectored INT request decodes in the VIC.

In any case, I presume that the best prottection is to have it in a separate
function....?
I found that calling a function that explicitly Disables IRQ Global,
sets/clears THRE,
then re-Enables IRQ Global, then returns makes all the permuations of
previous code now
behave as I expected it to, regardless of the method of doing the TX buffer
write and update
of the pointer, and regardless of how I set the optimisation.

This to me implies that the instruction sequences indeed are being changed.
I've been stepping around in ASM, but it is _very_ time consuming, it
started to annoy me :-)
I do intend to fully get to the bottom of this, as I want to know what on
earth was causing these
bizarre behaviours, it seems that it's compiler reordering, I will revisit
this later.
I'm writing 2 functions set_int() and clr_int() that take a register and a
bit number, and then
Enable/Disable individual INTs.

Does that seem like a plausible scenario ????

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.