Forums

Problems with ADSP-21161N interrupts

Started by Unknown January 25, 2005
Hi,

I'm working on ADSP-21161N rev 1.1. I should run SPORT0 interrutps at
9600 Hz, setting the dividers to 24 for SCLK at 2.083333333 Mhz and
217, thus having SPORT0 interrupts at 9600.6144 Hz. Additionally I
should run Timer interrupts at different frequencies, from 0.5 Hz to 40
Hz.

I have found that when I set the Timer interrupts to happen at around
10 Hz or faster, the system runs fine for a short while, and suddenly
the interrupts stop happening, sometimes both the Timer and Sport0
interrupts, other times either one. But if I configure it to happn at a
lower rate the system seems to be more stable, but not working
perfectly (still interrupts stop happening, but take longer to behave
like this).

With the aid of the emulator I can see that the IMASK register is being
written with values which mask the interrupts, that's the reason why
they stop happening. But that overwritting of the IMASK register
happens within library functions, as I could find by running a
simulation session and setting watchpoints to halt when the IMASK
register is written. The library function seems to be the one in charge
of handling the interrupts on the ADSP-21161N

My program is completely in C. I set the interrupts using the
interrupt() function. I tried the "non self-modifying" version of the
interrupt() function, and also the "fast" and "super fast" vesions,
niether one seems to help.

I activate the lower priority Timer interrupt, and interrupt nesting is
on too.

What can be wrong? How to solve it?
Thank you for your time and help.

Regards,

JaaC

Hi JaaC,

maybe because of the MMASK-Register, ADI had changed it's
initialisation from 0x00200000 (hardware) to 0x00E03003.

Regards,
Mattias


Hello Mattias,

In case that that value (0x00E03003) is what actually is written in the
MMASK register, which I can not verify at this moment, it would disable
the following when pushing the status stack:

- I1 Broadcast
- I9 Broadcast
- SIMD mode
- ALU saturation
- Interrupts
- I0 Bit reversing
- I8 Bit reversing

But I actually don't see how could this affect the IMASK register. For
my code to run without problems, IMASK value is 0x00400043. And indeed,
it runs like this for a while... But gets modified to either:
0x00000043 (Timer interrupt disabled), 0x00400003 (SPORT0 interrupt
disabled) or even worse, 0x00000003 (both intrrutps disabled).

Looking forward to your further help.

JaaC

Mattias Schick wrote:
> Hi JaaC, > > maybe because of the MMASK-Register, ADI had changed it's > initialisation from 0x00200000 (hardware) to 0x00E03003. > > Regards, > Mattias
Hi Jaac,

> But I actually don't see how could this affect the IMASK register.
your description remebered me to an error i once struggled with, so i may have confused IMASK and MMASK ... Does the error also occur without nesting? Mattias
Hi,

Mattias Schick wrote:
> Hi Jaac, > > > But I actually don't see how could this affect the IMASK register. > > your description remebered me to an error i once struggled with, > so i may have confused IMASK and MMASK ... > > Does the error also occur without nesting?
Yes. Any hints? Thanks in advance, JaaC
If it depends on the rate, it sounds like a timing problem.
Is there anything in any IRQ that may take too much time?


Jaime Andr�s Aranguren Cardona wrote:

> Hi, > > Mattias Schick wrote: > >>Hi Jaac, >> >> >>>But I actually don't see how could this affect the IMASK register. >> >>your description remebered me to an error i once struggled with, >>so i may have confused IMASK and MMASK ... >> >>Does the error also occur without nesting? > > Yes. Any hints? > > Thanks in advance, > > JaaC >
-- Please change no_spam to a.lodwig when replying via email!
Hello Andre,

Andre wrote:
> If it depends on the rate, it sounds like a timing problem. > Is there anything in any IRQ that may take too much time?
Yes, souds like that... but it is not likely to happen. On the timer interrupt the only thing I do is to toggle a flag. On the SPORT0 interrupt I simply run a multiplication of the signal by itself (squaring) and store it on a buffer for later downsampling, once the buffer is full it simply turns on a flag, otherwise turns it off. The downsampling happens in the main routine, checking for the flag set in the interrupt servicing routine. Need some more ideas, guys! Thank you very much. JaaC
Hello,

I've got some news, guys.

Nesting was not the problem.
Stack overflow was not the problem.
ADI libraries for ISR management were not the problem.

This was the problem, my stupid mistake:

In my code, I have routines like this, running on the ISR (at least one of
them):

buffer[counter] = sample;        // Store sample in buffer
counter++;                       // Increment counter
if (counter == MAX_VALUE) {
  flag = true;                   // Set flag if buffer gets full
}
else {
  flag = false;                  // Otherwise, keep it cleared
}

My mistake was that I forgot the "counter = 0;" sentence near "flag = true".
I was doing it in another routine, which does not get triggered at this
poing, but in a subsequent call to a function, the calling is controlled by
the "flag".

I simply moved the "counter = 0;" sentence near "flag = true", and
everythign works perfectly. Even with interrupt nesting enabled!!

I want to thank all of you for taking your precious time to give me your
valuable advice.

Long live comp.dsp!!

--
Jaime Andr�s Aranguren Cardona
jaac@nospam.sanjaac.com
SanJaaC Electronics
Soluciones en DSP
www.sanjaac.com

(Remove "nospam" from e-mail address)

"Jaime Andr&#2013265929;s Aranguren Cardona" <jaime.aranguren@gmail.com> escribi&#2013265923; en el
mensaje news:1106666756.456956.201120@f14g2000cwb.googlegroups.com...
> Hello Andre, > > Andre wrote: > > If it depends on the rate, it sounds like a timing problem. > > Is there anything in any IRQ that may take too much time? > > Yes, souds like that... but it is not likely to happen. > > On the timer interrupt the only thing I do is to toggle a flag. > > On the SPORT0 interrupt I simply run a multiplication of the signal by > itself (squaring) and store it on a buffer for later downsampling, once > the buffer is full it simply turns on a flag, otherwise turns it off. > > The downsampling happens in the main routine, checking for the flag set > in the interrupt servicing routine. > Need some more ideas, guys! > > Thank you very much. > > JaaC >