The weirdest of things..... Interrupts and port toggling.

Started by adrianunderwater April 14, 2008
Hi, I initially posted this problem under the heading:

"lpc2138 uart1 drops interrupts" however I have ascertained that the
UART1 is not missing any interrupt... But I am still stumped by my
problem.

In a nutshell, in the interrupt routine for uart1 transmit fifo empty,
I have the following snippet of code.

cmp W4,#0 ; No more characters to send,
bne int_uart1_thre2 ; execute the following

ldr W3,__IO ; Set 1 pin high and the other pin low
mov W,#PIN_TXEN ; __IO holds the base address of IO regs
str W,[W3,#IO0CLR]
mov W,#PIN_TXEN_
str W,[W3,#IO0SET]

ldr W6,fifo1temp ; Put into variable fifo1temp
str W3,[W6] ; the address of port0
ldr W,[W3,#PORT0] ; and the contents of port0
str W,[W6,#4]

b int_uart1_thre3 ; go to exit portion of interrupt.

All this works very well, except every hour or so, even though this
code is actually executed 100 times a second, (verified by reading the
variable fifo1temp) the 2 pins are not set/cleared to what they should
be. And this even though the variable has the proper values reflecting
what should be a proper operation.

When the TXEN and TXEN_ pins aren't toggled, communications stop, so I
can manually read the port values and peek and poke around. The
variable fifo1temp contents clearly show that the interrupt routine
has executed the above, and reading the port0 value shows that it has
had no effect.

And anywhere in the code where port0 is modified, the variable
fifo1temp is also modified... So I can reasonable assume that nowhere
else in my code is the port being changed without my knowing it.

I assumed at one point that this could be the MAM.2 bug...
But I have had the same behaviour in the following configurations:

mamcr=2 mamtim=3 clk = just under 60MHz (Prime condition for MAM.2 bug)

mamcr=1 mamtim=3 clk = just under 60MHz (errata sheet says this is a
work around for mam.2 bug)

mamcr=2 mamtim=5 clk = just under 60MHz
mamcr=1 mamtim=5 clk = just under 60MHz

And the three above cases with clk = 44MHz...

Does anyone have an idea for further investigation?
Thanks Adrian

An Engineer's Guide to the LPC2100 Series

Hi,

did you checked your code for re-entracy problems? Port0 state may be
mixed up if the IRQ fires between an IOCLR and an IOSET access.

Foltos

adrianunderwater wrote:
> Hi, I initially posted this problem under the heading:
>
> "lpc2138 uart1 drops interrupts" however I have ascertained that the
> UART1 is not missing any interrupt... But I am still stumped by my
> problem.
>
> In a nutshell, in the interrupt routine for uart1 transmit fifo empty,
> I have the following snippet of code.
>
> cmp W4,#0 ; No more characters to send,
> bne int_uart1_thre2 ; execute the following
>
> ldr W3,__IO ; Set 1 pin high and the other pin low
> mov W,#PIN_TXEN ; __IO holds the base address of IO regs
> str W,[W3,#IO0CLR]
> mov W,#PIN_TXEN_
> str W,[W3,#IO0SET]
>
> ldr W6,fifo1temp ; Put into variable fifo1temp
> str W3,[W6] ; the address of port0
> ldr W,[W3,#PORT0] ; and the contents of port0
> str W,[W6,#4]
>
> b int_uart1_thre3 ; go to exit portion of interrupt.
>
> All this works very well, except every hour or so, even though this
> code is actually executed 100 times a second, (verified by reading the
> variable fifo1temp) the 2 pins are not set/cleared to what they should
> be. And this even though the variable has the proper values reflecting
> what should be a proper operation.
>
> When the TXEN and TXEN_ pins aren't toggled, communications stop, so I
> can manually read the port values and peek and poke around. The
> variable fifo1temp contents clearly show that the interrupt routine
> has executed the above, and reading the port0 value shows that it has
> had no effect.
>
> And anywhere in the code where port0 is modified, the variable
> fifo1temp is also modified... So I can reasonable assume that nowhere
> else in my code is the port being changed without my knowing it.
>
> I assumed at one point that this could be the MAM.2 bug...
> But I have had the same behaviour in the following configurations:
>
> mamcr=2 mamtim=3 clk = just under 60MHz (Prime condition for MAM.2 bug)
>
> mamcr=1 mamtim=3 clk = just under 60MHz (errata sheet says this is a
> work around for mam.2 bug)
>
> mamcr=2 mamtim=5 clk = just under 60MHz
> mamcr=1 mamtim=5 clk = just under 60MHz
>
> And the three above cases with clk = 44MHz...
>
> Does anyone have an idea for further investigation?
> Thanks Adrian
>
>
Hi!!

Well I am ashamed of myself!!!

Somewhere else in my code I did a port read - modify - write. So of
course when the interrupt fell in the middle of those few
instructions, the port was written back with pre-interrupt data.

I did 2 versions that are running quite well, one (less favorable
option but just to validate the fix) where IRQ is disabled for the
port read - modify - write and the second version which uses port set
and port clear...

Sighs.... decades of software design to fall into a beginner's trap!

Adrian

--- In l..., Foltos wrote:
>
> Hi,
>
> did you checked your code for re-entracy problems? Port0 state may be
> mixed up if the IRQ fires between an IOCLR and an IOSET access.
>
> Foltos
>
> adrianunderwater wrote:
> > Hi, I initially posted this problem under the heading:
> >
> > "lpc2138 uart1 drops interrupts" however I have ascertained that the
> > UART1 is not missing any interrupt... But I am still stumped by my
> > problem.
> >
> > In a nutshell, in the interrupt routine for uart1 transmit fifo empty,
> > I have the following snippet of code.
> >
> > cmp W4,#0 ; No more characters to send,
> > bne int_uart1_thre2 ; execute the following
> >
> > ldr W3,__IO ; Set 1 pin high and the other pin low
> > mov W,#PIN_TXEN ; __IO holds the base address of IO regs
> > str W,[W3,#IO0CLR]
> > mov W,#PIN_TXEN_
> > str W,[W3,#IO0SET]
> >
> > ldr W6,fifo1temp ; Put into variable fifo1temp
> > str W3,[W6] ; the address of port0
> > ldr W,[W3,#PORT0] ; and the contents of port0
> > str W,[W6,#4]
> >
> > b int_uart1_thre3 ; go to exit portion of interrupt.
> >
> > All this works very well, except every hour or so, even though this
> > code is actually executed 100 times a second, (verified by reading the
> > variable fifo1temp) the 2 pins are not set/cleared to what they should
> > be. And this even though the variable has the proper values reflecting
> > what should be a proper operation.
> >
> > When the TXEN and TXEN_ pins aren't toggled, communications stop, so I
> > can manually read the port values and peek and poke around. The
> > variable fifo1temp contents clearly show that the interrupt routine
> > has executed the above, and reading the port0 value shows that it has
> > had no effect.
> >
> > And anywhere in the code where port0 is modified, the variable
> > fifo1temp is also modified... So I can reasonable assume that nowhere
> > else in my code is the port being changed without my knowing it.
> >
> > I assumed at one point that this could be the MAM.2 bug...
> > But I have had the same behaviour in the following configurations:
> >
> > mamcr=2 mamtim=3 clk = just under 60MHz (Prime condition for MAM.2
bug)
> >
> > mamcr=1 mamtim=3 clk = just under 60MHz (errata sheet says this is a
> > work around for mam.2 bug)
> >
> > mamcr=2 mamtim=5 clk = just under 60MHz
> > mamcr=1 mamtim=5 clk = just under 60MHz
> >
> > And the three above cases with clk = 44MHz...
> >
> > Does anyone have an idea for further investigation?
> > Thanks Adrian
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >