NetBurner Community Forum

A community of NetBurner users gathering to discuss NetBurner hardware, software, design and projects
It is currently Sat May 25, 2013 8:17 am

All times are UTC - 8 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Surprise effect in turning dma timer interrupts off and on
PostPosted: Sat Apr 21, 2012 10:25 pm 

Joined: Mon Feb 01, 2010 10:00 am
Posts: 32
Summary: I turn a DMA timer interrupt on and off and back on. When I turn it on the first time, it works. Once I turn it off, turning it on again doesn't work. I'm using (sim.timer[IndexDMAOneWire].tmr &= ~0x0001) and (sim.timer[IndexDMAOneWire].tmr |= 0x0001).

Experimenting showed I had to rewrite the timer configuration:
sim.timer[IndexDMAOneWire].tmr = 0x001A; // 0000 0000 0001 1010
sim.timer[IndexDMAOneWire].txmr = 0x00; // 0000 0000
sim.timer[IndexDMAOneWire].ter |= 0x02;
before turning the interrupt back on, each and every time, or nothing works.

Is that expected? I was hoping I could just suppress or allow the interrupt with just .tmr changes. Rewriting the registers isn't a big deal, but it was annoying to figure out it was needed. Is it documented somewhere? Anyone else seen this?

(I'm turning them on and off because I'm big-banging the one-wire protocol, using interrupts to get the timing exact; which involves rewriting tcn and trr on each interrupt, and turning them off entirely when there's no one-wire stuff happening.)


Top
 Profile  
 
 Post subject: Re: Surprise effect in turning dma timer interrupts off and
PostPosted: Sun Apr 22, 2012 9:33 pm 

Joined: Wed Apr 30, 2008 7:01 pm
Posts: 55
Location: Perth, Western Australia
From the processor (5234, 5270, 5282) manual:

If an interrupt source is being masked in the interrupt controller mask
register (IMR) or a module’s interrupt mask register while the
interrupt mask in the status register (SR[I]) is set to a value lower than
the interrupt’s level, a spurious interrupt may occur. This is because by
the time the status register acknowledges this interrupt, the interrupt
has been masked. A spurious interrupt is generated because the CPU
cannot determine the interrupt source. To avoid this situation for
interrupts sources with levels 1-6, first write a higher level interrupt
mask to the status register, before setting the mask in the IMR or the
module’s interrupt mask register. After the mask is set, return the
interrupt mask in the status register to its previous value. Since level 7
interrupts cannot be disabled in the status register prior to masking,
use of the IMR or module interrupt mask registers to disable level 7
interrupts is not recommended.

I don't know if this is part of your problem, but I would recommend putting UCOS_ENTER_CRITICAL() and UCOS_EXIT_CRITICAL() around your read-modify-write of the sim.tmr[].imr register. this would prevent any spurious interrupt which may occur while disabling the timer interrupt, the spurious interrupt MIGHT be putting the timer into a weird or unexpected mode.

There is a lot of guesswork in this answer but it won't hurt to try.

I wrote these a while ago but never got any feedback.

viewtopic.php?f=5&t=1116
viewtopic.php?f=5&t=1117


Top
 Profile  
 
 Post subject: Re: Surprise effect in turning dma timer interrupts off and
PostPosted: Mon Apr 23, 2012 6:24 pm 

Joined: Wed Apr 30, 2008 7:01 pm
Posts: 55
Location: Perth, Western Australia
roland.ames wrote:
I would recommend putting UCOS_ENTER_CRITICAL() and UCOS_EXIT_CRITICAL() around your read-modify-write of the sim.tmr[].imr register.


Sorry that should have been USER_ENTER_CRITICAL() and USER_EXIT_CRITICAL().


Top
 Profile  
 
 Post subject: Re: Surprise effect in turning dma timer interrupts off and
PostPosted: Tue Apr 24, 2012 3:22 am 

Joined: Mon Feb 01, 2010 10:00 am
Posts: 32
I don't THINK that's related, but it lead me to look at the spurious interrupt thread, and now I'm turning interrupts off and on around my use of setIntc. So that's another future problem killed.

I guess I'm going to have to dig deeper into the implementation of sim.timer[]. I can see it's a basic struct with no member functions, so bit twiddles are just bit twiddles and presumably can make no direct changes to the hardware state. That means there's code elsewhere, presumably written by Netburner, that looks at these bits while interrupts are happening, and that code doesn't like it when they are touched during interrupts. And this is not documented. *sigh*

I can work around this. Instead of twiddling .tmr in the interrupt handler to turn the interrupt off and on, I can just leave them on, and set my own flag elsewhere to tell my interrupt handler to just dismiss and return if I don't really want that interrupt. I don't like this. It's sloppy and means I'll be getting interrupts when I don't need them.

I really wish the documentation was more detailed.


Top
 Profile  
 
 Post subject: Re: Surprise effect in turning dma timer interrupts off and
PostPosted: Tue Apr 24, 2012 5:14 am 

Joined: Fri Feb 19, 2010 12:17 pm
Posts: 9
Location: Blue Bell, Pennsylvania, USA
Scott,

There is no implementation of sim.timer[] to delve into. It is a simple struct as you see, but it does not exist in program RAM. The struct is based at address 0x4000_0000 by the linker as directed by the sys.ld file. When you "twiddle" the bits in any sim member, you are directly affecting the processor registers which occupy the address space starting at 0x4000_0000.

--Mike


Top
 Profile  
 
 Post subject: Re: Surprise effect in turning dma timer interrupts off and
PostPosted: Tue Apr 24, 2012 8:19 am 

Joined: Thu Apr 24, 2008 2:59 pm
Posts: 538
Scott, the documentation is in the Freescale processor manual. Is that the one without enough detail? If so, maybe a post to the freescale message board might help.


Top
 Profile  
 
 Post subject: Re: Surprise effect in turning dma timer interrupts off and
PostPosted: Tue Apr 24, 2012 7:51 pm 

Joined: Mon Feb 01, 2010 10:00 am
Posts: 32
mhoyt wrote:
Scott,

There is no implementation of sim.timer[] to delve into. It is a simple struct as you see, but it does not exist in program RAM. The struct is based at address 0x4000_0000 by the linker as directed by the sys.ld file. When you "twiddle" the bits in any sim member, you are directly affecting the processor registers which occupy the address space starting at 0x4000_0000.

--Mike


Ah, it's mapped. Ok, I'm off to the freescale manuals. Although - note to rnixon - it's nice when the product documentation presents the behaviour essentials, and doesn't send you manual chasing.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 8 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group